home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / datatypes / film_datatype / classbase.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-27  |  14.0 KB  |  449 lines

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