Flx.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. #ifndef FLX_H
  19. #define FLX_H
  20. #include "file/file.h"
  21. // Define the magic numbers for FLC and FLI files.
  22. #define FLX_MAGIC_FLI 0xAF11
  23. #define FLX_MAGIC_FLC 0xAF12
  24. // Define operation modes
  25. #define FLX_RETURN_DELTAS 0
  26. #define FLX_RETURN_FULL 1
  27. // Define data chunk types
  28. #define FLX_DATA_COLOR256 4
  29. #define FLX_DATA_SS2 7
  30. #define FLX_DATA_COLOR 11
  31. #define FLX_DATA_LC 12
  32. #define FLX_DATA_BLACK 13
  33. #define FLX_DATA_BRUN 15
  34. #define FLX_DATA_COPY 16
  35. #define FLX_DATA_PSTAMP 18
  36. #ifndef RAMFLX_H // Already defined if RAMFLX.H was included.
  37. // Define struct that describes everything in a FLC/FLI header. The header is
  38. // 128 UCHARs for both FLC and FLI files, but the usage is somewhat different.
  39. typedef struct tag_FLX_FILE_HDR
  40. {
  41. long lEntireFileSize; // Size of entire file, including header
  42. USHORT wMagic; // Magic number: FLC = $af12, FLI = $af11
  43. short sNumFrames; // Number of frames, not including ring. Max 4000.
  44. short sWidth; // Width in pixels (always 320 in FLI)
  45. short sHeight; // Height in pixels (always 200 in FLI)
  46. short sDepth; // Bits per pixel (always 8)
  47. USHORT sFlags; // FLC: set to 3 if properly written, FLI: always 0
  48. long lMilliPerFrame; // FLC: milliseconds between frames (4 UCHARs)
  49. // FLI: jiffies (1/70th) between frames (2 UCHARs)
  50. // The rest is for FLC files only -- for FLI files, it's all reserved.
  51. USHORT sReserveA; // Reserved -- set to zero
  52. ULONG dCreatedTime; // MS-DOS-formatted date and time of file's creation
  53. ULONG dCreator; // Serial number of Animator Pro program used to
  54. // create file -- $464c4942 is a good one ("FLIB")
  55. ULONG dUpdatedTime; // MS-DOS-formatted date and time of file's update
  56. ULONG dUpdater; // Serial number of Animator Pro program used to
  57. // update file -- $464c4942 is a good one ("FLIB")
  58. short sAspectX; // X-axis aspect ratio at which file was created
  59. short sAspectY; // Y-axis aspect ratio at which file was created
  60. UCHAR bReservedB[38]; // Reserved -- set to zeroes
  61. long lOffsetFrame1; // Offset from beginning of file to first frame chunk
  62. long lOffsetFrame2; // Offset from beginning of file to second frame chunk,
  63. // used when looping from ring back to second frame
  64. UCHAR bReservedC[40]; // Reserved -- set to zeroes
  65. } FLX_FILE_HDR;
  66. // Define struct that describes frame chunk header.
  67. typedef struct tag_FLX_FRAME_HDR
  68. {
  69. long lChunkSize; // Size of entire frame chunk, including header
  70. // and all subordinate chunks
  71. USHORT wType; // Frame header chunk id: always 0xF1FA
  72. short sNumSubChunks; // Number of subordinate chunks. 0 indicates that
  73. // this frame is identical to previous frame.
  74. UCHAR bReserved[8]; // Reserved
  75. } FLX_FRAME_HDR;
  76. // Define struct that describes data chunk header.
  77. typedef struct tag_FLX_DATA_HDR
  78. {
  79. long lChunkSize; // Size of frame data chunk, including header
  80. USHORT wType; // Type of frame data chunk
  81. // NOTE: The actual data follows these two items, but is not
  82. // included in this struct because it has a variable size!
  83. } FLX_DATA_HDR;
  84. // Define struct that describes RGB color data as used by a FLC/FLI
  85. typedef struct tag_FLX_RGB
  86. {
  87. UCHAR bR;
  88. UCHAR bG;
  89. UCHAR bB;
  90. } FLX_RGB;
  91. #endif // RAMFLX_H
  92. // Define struct that describes the buffers where a frame's data is stored
  93. typedef struct tag_FLX_BUF
  94. {
  95. UCHAR* pbPixels; // Pointer to memory for pixel data
  96. short sPitch; // Pitch to be used for pixel data
  97. FLX_RGB* prgbColors; // Pointer to memory for color data (normally 256 colors)
  98. short bPixelsModified; // TRUE if pixels were modified (only valid after a "Read")
  99. short bColorsModified; // TRUE if colors were modified (only valid after a "Read")
  100. } FLX_BUF;
  101. // Define class
  102. class CFlx
  103. {
  104. public:
  105. // Default constructor. If this is used, then Setup() must be called before
  106. // any other function can be called.
  107. CFlx(void);
  108. // Destructor.
  109. ~CFlx();
  110. // Open an existing FLC/FLI file for reading. You can optionally get a copy of
  111. // the file header and can optionally have your buf memory allocated for you.
  112. // Returns 0 if successfull, non-zero otherwise.
  113. short Open(
  114. char* pszFileName, // Full path and filename of flic file
  115. short bSimple, // TRUE for simple mode, FALSE for advanced stuff
  116. FLX_FILE_HDR* pfilehdr, // Copy of header returned here if not NULL
  117. FLX_BUF* pbuf); // Memory allocated within struct if not NULL
  118. // Create a new flic file to be written to (the file cannot already exist).
  119. // The newer FLC format is written unless bOldFLI is TRUE, in which case the
  120. // older FLI format is used. You can optionally get a copy of the file header
  121. // and can optionally have your buf memory allocated for you.
  122. // Returns 0 if successfull, non-zero otherwise.
  123. short Create(
  124. char* pszFileName, // Full path and filename of flic file
  125. short bReplaceExisting, // TRUE if okay to replace existing file
  126. short sWidth, // Width of flic
  127. short sHeight, // Height of flic
  128. long lMilliPerFrame, // Milliseconds between frames
  129. short sAspectX, // X aspect ratio
  130. short sAspectY, // Y aspect ratio
  131. short bOldFLI, // TRUE for old FLI format, FALSE for new FLC
  132. short bSimple, // TRUE for simple mode, FALSE for advanced stuff
  133. FLX_FILE_HDR* pfilehdr, // Copy of header returned here if not NULL
  134. FLX_BUF* pbuf); // Memory allocated within struct if not NULL
  135. // Close the currently open file (if any).
  136. // Returns 0 if successfull, non-zero otherwise.
  137. // Modified 10/20/94 to accommodate buffer pointer
  138. short Close(FLX_BUF* pbuf = NULL);
  139. // Get copy of flic file header (file must have been opened or created). When
  140. // creating a new file, certain fields are not valid until the file is closed.
  141. // Returns 0 if successfull, non-zero otherwise.
  142. short GetHeader(FLX_FILE_HDR* pHeader);
  143. // Get the current frame number. When reading, this is the frame that was
  144. // last read. When writing, this is the frame that was last written. In both
  145. // cases, a value of 0 indicates that no frames have been read or written.
  146. // Otherwise, the number will be from 1 to n.
  147. short GetFrameNum(void);
  148. // Read the specified flic frame (1 to n, anything else is an error). The
  149. // time it takes to get the frame is proportional to the number of frames
  150. // between it and the last frame that was read. In simple mode, if the same
  151. // frame is requested more than once in a row, that frame is simply returned
  152. // each time. In non-simple mode, requesting the same frame again requires
  153. // us to restart the animation and work our way up to that frame again.
  154. // Returns 0 if successfull, non-zero otherwise.
  155. short ReadFrame(
  156. short sFrameNum, // Frame number to be read
  157. FLX_BUF* pbufRead); // Buffer for frame being read
  158. // Read the next flic frame (if flic was just opened, this will read frame 1).
  159. // Returns 0 if successfull, non-zero otherwise.
  160. short ReadNextFrame(
  161. FLX_BUF* pbufRead); // Buffer for frame being read
  162. // Write the next flic frame. If this function is used at all, it must be used
  163. // for writing every frame of the flic (do not use the other frame writing
  164. // functions). Create() must have been called before calling this function.
  165. // After the last frame has been written, call WriteFinish() and then Close().
  166. // Returns 0 if successfull, non-zero otherwise.
  167. short WriteNextFrame(
  168. FLX_BUF* pbufWrite); // Buffer of frame to be written
  169. // Finish writing the flic file. This must be called after the last frame was
  170. // written but before closing the file. The first and last frames are required
  171. // in order to generate the "ring" frame (used for looping the animation).
  172. // If you don't want a ring frame, simply specify NULL for both parameters.
  173. // The header is also updated with the final information for the file.
  174. // Returns 0 if successfull, non-zero otherwise.
  175. short WriteFinish(
  176. FLX_BUF* pbufFirst, // Buffer of first frame that was written or NULL
  177. FLX_BUF* pbufLast); // Buffer of last frame that was written or NULL
  178. // This is a lower-level function. You probably don't want to use it.
  179. // Returns 0 if successfull, non-zero otherwise.
  180. short WriteFirstFrame(
  181. FLX_BUF* pbufWrite); // Buffer of frame to be written
  182. // This is a lower-level function (same name as other function but different
  183. // parameters!) You probably don't want to use it.
  184. short WriteNextFrame(
  185. FLX_BUF* pbufWrite, // Buffer of frame to be written
  186. FLX_BUF* pbufPrev); // Buffer of previous frame (already written)
  187. // Create a FLX_BUF based on the specified width, height, and number of colors.
  188. // Returns 0 if successfull, non-zero otherwise.
  189. short CreateBuf(FLX_BUF* pbuf, short sWidth, short sHeight, short sColors);
  190. // Destroy a FLX_BUF that was previously created using CreateBuf().
  191. // The FLX_BUF must not be used after this call!
  192. void DestroyBuf(FLX_BUF* pbuf);
  193. private:
  194. void Restart(void);
  195. short DoReadFrame(FLX_BUF* pbufRead);
  196. short ReadDataColor(FLX_BUF* pbufRead, short sDataType);
  197. short ReadDataBlack(FLX_BUF* pbufRead);
  198. short ReadDataCopy(FLX_BUF* pbufRead);
  199. short ReadDataBRun(FLX_BUF* pbufRead);
  200. short ReadDataLC(FLX_BUF* pbufRead);
  201. short ReadDataSS2(FLX_BUF* pbufRead);
  202. short DoWriteFrame(FLX_BUF* pbufWrite, FLX_BUF* pbufPrev);
  203. short WriteColorDelta(FLX_BUF* pbufNext, FLX_BUF* pbufPrev, UCHAR* pBuf, long* plChunkSize);
  204. short WritePixelDelta(FLX_BUF* pbufNext, FLX_BUF* pbufPrev, UCHAR* pBuf, long* plChunkSize);
  205. short WriteDataChunk(UCHAR* pData, long lSize, USHORT wType, long* plChunkSize);
  206. short CompressLineDelta(
  207. short y, // Current line to compress, used to calculate offset.
  208. FLX_BUF* pbufNext, // Pointer to current flx frame.
  209. FLX_BUF* pbufPrev, // Pointer to previous flx frame.
  210. UCHAR* pbDst, // Pointer to the chunk storage.
  211. long& lSize, // Size of the data used by current compressed line.
  212. short sAlign, // 1 = UCHAR oriented, 2 = USHORT oriented
  213. short sLineSkipCount = 0); // Used only for USHORT oriented delta compression during which
  214. // the line skip count will be written out to the chunk.
  215. long CompressBRUN(
  216. UCHAR* pbIn, // Pointer to input (pixels to be compressed)
  217. short sPitch, // Pitch (distance from one pixel to the pixel below it)
  218. short sSrcX, // Starting x of rectangular area to compress
  219. short sSrcY, // Starting y of rectangular area to compress
  220. short sWidth, // Width of rectangular area to compress
  221. short sHeight, // Height of rectangular area to compress
  222. UCHAR* pbOut); // Pointer to output (compressed data)
  223. short ReadHeader(void);
  224. short WriteHeader(void);
  225. void ClearHeader(void);
  226. void InitBuf(FLX_BUF* pbuf);
  227. short AllocBuf(FLX_BUF* pbuf, short sWidth, short sHeight, short sColors);
  228. void FreeBuf(FLX_BUF* pbuf);
  229. void CopyBuf(FLX_BUF* pbufDst, FLX_BUF* pbufSrc);
  230. private:
  231. short m_bOpenForRead; // TRUE if file is open for read
  232. short m_bOpenForWrite; // TRUE if file is open for write
  233. short m_bSimple; // TRUE for simple mode (simple for the user)
  234. FLX_FILE_HDR m_filehdr; // File header
  235. FLX_BUF m_bufPrev; // Buf for previous frame
  236. FLX_BUF m_bufFirstFrame; // Buf for the first frame
  237. short m_bReadColors; // Whether or not to read colors from flic
  238. short m_bReadPixels; // Whether or not to read pixels from flic
  239. short m_sFrameNum; // Current frame number, 1 to n, 0 means none
  240. CNFile m_file; // File stream (for buffered file I/O)
  241. };
  242. #endif // FLX_H