home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 1 / Mecomp-CD.iso / amiga / datatypes / film_datatype / classbase.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-19  |  12.5 KB  |  414 lines

  1.  
  2. /*
  3. **
  4. **  $VER: classbase.c 1.5 (19.4.97)
  5. **  film.datatype 1.5
  6. **
  7. **  Library routines for a DataTypes class
  8. **
  9. **  Written 1996/97 by Roland 'Gizzy' Mainz
  10. **  Original example source from David N. Junod
  11. **
  12. */
  13.  
  14.  
  15. /* main includes */
  16. #include "classbase.h"
  17.  
  18.  
  19. /****** film.datatype/--datasheed-- ******************************************
  20. *
  21. *   NAME
  22. *       film.datatype -- data type for IFF FILM movies
  23. *
  24. *   SUPERCLASS
  25. *       animation.datatype
  26. *
  27. *   DESCRIPTION
  28. *       The film datatype, a sub-class of the animation.datatype, is
  29. *       used load and play IFF FILM movies.
  30. *
  31. *   METHODS
  32. *       OM_NEW -- Create a new animation object from a description file. The
  33. *           source may only be a file.
  34. *
  35. *       OM_DISPOSE -- Dispose instance and contents (frames, colormaps,
  36. *           sounds etc.), then pass msg to superclass
  37. *
  38. *       OM_UPDATE -- Perform an ICM_CHECKLOOP check, and if succesfull, the
  39. *           method will be executed like OM_SET downstairs.
  40. *
  41. *       OM_SET -- Pass msg to superclass and call GM_RENDER if retval from
  42. *           superclass was != 0UL.
  43. *
  44. *       GM_LAYOUT 
  45. *       DTM_PROCLAYOUT -- Collect information from superclass, set up
  46. *           struct DTSpecialInfo and send an OM_NOTIFY containing usefull
  47. *           attributes.
  48. *
  49. *       DTM_FRAMEBOX -- Set up object for a specified environment if
  50. *           FRAMEF_SPECIFY was set in (dtf -> dtf_FrameFlags).
  51. *
  52. *       ADTM_LOADFRAME -- Fill in struct adtFrame with requested information
  53. *           from internal FrameNode list like bitmap, colormap and sound.
  54. *
  55. *       ADTM_UNLOADFRAME -- Release resources obtained by ADTM_LOADFRAME like
  56. *           bitmaps, colormaps etc.
  57. *
  58. *       DTM_WRITE -- Save data in local (IFF FILM) or superclass (IFF ILBM)
  59. *           format.
  60. *
  61. *       All other methods are passed unchanged to superclass.
  62. *
  63. *   ATTRIBUTES
  64. *       Following attributes are set by the object and are READ-ONLY for
  65. *       applications:
  66. *       DTA_ObjName       -- reserved
  67. *       DTA_ObjAuthor     -- reserved
  68. *       DTA_ObjAnnotation -- reserved
  69. *       DTA_ObjCopyright  -- reserved
  70. *       DTA_ObjVersion    -- reserved
  71. *       DTA_NominalVert   -- same as ADTA_Width
  72. *       DTA_NominalHoriz  -- same as ADTA_Height
  73. *       ADTA_Width        -- Set by ILBM BitMapHeader
  74. *       ADTA_Height       -- Set by ILBM BitMapHeader
  75. *       ADTA_Depth        -- Set by ILBM BitMapHeader
  76. *
  77. *   BUGS
  78. *       - In large videos, the frames at the end will be played slower than
  79. *         those at the beginning of the file. This is the result of the
  80. *         sequential search internally used (only serious with more than 25000
  81. *         frames (mc6030/50mhz)).
  82. *         May or may not be fixed.
  83. *
  84. *       - Currently, after a full playback mainly all frames are cached
  85. *         because animation.datatype does not flush enougth frane during
  86. *         playback. This is not a bug of animation.datatype. I don't know that
  87. *         return codes of the ADTM_LOADFRAME method which causes
  88. *         animation.datatype to flush unused frames. Without information from
  89. *         CBM, Amiga Technologies or David Junod I cannot fix this bug.
  90. *         Comments welcome !
  91. *
  92. *   TODO
  93. *
  94. *   HISTORY
  95. *       V1.1
  96. *         First public release.
  97. *
  98. *       V1.2
  99. *         - Implemented relative seeking, which speeds up loading.
  100. *
  101. *         - Moved and removed some bounds checking code in the ILBM BODY
  102. *           loader.
  103. *
  104. *         - Moved, removed and new code: Small cleanup.
  105. *
  106. *         - Now supports a prefs file.
  107. *
  108. *         - If a ILBM CAMG-Chunks is missing in the movie and no MODEID
  109. *           option was set, BestModeID is used to get the best matching
  110. *           screen mode.
  111. *
  112. *       V1.3
  113. *         - Now uses interleaved bitmaps for faster loading.
  114. *
  115. *         - Small code cleanup.
  116. *
  117. *       V1.4
  118. *         - Recompiled with SAS/C 6.57.
  119. *
  120. *         - Fixed a small mistake in the template, which may cause crashes
  121. *           or other things (not seen, but...).
  122. *
  123. *         - Implemented VERBOSE prefs switch (verbose information).
  124. *
  125. *         - Stack check included. Forces a stack size of 16KB.
  126. *
  127. *         - Implemented LOADALL prefs switch (load all frames into memory).
  128. *
  129. *       V1.5
  130. *         - Now supports IFF ILBM CMAPs in the CAT CELLs (dynamic palette
  131. *           changes), which are supported by animation.datatype V41 or
  132. *           "DBufDTAnim".
  133. *
  134. *         - Uses OpenFromLock when obtaining a fh for random frame access.
  135. *           This allows the usage of "virtual filesystems" (datatypes.library
  136. *           V45 allows such things).
  137. *
  138. *         - Now the high order bits of each color gun are replicated through 
  139. *           the whole INT32 in the colormap.
  140. *
  141. *         - Now uses EXPERIMENTAL stack swapping code. The "Need more stack"
  142. *           requester has been gone for this reason.
  143. *
  144. *         - Fixed a bug in LibExpunge (didn't check lib_OpenCnt), which is
  145. *           also present in all my other external BOOSI classes (and
  146. *           datatypes).
  147. *           Thanks to Guenter Niki (gniki@informatik.uni-rostok.de) for
  148. *           reporting this bug.
  149. *
  150. *         - Now supports saving in the local format (e.g. IFF FILM).
  151. *           Note that saveing begins with the __current__ frame and can be
  152. *           controlled with the ADTA_Frame, ADTA_Frames and 
  153. *           ADTA_FrameIncrement attributes.
  154. *
  155. *         - Now support DTST_RAM (creates an empty film.datatype object).
  156. *
  157. *         - Now supports subclasses of film.datatype, mainly to fill in
  158. *           the ADTM_LOADFRAME/ADTM_UNLOADFRAME methods when using an empty
  159. *           (e.g. created with DTST_RAM) film.datatype object.
  160. *
  161. *   NOTES
  162. *
  163. *   SEE ALSO
  164. *       animation.datatype,
  165. *       mpegsystem.datatype, mpegvideo.datatype,
  166. *       picmovie.datatype,
  167. *       cdxl.datatype. avi.datatype, quicktime.datatype,
  168. *       directory.datatype,
  169. *       markabletextdtclass
  170. *
  171. *******************************************************************************
  172. *
  173. */
  174.  
  175.  
  176. /****** film.datatype/--input_format-- ****************************************
  177. *
  178. *    NAME
  179. *        IFF FILM -- ILBM frames with interleaved 8SVX samples
  180. *
  181. *    DESCRIPTION
  182. *        A IFF FILM stream contains uncompressed video and audio data.
  183. *        The LIST section contains a ILBM part and a 8SVX part, which
  184. *        must contain a ILBM BMHD (BitMapHeader), a ILBM CMAP
  185. *        (global colormap), a ILMB CAMG (amiga view mod id) and a 8SVX VHDR
  186. *        (VoiceHeader). Other information (like a 8SVX CHAN chunk are
  187. *        optional).
  188. *
  189. *        After this "header" part, the single animation frames will follow.
  190. *        A "frame" consists of a CAT CELL, which contains the video (FORM ILBM
  191. *        BODY) and audio (FORM 8SVX BODY) data; a ILBM CMAP is optional when 
  192. *        palette changes occurs.
  193. *        Each ILBM/8SVX BODY must have exactly the same size, and as a result,
  194. *        all CELLs have the same size (usefull for continous reading).
  195. *
  196. *        Example (created with "sift"):
  197. *        . LIST 736892 FILM
  198. *        . . PROP 100 ILBM          ; shared ILBM properties
  199. *        . . . BMHD 20 ILBM
  200. *        . . . CAMG 4 ILBM
  201. *        . . . CMAP 48 ILBM
  202. *        . . PROP 44 8SVX           ; shared 8SVX properties
  203. *        . . . VHDR 20 8SVX
  204. *        . . . CHAN 4 8SVX
  205. *        . . CAT  16000 CELL        ; 1st cell (frame of movie)
  206. *        . . . FORM 14532 ILBM
  207. *        . . . . BODY 14520 ILBM    ;   ILBM BitMap data
  208. *        . . . FORM 1448 8SVX
  209. *        . . . . BODY 1436 8SVX     ;   8SVX Sample data
  210. *        . . CAT  16000 CELL        ; 2nd cell
  211. *        . . . FORM 14532 ILBM
  212. *        . . . . BODY 14520 ILBM    ;   ILBM BitMap data
  213. *        . . . FORM 1448 8SVX
  214. *        . . . . BODY 1436 8SVX     ;   8SVX Sample data
  215. *        . . CAT  16000 CELL        ; 3rd cell
  216. *        . . . FORM 14532 ILBM
  217. *        . . . . BODY 14520 ILBM    ;   ILBM BitMap data
  218. *        . . . FORM 1448 8SVX
  219. *        . . . . BODY 1436 8SVX     ;   8SVX Sample data
  220. *        and so on....
  221. *
  222. *    SEE ALSO
  223. *        - AminetCD2:gfx/show/AGMSFilm2.LhA, which includes a much better
  224. *          description, the history and background of the IFF FILM format.
  225. *
  226. *        - Aminet:gfx/conv/DumpDTAnim#?.LhA as an implementation of an
  227. *          IFF FILM writer
  228. *
  229. *        - ARKM Devices: IFF part
  230. *
  231. *        - iffparse.library autodocs
  232. *
  233. *******************************************************************************
  234. *
  235. */
  236.  
  237.  
  238.  
  239. /*****************************************************************************/
  240.  
  241. DISPATCHERFLAGS
  242. struct IClass *ObtainFilmEngine( REGA6 struct ClassBase *cb )
  243. {
  244.     return( (cb -> cb_Lib . cl_Class) );
  245. }
  246.  
  247. /*****************************************************************************/
  248.  
  249. DISPATCHERFLAGS
  250. struct Library *LibInit( REGD0 struct ClassBase *cb, REGA0 BPTR seglist, REGA6 struct ExecBase *sysbase )
  251. {
  252.     cb -> cb_SegList = seglist;
  253.     cb -> cb_SysBase = sysbase;
  254.  
  255.     InitSemaphore( (&(cb -> cb_Lock)) );
  256.  
  257.     if( (cb -> cb_SysBase -> LibNode . lib_Version) >= 39UL )
  258.     {
  259.       /* Obtain ROM libs */
  260.       if( cb -> cb_IntuitionBase = OpenLibrary( "intuition.library", 39UL ) )
  261.       {
  262.         if( cb -> cb_GfxBase = OpenLibrary( "graphics.library", 39UL ) )
  263.         {
  264.           if( cb -> cb_DOSBase = OpenLibrary( "dos.library", 39UL ) )
  265.           {
  266.             if( cb -> cb_IFFParseBase = OpenLibrary( "iffparse.library", 39UL ) )
  267.             {
  268.               if( cb -> cb_UtilityBase = OpenLibrary( "utility.library", 39UL ) )
  269.               {
  270.                 return( (&(cb -> cb_Lib . cl_Lib)) );
  271.  
  272. #ifdef COMMENTED_OUT
  273.                 CloseLibrary( UtilityBase );
  274. #endif /* COMMENTED_OUT */
  275.               }
  276.  
  277.               CloseLibrary( IFFParseBase );
  278.             }
  279.  
  280.             CloseLibrary( DOSBase );
  281.           }
  282.  
  283.           CloseLibrary( GfxBase );
  284.         }
  285.  
  286.         CloseLibrary( IntuitionBase );
  287.       }
  288.     }
  289.  
  290.     return( NULL );
  291. }
  292.  
  293. /*****************************************************************************/
  294.  
  295. DISPATCHERFLAGS
  296. LONG LibOpen( REGA6 struct ClassBase *cb )
  297. {
  298.     LONG retval = (LONG)cb;
  299.     BOOL success = TRUE;
  300.  
  301.     ObtainSemaphore( (&(cb -> cb_Lock)) );
  302.  
  303.     /* Use an internal use counter */
  304.     cb -> cb_Lib . cl_Lib . lib_OpenCnt++;
  305.     cb -> cb_Lib . cl_Lib . lib_Flags &= ~LIBF_DELEXP;
  306.  
  307.     if( (cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 1U )
  308.     {
  309.       if( (cb -> cb_Lib . cl_Class) == NULL )
  310.       {
  311.         success = FALSE;
  312.  
  313.         if( cb -> cb_DataTypesBase = OpenLibrary( "datatypes.library", 39UL ) )
  314.         {
  315.           if( cb -> cb_SuperClassBase = OpenLibrary( "datatypes/animation.datatype", 39UL ) )
  316.           {
  317.             if( cb -> cb_Lib . cl_Class = initClass( cb ) )
  318.             {
  319.               success = TRUE;
  320.             }
  321.           }
  322.         }
  323.       }
  324.     }
  325.  
  326.     if( !success )
  327.     {
  328.       CloseLibrary( (cb -> cb_SuperClassBase) );
  329.       CloseLibrary( (cb -> cb_DataTypesBase) );
  330.  
  331.       cb -> cb_DataTypesBase = cb -> cb_SuperClassBase = NULL;
  332.  
  333.       (cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
  334.  
  335.       retval = 0L;
  336.     }
  337.  
  338.     ReleaseSemaphore( (&(cb -> cb_Lock)) );
  339.  
  340.     return( retval );
  341. }
  342.  
  343. /*****************************************************************************/
  344.  
  345. DISPATCHERFLAGS
  346. LONG LibClose( REGA6 struct ClassBase *cb )
  347. {
  348.     LONG retval = 0L;
  349.  
  350.     ObtainSemaphore( (&(cb -> cb_Lock)) );
  351.  
  352.     if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
  353.     {
  354.       (cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
  355.     }
  356.  
  357.     if( ((cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 0U) && (cb -> cb_Lib . cl_Class) )
  358.     {
  359.       if( FreeClass( (cb -> cb_Lib . cl_Class) ) )
  360.       {
  361.         cb -> cb_Lib . cl_Class = NULL;
  362.  
  363.         CloseLibrary( (cb -> cb_SuperClassBase) );
  364.         CloseLibrary( (cb -> cb_DataTypesBase) );
  365.       }
  366.       else
  367.       {
  368.         cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
  369.       }
  370.     }
  371.  
  372.     ReleaseSemaphore( (&(cb -> cb_Lock)) );
  373.  
  374.     if( cb -> cb_Lib . cl_Lib . lib_Flags & LIBF_DELEXP )
  375.     {
  376.       retval = LibExpunge( cb );
  377.     }
  378.  
  379.     return( retval );
  380. }
  381.  
  382. /*****************************************************************************/
  383.  
  384. DISPATCHERFLAGS
  385. LONG LibExpunge( REGA6 struct ClassBase *cb )
  386. {
  387.     BPTR seg;
  388.  
  389.     if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
  390.     {
  391.       cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
  392.  
  393.       seg = NULL;
  394.     }
  395.     else
  396.     {
  397.       Remove( (&(cb -> cb_Lib . cl_Lib . lib_Node)) );
  398.  
  399.       seg = cb -> cb_SegList;
  400.  
  401.       CloseLibrary( (cb -> cb_UtilityBase) );
  402.       CloseLibrary( (cb -> cb_IFFParseBase) );
  403.       CloseLibrary( (cb -> cb_DOSBase) );
  404.       CloseLibrary( (cb -> cb_GfxBase) );
  405.       CloseLibrary( (cb -> cb_IntuitionBase) );
  406.  
  407.       FreeMem( (APTR)((ULONG)(cb) - (ULONG)(cb -> cb_Lib . cl_Lib . lib_NegSize)), (ULONG)((cb -> cb_Lib . cl_Lib . lib_NegSize) + (cb -> cb_Lib . cl_Lib . lib_PosSize)) );
  408.     }
  409.  
  410.     return( (LONG)seg );
  411. }
  412.  
  413.  
  414.