home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 110 / af110sub.adf / DTConvert.lzx / DTConvert / convert.c next >
C/C++ Source or Header  |  1998-03-11  |  34KB  |  982 lines

  1.  
  2. /*
  3. **
  4. **  $VER: convert.c 1.7 (2.3.98)
  5. **  datatypes.library/Examples/DTConvert
  6. **
  7. **  Converts file into another format using datatypes
  8. **
  9. **  converters for the various datatype classes
  10. **
  11. **  Written 1996-1998 by Roland 'Gizzy' Mainz
  12. **
  13. */
  14.  
  15. /* project includes */
  16. #include "DTConvert.h"
  17. #include "convert.h"
  18.  
  19. /* local prototypes */
  20. static                 BOOL           ConvertDataType( Object *, struct DataType *, STRPTR );
  21. static                 BOOL           ConvertPicture( Object *, struct DataType *, STRPTR );
  22. static                 BOOL           ConvertAnimation( Object *, struct DataType *, STRPTR );
  23. static                 BOOL           ConvertSound( Object *, struct DataType *, STRPTR );
  24. static DISPATCHERFLAGS ULONG          WriteAnimAndSoundDispatch( REGA0 struct IClass *, REGA2 Object *, REGA1 Msg );
  25. static                 void           No_Local_Encoder_Message( struct DataType * );
  26.  
  27.  
  28. void Convert( STRPTR srcname, STRPTR datatypename, BOOL iff, STRPTR destname )
  29. {
  30.     struct DataType *destdtn = NULL;
  31.  
  32.     if( datatypename )
  33.     {
  34.       destdtn = ObtainDataTypeA( DTST_RAM, (APTR)datatypename, NULL );
  35.     }
  36.  
  37.     if( srcname && destname )
  38.     {
  39.       if( destdtn || (iff && (!datatypename)) )
  40.       {
  41.         Object *srcdto;
  42.         ULONG   groupid = ((destdtn)?(destdtn -> dtn_Header -> dth_GroupID):(0UL));
  43.         BOOL    retry   = TRUE;
  44.  
  45.         Message( "loading source data \"%s\"\n", srcname );
  46.  
  47. retry: /* see downstairs */
  48.  
  49.         if( srcdto = NewDTObject( (APTR)srcname, XTAG( destdtn, DTA_GroupID ), groupid, TAG_DONE ) )
  50.         {
  51.           if( ConvertDataType( srcdto, destdtn, destname ) )
  52.           {
  53.             Message( "file successfully converted\n" );
  54.  
  55.             /* did we use DTWM_RAW ? */
  56.             if( destdtn )
  57.             {
  58.               BPTR result_lock;
  59.  
  60.               /* Check which data format we _really_ got. In the case that a datatypes class does not
  61.                * implement an encoder for it's format, throw out an error...
  62.                */
  63.               if( result_lock = Lock( destname, SHARED_LOCK ) )
  64.               {
  65.                 struct DataType *resulting_dtn;
  66.  
  67.                 if( resulting_dtn = ObtainDataType( DTST_FILE,   (APTR)result_lock,
  68.                                                     DTA_GroupID, (destdtn -> dtn_Header -> dth_GroupID),
  69.                                                     TAG_DONE ) )
  70.                 {
  71.                   /* Not the same datatype ? */
  72.                   if( Stricmp( (destdtn -> dtn_Header -> dth_Name), (resulting_dtn -> dtn_Header -> dth_Name) ) )
  73.                   {
  74.                     No_Local_Encoder_Message( destdtn );
  75.                   }
  76.  
  77.                   ReleaseDataType( resulting_dtn );
  78.                 }
  79.  
  80.                 UnLock( result_lock );
  81.               }
  82.             }
  83.           }
  84.           else
  85.           {
  86.             Message( "conversion failed\n" );
  87.           }
  88.  
  89.           DisposeDTObject( srcdto );
  90.         }
  91.         else
  92.         {
  93.           if( retry )
  94.           {
  95.             retry = FALSE;
  96.  
  97.             /* Kluge that conversion between GID_ANIMATION and GID_MOVIE datatypes gets possible */
  98.             switch( groupid )
  99.             {
  100.               case GID_ANIMATION: groupid = GID_MOVIE;     goto retry;
  101.               case GID_MOVIE:     groupid = GID_ANIMATION; goto retry;
  102.             }
  103.           }
  104.  
  105.           Message( "can't create source object\n" );
  106.         }
  107.       }
  108.       else
  109.       {
  110.         Message( "can' open destination datatype\n" );
  111.       }
  112.     }
  113.     else
  114.     {
  115.       SetIoErr( ERROR_REQUIRED_ARG_MISSING );
  116.     }
  117.  
  118.     ReleaseDataType( destdtn );
  119. }
  120.  
  121.  
  122. static
  123. BOOL ConvertDataType( Object *srcdto, struct DataType *destdtn, STRPTR destfile )
  124. {
  125.     BOOL success = FALSE;
  126.     LONG error   = 0L;
  127.  
  128.     if( srcdto && destfile )
  129.     {
  130.       struct DataType *srcdtn;
  131.  
  132.       (void)GetDTAttrs( srcdto, DTA_DataType, (&srcdtn), TAG_DONE );
  133.  
  134.       Message( "converting \"%s\" %s into \"%s\" %s\n",
  135.               (srcdtn  -> dtn_Header -> dth_Name),
  136.               GetDTString( (srcdtn -> dtn_Header -> dth_GroupID) ),
  137.               ((destdtn)?(destdtn -> dtn_Header -> dth_Name):("IFF")),
  138.               ((destdtn)?GetDTString( (destdtn -> dtn_Header -> dth_GroupID) ):("IFF")) );
  139.  
  140.       switch( srcdtn -> dtn_Header -> dth_GroupID )
  141.       {
  142.         case GID_SYSTEM:
  143.         {
  144.             /* There is currently no system.datatype base class defined */
  145.             error = ERROR_ACTION_NOT_KNOWN;
  146.         }
  147.             break;
  148.  
  149.         case GID_TEXT:
  150.         {
  151.             /* text.datatype -> text.datatype conversion possible, but not implemented...  */
  152.             error = ERROR_NOT_IMPLEMENTED;
  153.         }
  154.             break;
  155.  
  156.         case GID_DOCUMENT:
  157.         {
  158.             /* There is currently no document.datatype base class defined */
  159.             error = ERROR_ACTION_NOT_KNOWN;
  160.         }
  161.             break;
  162.  
  163.         case GID_SOUND:
  164.         {
  165.             success = ConvertSound( srcdto, destdtn, destfile );
  166.             error = IoErr();
  167.         }
  168.             break;
  169.  
  170.         case GID_INSTRUMENT:
  171.         {
  172.             /* There is currently no instrument.datatype base class defined */
  173.             error = ERROR_ACTION_NOT_KNOWN;
  174.         }
  175.             break;
  176.  
  177.         case GID_MUSIC:
  178.         {
  179.             /* There is currently no music.datatype base class defined */
  180.             error = ERROR_ACTION_NOT_KNOWN;
  181.         }
  182.             break;
  183.  
  184.         case GID_PICTURE:
  185.         {
  186.             success = ConvertPicture( srcdto, destdtn, destfile );
  187.             error = IoErr();
  188.         }
  189.             break;
  190.  
  191.         case GID_ANIMATION:
  192.         case GID_MOVIE:
  193.         {
  194.             success = ConvertAnimation( srcdto, destdtn, destfile );
  195.             error = IoErr();
  196.         }
  197.             break;
  198.  
  199.         default:
  200.         {
  201.             error = ERROR_ACTION_NOT_KNOWN;
  202.         }
  203.             break;
  204.       }
  205.     }
  206.  
  207.     SetIoErr( error );
  208.  
  209.     return( success );
  210. }
  211.  
  212.  
  213. static
  214. BOOL ConvertPicture( Object *srcdto, struct DataType *destdtn, STRPTR destfile )
  215. {
  216.     BOOL success = FALSE;
  217.     LONG error   = 0L;
  218.  
  219.     Message( "picture converter\n" );
  220.  
  221.     if( srcdto && destfile )
  222.     {
  223.       Object          *destdto;
  224.       struct DataType *srcdtn;
  225.       struct BitMap   *bm;
  226.  
  227.       /* Some (ugly) picture.datatype needs a DTM_PROCLAYOUT before
  228.        * allowing to access their bitmaps
  229.        */
  230.       (void)GetDTAttrs( srcdto, PDTA_BitMap, (&bm), TAG_DONE );
  231.  
  232.       if( bm == NULL )
  233.       {
  234.         struct gpLayout  gpl;
  235.  
  236.         Message( "source requires layouting...\n" );
  237.  
  238.         /* "Layout" picture (for those picture classes which need this,
  239.          * __NOT__ recommened)
  240.          */
  241.         SetDTAttrs( srcdto, NULL, NULL, PDTA_Remap, FALSE, TAG_DONE );
  242.  
  243.         gpl . MethodID    = DTM_PROCLAYOUT;
  244.         gpl . gpl_GInfo   = NULL;
  245.         gpl . gpl_Initial = 1L;
  246.  
  247.         DoDTMethodA( srcdto, NULL, NULL, (Msg)(&gpl) );
  248.       }
  249.  
  250.       /* Get source datatype, see below */
  251.       (void)GetDTAttrs( srcdto, DTA_DataType, (&srcdtn), TAG_DONE );
  252.  
  253.       /* Create empty picture.datatype subclass object */
  254.       if( destdto = NewDTObject( NULL, DTA_SourceType,                   DTST_RAM,
  255.                                        XTAG( destdtn,    DTA_DataType ), destdtn,
  256.                                        XTAG( (!destdtn), DTA_GroupID  ), (srcdtn -> dtn_Header -> dth_GroupID),
  257.                                        TAG_DONE ) )
  258.       {
  259.         STRPTR                objname,
  260.                               objauthor,
  261.                               objannotation,
  262.                               objcopyright,
  263.                               objversion;
  264.         ULONG                 modeid;
  265.         ULONG                 numcolors;
  266.         struct BitMapHeader  *sbmh,
  267.                              *dbmh;
  268.         ULONG                *scregs;
  269.         struct ColorRegister *scm;
  270.  
  271.         if( GetDTAttrs( srcdto, DTA_ObjName,         (&objname),
  272.                                 DTA_ObjAuthor,       (&objauthor),
  273.                                 DTA_ObjAnnotation,   (&objannotation),
  274.                                 DTA_ObjCopyright,    (&objcopyright),
  275.                                 DTA_ObjVersion,      (&objversion),
  276.                                 PDTA_ModeID,         (&modeid),
  277.                                 PDTA_BitMapHeader,   (&sbmh),
  278.                                 PDTA_NumColors,      (&numcolors),
  279.                                 PDTA_CRegs,          (&scregs),
  280.                                 PDTA_ColorRegisters, (&scm),
  281.                                 PDTA_BitMap,         (&bm),
  282.                                 TAG_DONE ) == 11UL )
  283.         {
  284.           if( GetDTAttrs( destdto, PDTA_BitMapHeader, (&dbmh), TAG_DONE ) == 1UL )
  285.           {
  286.             if( sbmh && bm && dbmh )
  287.             {
  288.               ULONG                *dcregs;
  289.               struct ColorRegister *dcm;
  290.  
  291.               /* copy bitmapheader (RAW) from source bmh... */
  292.               *dbmh = *sbmh;
  293.  
  294.               /* ...and fill in attributes which may be different */
  295.               dbmh -> bmh_Compression = cmpNone;
  296.  
  297.               /* we're writing a full palette, set this flag (currently NOP, but...) */
  298.               dbmh -> bmh_Pad    = BMHDF_CMAPOK; /* also known as bmh_Flags */
  299.  
  300.               /* Set datas "name", "author", "annotation", "copyright", "version" etc.,
  301.                * screen mode id,
  302.                * our bitmap and
  303.                * the requested number of colors...
  304.                */
  305.               SetDTAttrs( destdto, NULL, NULL,
  306.                           DTA_ObjName,       objname,
  307.                           DTA_ObjAuthor,     objauthor,
  308.                           DTA_ObjAnnotation, objannotation,
  309.                           DTA_ObjCopyright,  objcopyright,
  310.                           DTA_ObjVersion,    objversion,
  311.                           PDTA_ModeID,       modeid,
  312.                           PDTA_NumColors,    numcolors,
  313.                           PDTA_BitMap,       bm,
  314.                           TAG_DONE );
  315.  
  316.               /* Some (ugly) picture.datatype needs a DTM_PROCLAYOUT before
  317.                * allowing to access their bitmaps
  318.                */
  319.               (void)GetDTAttrs( destdto, PDTA_BitMap, (&bm), TAG_DONE );
  320.  
  321.               if( bm == NULL )
  322.               {
  323.                 struct gpLayout  gpl;
  324.  
  325.                 Message( "destination requires layouting...\n" );
  326.  
  327.                 /* "Layout" picture (for those picture classes which need this,
  328.                  * __NOT__ recommened)
  329.                  */
  330.                 SetDTAttrs( destdto, NULL, NULL, PDTA_Remap, FALSE, TAG_DONE );
  331.  
  332.                 gpl . MethodID    = DTM_PROCLAYOUT;
  333.                 gpl . gpl_GInfo   = NULL;
  334.                 gpl . gpl_Initial = 1L;
  335.  
  336.                 DoDTMethodA( destdto, NULL, NULL, (Msg)(&gpl) );
  337.               }
  338.  
  339.               /* Get color tables (dest cregs, dest cm)  */
  340.               if( GetDTAttrs( destdto, PDTA_CRegs,          (&dcregs),
  341.                                        PDTA_ColorRegisters, (&dcm),
  342.                                        TAG_DONE ) == 2UL )
  343.               {
  344.                 /* Success ? */
  345.                 if( dcregs && dcm )
  346.                 {
  347.                   ULONG i;
  348.  
  349.                   /* Copy color tables... */
  350.                   for( i = 0UL ; i < numcolors ; i++ )
  351.                   {
  352.                     dcregs[ ((i * 3) + 0) ] = scregs[ ((i * 3) + 0) ]; /* copy r, */
  353.                     dcregs[ ((i * 3) + 1) ] = scregs[ ((i * 3) + 1) ]; /*      g, */
  354.                     dcregs[ ((i * 3) + 2) ] = scregs[ ((i * 3) + 2) ]; /*      b  */
  355.  
  356.                     *dcm++ = *scm++; /* copy colorregisters */
  357.                   }
  358.  
  359.                   Message( "saving picture: \"%s\"\n", destfile );
  360.  
  361.                   if( !(success = SaveDTObjectA( destdto, NULL, NULL, destfile, DTWM_RAW, TRUE, NULL )) )
  362.                   {
  363.                     error = IoErr();
  364.                     Message( "saving failed\n" );
  365.                   }
  366.                 }
  367.                 else
  368.                 {
  369.                   Message( "picture object mem err (no color tables)\n" );
  370.                   error = ERROR_NO_FREE_STORE;
  371.                 }
  372.               }
  373.               else
  374.               {
  375.                 /* can't get required args from object */
  376.                 error = ERROR_OBJECT_WRONG_TYPE;
  377.               }
  378.  
  379.               /* src datatype will free it's bitmap  */
  380.               SetDTAttrs( destdto, NULL, NULL, PDTA_BitMap, NULL, TAG_DONE );
  381.             }
  382.             else
  383.             {
  384.               Message( "can't get bitmap\n" );
  385.               error = ERROR_NO_FREE_STORE;
  386.             }
  387.           }
  388.           else
  389.           {
  390.             /* can't get required args from destination object */
  391.             Message( "can't get PDTA_BitMapHeader from destination object \n" );
  392.             error = ERROR_OBJECT_WRONG_TYPE;
  393.           }
  394.         }
  395.         else
  396.         {
  397.           /* can't get required args from source object */
  398.           Message( "can't get required args from source object\n" );
  399.           error = ERROR_OBJECT_WRONG_TYPE;
  400.         }
  401.  
  402.         /* Get rid of the picture object */
  403.         DisposeDTObject( destdto );
  404.       }
  405.       else
  406.       {
  407.         /* NewDTObject failed */
  408.         error = IoErr();
  409.  
  410.         Message( "can't create empty object\n" );
  411.  
  412.         if( destdtn )
  413.         {
  414.           No_Local_Encoder_Message( destdtn );
  415.         }
  416.       }
  417.     }
  418.     else
  419.     {
  420.       /* missing function args */
  421.       error = ERROR_REQUIRED_ARG_MISSING;
  422.     }
  423.  
  424.     SetIoErr( error );
  425.  
  426.     return( success );
  427. }
  428.  
  429.  
  430. static
  431. BOOL ConvertAnimation( Object *srcdto, struct DataType *destdtn, STRPTR destfile )
  432. {
  433.     BOOL success = FALSE;
  434.     LONG error   = 0L;
  435.  
  436.     Message( "animation converter\n" );
  437.  
  438.     if( srcdto && destfile && destdtn )
  439.     {
  440.       TEXT             classname[ 256 ];
  441.       struct Library  *DTClassBase;
  442.       Object          *destdto;
  443.       struct DataType *srcdtn;
  444.  
  445.       /* Get source datatype, see below */
  446.       (void)GetDTAttrs( srcdto, DTA_DataType, (&srcdtn), TAG_DONE );
  447.  
  448.       /* Create class library name... */
  449.       mysprintf( classname, "DataTypes/%s.datatype", (destdtn -> dtn_Header -> dth_BaseName) );
  450.  
  451.       /* ...then open it */
  452.       if( DTClassBase = OpenLibrary( classname, 0UL ) )
  453.       {
  454.         struct IClass *AnimClass;
  455.  
  456.         /* Obtain destination class */
  457.         if( AnimClass = ObtainEngine() )
  458.         {
  459.           struct IClass *WriteAnimClass;
  460.  
  461.           /* Create our new class... */
  462.           if( WriteAnimClass = MakeClass( NULL, NULL, AnimClass, 0UL, 0UL ) )
  463.           {
  464.             /* Prepare class for usage... */
  465.             WriteAnimClass -> cl_Dispatcher . h_Entry = (HOOKFUNC)WriteAnimAndSoundDispatch;
  466.             WriteAnimClass -> cl_UserData             = 0UL; /* datatypes.library expects here a (struct Library *) or NULL,
  467.                                                               * therefore we cannot use this for our context data
  468.                                                               */
  469.  
  470.             /* Create empty subclass object (from our dest write class) */
  471.             if( destdto = (Object *)NewDTObject( NULL, DTA_SourceType,          DTST_RAM,       /* Create empty object...    */
  472.                                                        DTA_DataType,            destdtn,        /* ...using this datatype... */
  473.                                                        DTA_Class,               WriteAnimClass, /* ...from this class...     */
  474.                                                        WRITEANIMA_SourceObject, srcdto,         /* source of data            */
  475.                                                        TAG_DONE ) )
  476.             {
  477.               /* datatypesclass attributes */
  478.               STRPTR                objname,
  479.                                     objauthor,
  480.                                     objannotation,
  481.                                     objcopyright,
  482.                                     objversion;
  483.  
  484.               /* picture (e.g. global) attributes  */
  485.               ULONG                 modeid;
  486.               ULONG                 numcolors;
  487.               struct BitMap        *bm;
  488.               struct BitMapHeader  *sbmh,
  489.                                    *dbmh;
  490.               ULONG                *scregs;
  491.               struct ColorRegister *scm;
  492.               ULONG                 width,
  493.                                     height,
  494.                                     depth;
  495.                                     
  496.               /* animation attributes */
  497.               ULONG                 frames,
  498.                                     fps,
  499.                                     finc;
  500.                                     
  501.               /* sound attributes */
  502.               BYTE                 *sample;
  503.               ULONG                 samplelength,
  504.                                     period,
  505.                                     volume,
  506.                                     cycles;
  507.  
  508.               if( GetDTAttrs( srcdto, DTA_ObjName,          (&objname),
  509.                                       DTA_ObjAuthor,        (&objauthor),
  510.                                       DTA_ObjAnnotation,    (&objannotation),
  511.                                       DTA_ObjCopyright,     (&objcopyright),
  512.                                       DTA_ObjVersion,       (&objversion),
  513.                                       PDTA_BitMapHeader,    (&sbmh),
  514.                                       ADTA_ModeID,          (&modeid),
  515.                                       ADTA_NumColors,       (&numcolors),
  516.                                       ADTA_CRegs,           (&scregs),
  517.                                       ADTA_ColorRegisters,  (&scm),
  518.                                       ADTA_KeyFrame,        (&bm),
  519.                                       ADTA_Width,           (&width),
  520.                                       ADTA_Height,          (&height),
  521.                                       ADTA_Depth,           (&depth),
  522.                                       ADTA_Frames,          (&frames),
  523.                                       ADTA_FramesPerSecond, (&fps),
  524.                                       ADTA_FrameIncrement,  (&finc),
  525.                                       ADTA_Sample,          (&sample),
  526.                                       ADTA_SampleLength,    (&samplelength),
  527.                                       ADTA_Period,          (&period),
  528.                                       ADTA_Volume,          (&volume),
  529.                                       ADTA_Cycles,          (&cycles),
  530.                                       TAG_DONE ) == 22UL )
  531.               {
  532.                 if( GetDTAttrs( destdto, PDTA_BitMapHeader, (&dbmh), TAG_DONE ) == 1UL )
  533.                 {
  534.                   if( sbmh && bm && dbmh )
  535.                   {
  536.                     ULONG                *dcregs;
  537.                     struct ColorRegister *dcm;
  538.  
  539.                     /* copy bitmapheader (RAW) from animation bmh... */
  540.                     *dbmh = *sbmh;
  541.  
  542.                     /* ...and fill in attributes which may be different */
  543.                     dbmh -> bmh_Compression = cmpNone;
  544.  
  545.                     /* we're writing a full palette, set this flag (currently NOP, but...) */
  546.                     dbmh -> bmh_Pad  = BMHDF_CMAPOK; /* also known as bmh_Flags */
  547.  
  548.                     /* Set datas "name", "author", "annotation", "copyright", "version" etc.,
  549.                      * screen mode id,
  550.                      * our bitmap and
  551.                      * the requested number of colors...
  552.                      */
  553.                     SetDTAttrs( destdto, NULL, NULL,
  554.                                 DTA_ObjName,          objname,
  555.                                 DTA_ObjAuthor,        objauthor,
  556.                                 DTA_ObjAnnotation,    objannotation,
  557.                                 DTA_ObjCopyright,     objcopyright,
  558.                                 DTA_ObjVersion,       objversion,
  559.                                 PDTA_BitMapHeader,    sbmh,
  560.                                 ADTA_ModeID,          modeid,
  561.                                 ADTA_NumColors,       numcolors,
  562.                                 ADTA_CRegs,           scregs,
  563.                                 ADTA_ColorRegisters,  scm,
  564.                                 ADTA_KeyFrame,        bm,
  565.                                 ADTA_Width,           width,
  566.                                 ADTA_Height,          height,
  567.                                 ADTA_Depth,           depth,
  568.                                 ADTA_Frames,          frames,
  569.                                 ADTA_FramesPerSecond, fps,
  570.                                 ADTA_FrameIncrement,  finc,
  571.                                 ADTA_Sample,          sample,
  572.                                 ADTA_SampleLength,    samplelength,
  573.                                 ADTA_Period,          period,
  574.                                 ADTA_Volume,          volume,
  575.                                 ADTA_Cycles,          cycles,
  576.                                 TAG_DONE );
  577.  
  578.                     /* Get color tables (dest cregs, dest cm)  */
  579.                     if( GetDTAttrs( destdto, ADTA_CRegs,          (&dcregs),
  580.                                              ADTA_ColorRegisters, (&dcm),
  581.                                              TAG_DONE ) == 2UL )
  582.                     {
  583.                       /* Success ? */
  584.                       if( (dcregs && dcm) || (numcolors == 0UL) )
  585.                       {
  586.                         ULONG i;
  587.  
  588.                         /* Copy color tables... */
  589.                         for( i = 0UL ; i < numcolors ; i++ )
  590.                         {
  591.                           dcregs[ ((i * 3) + 0) ] = scregs[ ((i * 3) + 0) ]; /* copy r, */
  592.                           dcregs[ ((i * 3) + 1) ] = scregs[ ((i * 3) + 1) ]; /*      g, */
  593.                           dcregs[ ((i * 3) + 2) ] = scregs[ ((i * 3) + 2) ]; /*      b  */
  594.  
  595.                           *dcm++ = *scm++; /* copy colorregisters */
  596.                         }
  597.  
  598.                         Message( "saving animation: \"%s\"\n", destfile );
  599.  
  600.                         if( !(success = SaveDTObjectA( destdto, NULL, NULL, destfile, DTWM_RAW, TRUE, NULL )) )
  601.                         {
  602.                           error = IoErr();
  603.                           Message( "saving failed\n" );
  604.                         }
  605.                       }
  606.                       else
  607.                       {
  608.                         Message( "animation object mem err (no color tables)\n" );
  609.                         error = ERROR_NO_FREE_STORE;
  610.                       }
  611.                     }
  612.                     else
  613.                     {
  614.                       /* can't get required args from object */
  615.                       error = ERROR_OBJECT_WRONG_TYPE;
  616.                     }
  617.  
  618.                     /* src datatype will free it's key frame (bitmap) */
  619.                     SetDTAttrs( destdto, NULL, NULL, ADTA_KeyFrame, NULL, TAG_DONE );
  620.                   }
  621.                   else
  622.                   {
  623.                     Message( "can't get key frame (bitmap)\n" );
  624.                     error = ERROR_NO_FREE_STORE;
  625.                   }
  626.                 }
  627.                 else
  628.                 {
  629.                   /* can't get required args from destination object */
  630.                   Message( "can't get PDTA_BitMapHeader from destination\n" );
  631.                   error = ERROR_OBJECT_WRONG_TYPE;
  632.                 }
  633.               }
  634.               else
  635.               {
  636.                 /* can't get required args from source object */
  637.                 Message( "can't get required args from source object\n" );
  638.                 error = ERROR_OBJECT_WRONG_TYPE;
  639.               }
  640.  
  641.               /* Get rid of the animation object */
  642.               DisposeDTObject( destdto );
  643.             }
  644.             else
  645.             {
  646.               /* NewDTObject failed */
  647.               error = IoErr();
  648.  
  649.               Message( "can't create empty object\n" );
  650.  
  651.               if( destdtn )
  652.               {
  653.                 No_Local_Encoder_Message( destdtn );
  654.               }
  655.             }
  656.  
  657.             /* Free class... */
  658.             while( !FreeClass( WriteAnimClass ) )
  659.             {
  660.               /* Let other tasks partake... */
  661.               Delay( (TICKS_PER_SECOND / 5UL) );
  662.             }
  663.           }
  664.         }
  665.         else
  666.         {
  667.           Message( "can't obtain output anim class\n" );
  668.         }
  669.  
  670.         CloseLibrary( DTClassBase );
  671.       }
  672.       else
  673.       {
  674.         /* Can't open class library */
  675.         if( !(error = IoErr()) )
  676.         {
  677.           error = DTERROR_UNKNOWN_DATATYPE;
  678.         }
  679.       }
  680.     }
  681.     else
  682.     {
  683.       /* missing function args */
  684.       error = ERROR_REQUIRED_ARG_MISSING;
  685.     }
  686.  
  687.     SetIoErr( error );
  688.  
  689.     return( success );
  690. }
  691.  
  692.  
  693. static
  694. BOOL ConvertSound( Object *srcdto, struct DataType *destdtn, STRPTR destfile )
  695. {
  696.     BOOL success = FALSE;
  697.     LONG error   = 0L;
  698.  
  699.     Message( "sound converter\n" );
  700.  
  701.     if( srcdto && destfile )
  702.     {
  703.       Object          *destdto;
  704.       struct DataType *srcdtn;
  705.  
  706.       /* Get source datatype, see below */
  707.       (void)GetDTAttrs( srcdto, DTA_DataType, (&srcdtn), TAG_DONE );
  708.  
  709.       /* Create empty sound.datatype subclass object */
  710.       if( destdto = NewDTObject( NULL, DTA_SourceType,                   DTST_RAM,
  711.                                        XTAG( destdtn,    DTA_DataType ), destdtn,
  712.                                        XTAG( (!destdtn), DTA_GroupID  ), (srcdtn -> dtn_Header -> dth_GroupID),
  713.                                        TAG_DONE ) )
  714.       {
  715.         STRPTR                objname,
  716.                               objauthor,
  717.                               objannotation,
  718.                               objcopyright,
  719.                               objversion;
  720.         struct VoiceHeader   *svh,
  721.                              *dvh;
  722.         SAMPLE8              *sample;
  723.         ULONG                 samplelength;
  724.         ULONG                 period,
  725.                               volume,
  726.                               cycles;
  727.  
  728.         if( GetDTAttrs( srcdto, DTA_ObjName,         (&objname),
  729.                                 DTA_ObjAuthor,       (&objauthor),
  730.                                 DTA_ObjAnnotation,   (&objannotation),
  731.                                 DTA_ObjCopyright,    (&objcopyright),
  732.                                 DTA_ObjVersion,      (&objversion),
  733.                                 SDTA_VoiceHeader,    (&svh),
  734.                                 SDTA_Sample,         (&sample),
  735.                                 SDTA_SampleLength,   (&samplelength),
  736.                                 SDTA_Period,         (&period),
  737.                                 SDTA_Volume,         (&volume),
  738.                                 SDTA_Cycles,         (&cycles),
  739.                                 TAG_DONE ) == 11UL )
  740.         {
  741.           if( GetDTAttrs( destdto, SDTA_VoiceHeader, (&dvh), TAG_DONE ) == 1UL )
  742.           {
  743.             if( svh && sample && samplelength && dvh )
  744.             {
  745.               /* copy voiceheader (RAW) from source vh... */
  746.               *dvh = *svh;
  747.  
  748.               /* ...and fill in attributes which may be different */
  749.               dvh -> vh_Compression = CMP_NONE;
  750.  
  751.               /* Set datas "name", "author", "annotation", "copyright", "version" etc.,
  752.                * screen mode id,
  753.                * our sample data etc.
  754.                */
  755.               SetDTAttrs( destdto, NULL, NULL,
  756.                           DTA_ObjName,       objname,
  757.                           DTA_ObjAuthor,     objauthor,
  758.                           DTA_ObjAnnotation, objannotation,
  759.                           DTA_ObjCopyright,  objcopyright,
  760.                           DTA_ObjVersion,    objversion,
  761.                           SDTA_Sample,       sample,
  762.                           SDTA_SampleLength, samplelength,
  763.                           SDTA_Period,       period,
  764.                           SDTA_Volume,       volume,
  765.                           SDTA_Cycles,       cycles,
  766.                           TAG_DONE );
  767.  
  768.               Message( "saving sound: \"%s\"\n", destfile );
  769.  
  770.               if( !(success = SaveDTObjectA( destdto, NULL, NULL, destfile, DTWM_RAW, TRUE, NULL )) )
  771.               {
  772.                 error = IoErr();
  773.                 Message( "saving failed\n" );
  774.               }
  775.  
  776.               /* src datatype will free it's sample data  */
  777.               SetDTAttrs( destdto, NULL, NULL, SDTA_Sample, NULL, TAG_DONE );
  778.             }
  779.             else
  780.             {
  781.               Message( "can't get sample (maybe unsupported sound.datatype V41 mode)\n" );
  782.               error = ERROR_NO_FREE_STORE;
  783.             }
  784.           }
  785.           else
  786.           {
  787.             /* can't get required args from destination object */
  788.             Message( "can't get required args from destination object\n" );
  789.             error = ERROR_OBJECT_WRONG_TYPE;
  790.           }
  791.         }
  792.         else
  793.         {
  794.           /* can't get required args from source object */
  795.           Message( "can't get required args from source object\n" );
  796.           error = ERROR_OBJECT_WRONG_TYPE;
  797.         }
  798.  
  799.         /* Get rid of the sound object */
  800.         DisposeDTObject( destdto );
  801.       }
  802.       else
  803.       {
  804.         /* NewDTObject failed */
  805.         error = IoErr();
  806.  
  807.         Message( "can't create empty object\n" );
  808.  
  809.         if( destdtn )
  810.         {
  811.           No_Local_Encoder_Message( destdtn );
  812.         }
  813.       }
  814.     }
  815.     else
  816.     {
  817.       /* missing function args */
  818.       error = ERROR_REQUIRED_ARG_MISSING;
  819.     }
  820.  
  821.     SetIoErr( error );
  822.  
  823.     return( success );
  824. }
  825.  
  826.  
  827. /* WriteAnimClass/WriteSoundClass dispatcher */
  828. static
  829. DISPATCHERFLAGS
  830. ULONG WriteAnimAndSoundDispatch( REGA0 struct IClass *cl, REGA2 Object *o, REGA1 Msg msg )
  831. {
  832.     ULONG retval = 0UL;
  833.  
  834.     switch( msg -> MethodID )
  835.     {
  836. #ifdef CURRENTLY_USELESS_CODE
  837.         case OM_NEW:
  838.         {
  839.             /* Assumes that WRITEANIMA_SourceObject contains a valid object
  840.              * (WRITEANIMA_SourceObject s mapped to DTA_UserData; datatypesclass handles
  841.              * storage of this attribute :-)
  842.              */
  843.             if( retval = DoSuperMethodA( cl, o, msg ) )
  844.             {
  845.               /* NOP */
  846.             }
  847.         }
  848.             break;
  849.  
  850.         case OM_DISPOSE:
  851.         {
  852.             DoSuperMethodA( cl, o, msg );
  853.         }
  854.             break;
  855. #endif /* CURRENTLY_USELESS_CODE */
  856.  
  857.         case OM_UPDATE:
  858.         {
  859.             /* Avoid OM_NOTIFY loops */
  860.             if( DoMethod( o, ICM_CHECKLOOP ) )
  861.             {
  862.               break;
  863.             }
  864.         }
  865.         case OM_SET:
  866.         {
  867.             /* Pass the attributes to the text class and force a refresh
  868.              * if we need it
  869.              */
  870.             if( retval = DoSuperMethodA( cl, o, msg ) )
  871.             {
  872. /* writeanimclass is alwasy the top instance... */
  873. #ifdef COMMENTED_OUT
  874.               /* Top instance ? */
  875.               if( OCLASS( o ) == cl )
  876. #endif /* COMMENTED_OUT */
  877.               {
  878.                 struct RastPort *rp;
  879.  
  880.                 /* Get a pointer to the rastport */
  881.                 if( rp = ObtainGIRPort( (((struct opSet *)msg) -> ops_GInfo) ) )
  882.                 {
  883.                   struct gpRender gpr;
  884.  
  885.                   /* Force a redraw */
  886.                   gpr . MethodID   = GM_RENDER;
  887.                   gpr . gpr_GInfo  = ((struct opSet *)msg) -> ops_GInfo;
  888.                   gpr . gpr_RPort  = rp;
  889.                   gpr . gpr_Redraw = GREDRAW_UPDATE;
  890.  
  891.                   DoMethodA( o, (Msg)(&gpr) );
  892.  
  893.                   /* Release the temporary rastport */
  894.                   ReleaseGIRPort( rp );
  895.                 }
  896.  
  897.                 retval = 0UL;
  898.               }
  899.             }
  900.         }
  901.             break;
  902.  
  903.         /* This two methods are superset by writeanimclass (e.g. us) */
  904.         case ADTM_LOADFRAME:
  905.         case ADTM_UNLOADFRAME:
  906.         {
  907.             Object *source;
  908.  
  909.             if( GetDTAttrs( o, WRITEANIMA_SourceObject, (&source), TAG_DONE ) == 1UL )
  910.             {
  911.               if( source )
  912.               {
  913.                 /* Route msg to source object... */
  914.                 retval = DoMethodA( source, msg );
  915.               }
  916.               else
  917.               {
  918.                 /* This error code aborts animation.datatype's playback and should also abort any encoder
  919.                  * (only ERROR_OBJECT_NOT_FOUND should be ignored by encoders...)
  920.                  */
  921.                 SetIoErr( ERROR_REQUIRED_ARG_MISSING );
  922.               }
  923.             }
  924.         }
  925.             break;
  926.  
  927. #ifdef SOUNDDATATYPE_V41_SUPPORT
  928.         /* This two methods are superset by writesoundclass (e.g. us) */
  929.         case SDTM_LOADSAMPLE:
  930.         case SDTM_UNLOADSAMPLE:
  931.         {
  932.             Object *source;
  933.  
  934.             if( GetDTAttrs( o, WRITESOUNDA_SourceObject, (&source), TAG_DONE ) )
  935.             {
  936.               if( source )
  937.               {
  938.                 /* Route msg to source object... */
  939.                 retval = DoMethodA( source, msg );
  940.               }
  941.               else
  942.               {
  943.                 /* This error code aborts animation.datatype's playback and should also abort any encoder
  944.                  * (only ERROR_OBJECT_NOT_FOUND should be ignored by encoders...)
  945.                  */
  946.                 SetIoErr( ERROR_REQUIRED_ARG_MISSING );
  947.               }
  948.             }
  949.         }
  950.             break;
  951. #endif /* SOUNDDATATYPE_V41_SUPPORT */
  952.  
  953.         /* Let the superclass handle everything else */
  954.         default:
  955.         {
  956.             retval = DoSuperMethodA( cl, o, msg );
  957.         }
  958.             break;
  959.     }
  960.  
  961.     return( retval );
  962. }
  963.  
  964.  
  965. static
  966. void No_Local_Encoder_Message( struct DataType *dtn )
  967. {
  968.     struct DataTypeHeader *dth = dtn -> dtn_Header;
  969.  
  970.     Message( "##########################################################################\n"
  971.              "# Error: the selected class \"%s\"\n"
  972.              "# does not implement an encoder (which is reposible to save the data in\n"
  973.              "# the requested format \"%s\").\n"
  974.              "# Please contact the author of the SUBCLASS to fix this problem...\n"
  975.              "##########################################################################\n",
  976.              (dth -> dth_BaseName), (dth -> dth_Name) );
  977. }
  978.  
  979.  
  980.  
  981.  
  982.