Flx.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  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. ///////////////////////////////////////////////////////////////////////////////
  19. //
  20. // FLX.CPP
  21. //
  22. // History:
  23. // 08/05/94 MR Started. (10h)
  24. //
  25. // 08/07/94 MR Got decompression working (except for SS2) and started
  26. // on compression. (13h)
  27. //
  28. // 08/08/94 MR General cleanup of interfaces, etc. (12h)
  29. //
  30. // 08/09/94 MR Finished up basic compression.
  31. //
  32. // 08/12/94 MR Added flags to FLX_BUF struct that indicate whether the
  33. // pixels and/or the colors were modified by a "Read".
  34. //
  35. // 08/15/94 MR Fixed bug in ReadFrame() -- if the requested frame was
  36. // the current frame, it was not copied to the specified buf.
  37. //
  38. // Also added a function that returns the last frame that
  39. // was written.
  40. //
  41. // 03/06/96 JMI Converted references from PORTABLE.H (e.g., DWORD) to
  42. // references from SYSTEM.H (e.g., ULONG).
  43. //
  44. //
  45. ///////////////////////////////////////////////////////////////////////////////
  46. //
  47. // THIS FILE CONTAINS ONLY THE PUBLIC FUNCTIONS.
  48. // THE PRIVATE FUNCTIONS ARE IN FLXP.CPP
  49. //
  50. ///////////////////////////////////////////////////////////////////////////////
  51. //
  52. // Offers a clean and simple interface for reading and writing .FLC files.
  53. //
  54. // MEGA WARNING: The memory management being used in this module relies
  55. // completely on the memory model under which it is compiled. The recommended
  56. // model is large. However, in large model, flics larger than 320 x 200 are
  57. // not possible since the image data would exceed 64k! In the 32-bit future,
  58. // this will no longer be a problem. For now, we're stuck with it.
  59. // Note that using the huge memory model will not help because many of the
  60. // math and the indexes are "short" (16 bits), so the results would not be/
  61. // valid for larger than 320 x 200!
  62. //
  63. ///////////////////////////////////////////////////////////////////////////////
  64. #include "common/system.h"
  65. #include "flx/FLX.H"
  66. ///////////////////////////////////////////////////////////////////////////////
  67. //
  68. // Default constructor. If this is used, then Setup() must be called before
  69. // any other function can be called.
  70. //
  71. ///////////////////////////////////////////////////////////////////////////////
  72. CFlx::CFlx(void)
  73. {
  74. // Set flags to default states
  75. m_bOpenForRead = FALSE;
  76. m_bOpenForWrite = FALSE;
  77. // Init FLX_BUF
  78. InitBuf(&m_bufPrev);
  79. InitBuf(&m_bufFirstFrame);
  80. // Clear file header
  81. ClearHeader();
  82. }
  83. ///////////////////////////////////////////////////////////////////////////////
  84. //
  85. // Destructor.
  86. //
  87. ///////////////////////////////////////////////////////////////////////////////
  88. CFlx::~CFlx()
  89. {
  90. // Close in case file was left open
  91. Close();
  92. // Clear header in case it's illegally accessed after we're destroyed
  93. ClearHeader();
  94. // Free any memory that needs freeing
  95. FreeBuf(&m_bufPrev);
  96. FreeBuf(&m_bufFirstFrame);
  97. // Clear flags to default values (same reason we cleared header)
  98. m_bOpenForRead = FALSE;
  99. m_bOpenForWrite = FALSE;
  100. }
  101. ///////////////////////////////////////////////////////////////////////////////
  102. //
  103. // Open an existing FLC/FLI file for reading. You can optionally get a copy of
  104. // the file header and can optionally have your buf memory allocated for you.
  105. // Returns 0 if successfull, non-zero otherwise.
  106. //
  107. // 10/20/94, Paul Lin, add code to reset error conditions on the fstream object
  108. // so that the next time this function is called, it doesn't fail
  109. //
  110. ///////////////////////////////////////////////////////////////////////////////
  111. short CFlx::Open(
  112. char* pszFileName, // Full path and filename of flic file
  113. short bSimple, // TRUE for simple mode, FALSE for advanced stuff
  114. FLX_FILE_HDR* pfilehdr, // Copy of header returned here if not NULL
  115. FLX_BUF* pbuf) // Memory allocated within struct if not NULL
  116. {
  117. short sError = 0;
  118. // Close in case it was left open
  119. Close();
  120. // Clear file header. This is done primarily for the older FLI files
  121. // so that all fields, even those that aren't used by FLI files, will
  122. // be set to default values.
  123. ClearHeader();
  124. // Open file (only if it already exists -- do not create new file!)
  125. if (m_file.Open(pszFileName, "rb", ENDIAN_LITTLE) == 0)
  126. {
  127. // Set file mode to binary (this seems to be necessary even
  128. // though we specified ios::binary when we opened the stream)
  129. // Read the header. Regardless of whether it's a FLC or FLI file,
  130. // the header is returned as if it was a FLC file.
  131. if (ReadHeader() == 0)
  132. {
  133. // Restart animation
  134. Restart();
  135. // Default is to read both pixels and color data from flic
  136. m_bReadPixels = TRUE;
  137. m_bReadColors = TRUE;
  138. // If user wants simple operation, then we need to allocate buffers for the
  139. // previous frame and the previous color palette.
  140. m_bSimple = bSimple;
  141. if (m_bSimple)
  142. {
  143. sError = AllocBuf(&m_bufPrev, m_filehdr.sWidth, m_filehdr.sHeight, 256);
  144. sError = AllocBuf(&m_bufPrev, m_filehdr.sWidth, m_filehdr.sHeight, 256);
  145. }
  146. }
  147. else
  148. sError = 1;
  149. }
  150. else
  151. sError = 1;
  152. // Final check for file errors
  153. if ((sError == 0) && m_file.Error() != FALSE)
  154. sError = 1;
  155. // If pointer to header not NULL, then return copy of header there
  156. if ((sError == 0) && (pfilehdr != NULL))
  157. *pfilehdr = m_filehdr;
  158. // If pointer to buf not NULL, then allocate memory
  159. if ((sError == 0) && (pbuf != NULL))
  160. sError = CreateBuf(pbuf, m_filehdr.sWidth, m_filehdr.sHeight, 256);
  161. // If no errors, then file is finally marked "open for reading"
  162. if (sError == 0)
  163. m_bOpenForRead = TRUE;
  164. // If error, reset the fstream object
  165. if (sError == 1)
  166. {
  167. // clear the ios's error flags
  168. m_file.ClearError();
  169. }
  170. return sError;
  171. }
  172. ///////////////////////////////////////////////////////////////////////////////
  173. //
  174. // Create a new flic file to be written to (the file cannot already exist).
  175. // The newer FLC format is written unless bOldFLI is TRUE, in which case the
  176. // older FLI format is used. You can optionally get a copy of the file header
  177. // and can optionally have your buf memory allocated for you.
  178. // Returns 0 if successfull, non-zero otherwise.
  179. //
  180. ///////////////////////////////////////////////////////////////////////////////
  181. short CFlx::Create(
  182. char* pszFileName, // Full path and filename of flic file
  183. short bReplaceExisting, // TRUE if okay to replace existing file
  184. short sWidth, // Width of flic
  185. short sHeight, // Height of flic
  186. long lMilliPerFrame, // Milliseconds between frames
  187. short sAspectX, // X aspect ratio
  188. short sAspectY, // Y aspect ratio
  189. short bOldFLI, // TRUE for old FLI format, FALSE for new FLC
  190. short bSimple, // TRUE for simple mode, FALSE for advanced stuff
  191. FLX_FILE_HDR* pfilehdr, // Copy of header returned here if not NULL
  192. FLX_BUF* pbuf) // Memory allocated within struct if not NULL
  193. {
  194. short sError = 0;
  195. // Close in case it was left open
  196. Close();
  197. // Create file. Depending on what user selected, either allow for the
  198. // replacement of existing files or don't.
  199. short sSux;
  200. if (bReplaceExisting)
  201. sSux = m_file.Open(pszFileName, "wb", ENDIAN_LITTLE);
  202. else
  203. {
  204. // There's no no-replace flag so we must text.
  205. if (m_file.Open(pszFileName, "rb", ENDIAN_LITTLE) == 0)
  206. {
  207. // File exists.
  208. sSux = TRUE;
  209. m_file.Close();
  210. }
  211. else
  212. {
  213. // File doesn't exist.
  214. sSux = m_file.Open(pszFileName, "wb", ENDIAN_LITTLE);
  215. }
  216. }
  217. if (sSux == FALSE)
  218. {
  219. // Set file mode to binary (this seems to be necessary even
  220. // though we specified ios::binary when we opened the stream)
  221. // Clear header to set reserved fields to default values.
  222. ClearHeader();
  223. // Fill in as many real values as possible. Certain values will
  224. // need to be updated after all the frames have been written.
  225. m_filehdr.lEntireFileSize = 0; // Not yet known!
  226. if (bOldFLI)
  227. m_filehdr.wMagic = FLX_MAGIC_FLI; // Old FLI format
  228. else
  229. m_filehdr.wMagic = FLX_MAGIC_FLC; // New FLC format
  230. m_filehdr.sNumFrames = 0; // Not yet known!
  231. m_filehdr.sWidth = sWidth; // Set width
  232. m_filehdr.sHeight = sHeight; // Set height
  233. m_filehdr.sDepth = 8; // Always 8 (256 colors)
  234. m_filehdr.sFlags = 0; // 0 until header is written
  235. m_filehdr.lMilliPerFrame = lMilliPerFrame; // Set timing
  236. m_filehdr.dCreatedTime = 0; // Set to 0 for now (too lazy)
  237. m_filehdr.dCreator = 0x464c4942; // Set to "FLIB" as per doc's
  238. m_filehdr.dUpdatedTime = 0; // Set to 0 for now (too lazy)
  239. m_filehdr.dUpdater = 0x464c4942; // Set to "FLIB" as per doc's
  240. m_filehdr.sAspectX = sAspectX; // Set aspect x
  241. m_filehdr.sAspectY = sAspectY; // Set aspect y
  242. m_filehdr.lOffsetFrame1 = 128; // Immediately after header
  243. m_filehdr.lOffsetFrame2 = 0; // Not yet known!
  244. // Write out header (but don't mark as complete yet!)
  245. WriteHeader();
  246. // Reset current frame number
  247. m_sFrameNum = 0;
  248. // If user wants simple operation, then we need to allocate buffers for the
  249. // previous frame and the previous color palette.
  250. m_bSimple = bSimple;
  251. if (m_bSimple)
  252. {
  253. sError = AllocBuf(&m_bufPrev, m_filehdr.sWidth, m_filehdr.sHeight, 256);
  254. sError = AllocBuf(&m_bufFirstFrame, m_filehdr.sWidth, m_filehdr.sHeight, 256);
  255. }
  256. }
  257. else
  258. sError = 1;
  259. // Final check for file errors
  260. if ((sError == 0) && m_file.Error() != FALSE)
  261. sError = 1;
  262. // If pointer to header not NULL, then return copy of header there
  263. if ((sError == 0) && (pfilehdr != NULL))
  264. *pfilehdr = m_filehdr;
  265. // If pointer to buf not NULL, then allocate memory
  266. if ((sError == 0) && (pbuf != NULL))
  267. sError = CreateBuf(pbuf, m_filehdr.sWidth, m_filehdr.sHeight, 256);
  268. // If no errors, then file is finally marked "open for writing"
  269. if (sError == 0)
  270. m_bOpenForWrite = TRUE;
  271. return sError;
  272. }
  273. ///////////////////////////////////////////////////////////////////////////////
  274. //
  275. // Close the currently open file (if any). If a flic was being written to the
  276. // file, this will NOT properly complete the file. A separate function is
  277. // supplied for that, and it should be called before this function.
  278. // Returns 0 if successfull, non-zero otherwise.
  279. //
  280. ///////////////////////////////////////////////////////////////////////////////
  281. short CFlx::Close(FLX_BUF* pbuf)
  282. {
  283. short sError = 1;
  284. // Before we close the file, let's write the ring frame!
  285. if (m_bOpenForWrite)
  286. {
  287. WriteFinish(&m_bufFirstFrame, &m_bufPrev);
  288. }
  289. // If file is open, try to close it.
  290. if (m_bOpenForRead || m_bOpenForWrite)
  291. {
  292. if (m_file.Close() == 0)
  293. {
  294. // Clear flags
  295. m_bOpenForRead = FALSE;
  296. m_bOpenForWrite = FALSE;
  297. // Free any memory associated with buf
  298. FreeBuf(&m_bufPrev);
  299. // Successfull
  300. sError = 0;
  301. }
  302. }
  303. else
  304. sError = 0;
  305. // let's free the buffer passed in, if valid
  306. if (pbuf != NULL)
  307. FreeBuf(pbuf);
  308. return sError;
  309. }
  310. ///////////////////////////////////////////////////////////////////////////////
  311. //
  312. // Get copy of flic file header (file must have been opened or created). When
  313. // creating a new file, certain fields are not valid until the file is closed.
  314. // Returns 0 if successfull, non-zero otherwise.
  315. //
  316. ///////////////////////////////////////////////////////////////////////////////
  317. short CFlx::GetHeader(FLX_FILE_HDR* pFileHdr)
  318. {
  319. short sError = 1;
  320. if (m_bOpenForRead || m_bOpenForWrite)
  321. {
  322. // Copy our header struct to user's struct
  323. *pFileHdr = m_filehdr;
  324. sError = 0;
  325. }
  326. return sError;
  327. }
  328. ///////////////////////////////////////////////////////////////////////////////
  329. //
  330. // Get the current frame number. When reading, this is the frame that was
  331. // last read. When writing, this is the frame that was last written. In both
  332. // cases, a value of 0 indicates that no frames have been read or written.
  333. // Otherwise, the number will be from 1 to n.
  334. //
  335. ///////////////////////////////////////////////////////////////////////////////
  336. short CFlx::GetFrameNum(void)
  337. {
  338. return m_sFrameNum;
  339. }
  340. ///////////////////////////////////////////////////////////////////////////////
  341. //
  342. // Read the specified flic frame (1 to n, anything else is an error). The
  343. // time it takes to get the frame is proportional to the number of frames
  344. // between it and the last frame that was read. In simple mode, if the same
  345. // frame is requested more than once in a row, that frame is simply returned
  346. // each time. In non-simple mode, requesting the same frame again requires
  347. // us to restart the animation and work our way up to that frame again.
  348. // Returns 0 if successfull, non-zero otherwise.
  349. //
  350. ///////////////////////////////////////////////////////////////////////////////
  351. short CFlx::ReadFrame(
  352. short sFrameNum, // Frame number to be read
  353. FLX_BUF* pbufRead) // Buffer for frame being read
  354. {
  355. short sError = 0;
  356. if (m_bOpenForRead)
  357. {
  358. // Make sure valid frame number was specified
  359. if ((sFrameNum >= 1) && (sFrameNum <= m_filehdr.sNumFrames))
  360. {
  361. // If we're in simple mode and the requested frame is the current
  362. // frame, then we can handle it quickly.
  363. if (m_bSimple && (sFrameNum == m_sFrameNum))
  364. {
  365. // Copy the frame from our buffer to the user buffer.
  366. // Note that we copy the modified flags, too!
  367. CopyBuf(pbufRead, &m_bufPrev);
  368. pbufRead->bPixelsModified = m_bufPrev.bPixelsModified;
  369. pbufRead->bColorsModified = m_bufPrev.bColorsModified;
  370. }
  371. else
  372. {
  373. // If specified frame is before (or equal to) the current frame,
  374. // we need to restart the animation.
  375. if (sFrameNum <= m_sFrameNum)
  376. Restart();
  377. // Go frame-by-frame to the requested frame
  378. while ((m_sFrameNum < sFrameNum) && (sError == 0))
  379. sError = ReadNextFrame(pbufRead);
  380. }
  381. }
  382. else
  383. sError = 1;
  384. }
  385. else
  386. sError = 1;
  387. return sError;
  388. }
  389. ///////////////////////////////////////////////////////////////////////////////
  390. //
  391. // Read the next flic frame (if flic was just opened, this will read frame 1).
  392. // The "modified" flags are updated in the specified FLX_BUF.
  393. // Returns 0 if successfull, non-zero otherwise.
  394. //
  395. ///////////////////////////////////////////////////////////////////////////////
  396. short CFlx::ReadNextFrame(
  397. FLX_BUF* pbufRead) // Buffer for frame being read
  398. {
  399. short sError = 0;
  400. if (m_bOpenForRead)
  401. {
  402. if (m_bSimple)
  403. {
  404. // Apply delta to our buf and copy result to user buf.
  405. // Note that we copy the modified flags, too!
  406. sError = DoReadFrame(&m_bufPrev);
  407. if (sError == 0)
  408. {
  409. CopyBuf(pbufRead, &m_bufPrev);
  410. pbufRead->bPixelsModified = m_bufPrev.bPixelsModified;
  411. pbufRead->bColorsModified = m_bufPrev.bColorsModified;
  412. }
  413. }
  414. else
  415. {
  416. // Apply delta directly to user buf
  417. DoReadFrame(pbufRead);
  418. }
  419. }
  420. else
  421. sError = 1;
  422. return sError;
  423. }
  424. ///////////////////////////////////////////////////////////////////////////////
  425. //
  426. // Write the next flic frame. This function can only be used if "simple" mode
  427. // was specified to the Create() function (which must be called before this).
  428. // Don't mix calls to this and other frame writing functions. After the last
  429. // frame has been written, call WriteFinish() and then Close().
  430. // Returns 0 if successfull, non-zero otherwise.
  431. //
  432. ///////////////////////////////////////////////////////////////////////////////
  433. short CFlx::WriteNextFrame(
  434. FLX_BUF* pbufWrite) // Buffer of frame to be written
  435. {
  436. short sError = 0;
  437. // Verify open for writing and simple mode and header not written yet
  438. if (m_bOpenForWrite && m_bSimple && (m_filehdr.sFlags != 3))
  439. {
  440. // In simple mode, we keep a copy of the previous frame so the user
  441. // doesn't have to.
  442. if (m_sFrameNum == 0)
  443. {
  444. sError = WriteFirstFrame(pbufWrite);
  445. // Since this is the first frame, copy it to the first frame buffer for ring frame use later.
  446. CopyBuf(&m_bufFirstFrame, pbufWrite);
  447. }
  448. else
  449. sError = DoWriteFrame(pbufWrite, &m_bufPrev);
  450. CopyBuf(&m_bufPrev, pbufWrite);
  451. }
  452. else
  453. sError;
  454. return sError;
  455. }
  456. ///////////////////////////////////////////////////////////////////////////////
  457. //
  458. // Read the specified flic frame (1 to n, anything else is an error). The
  459. // time it takes to get the frame is proportional to the number of frames
  460. // between it and the last frame that was read.
  461. // Returns 0 if successfull, non-zero otherwise.
  462. //
  463. ///////////////////////////////////////////////////////////////////////////////
  464. short CFlx::WriteFirstFrame(
  465. FLX_BUF* pbufWrite) // Buffer of frame to be written
  466. {
  467. if (m_bOpenForWrite && (m_sFrameNum == 0))
  468. return DoWriteFrame(pbufWrite, NULL);
  469. else
  470. return 1;
  471. }
  472. ///////////////////////////////////////////////////////////////////////////////
  473. //
  474. // Write the next flic frame (actually, write the delta between it and the
  475. // previous frame. Both Create() and WriteFirstFrame() must be called
  476. // successfully before calling this function for each of the remaining frames.
  477. // Returns 0 if successfull, non-zero otherwise.
  478. //
  479. ///////////////////////////////////////////////////////////////////////////////
  480. short CFlx::WriteNextFrame(
  481. FLX_BUF* pbufWrite, // Buffer of next frame to be written
  482. FLX_BUF* pbufPrev) // Buffer of previously written frame
  483. {
  484. // Verify open for writing, min 1 frame written and header not written yet
  485. if (m_bOpenForWrite && (m_sFrameNum >= 1) && (m_filehdr.sFlags != 3))
  486. return DoWriteFrame(pbufWrite, pbufPrev);
  487. else
  488. return 1;
  489. }
  490. ///////////////////////////////////////////////////////////////////////////////
  491. //
  492. // Finish writing the flic file. This must be called after the last frame was
  493. // written but before closing the file. The first and last frames are required
  494. // in order to generate the "ring" frame (used for looping the animation).
  495. // If you don't want a ring frame, simply specify NULL for both parameters.
  496. // The header is also updated with the final information for the file.
  497. // Returns 0 if successfull, non-zero otherwise.
  498. //
  499. ///////////////////////////////////////////////////////////////////////////////
  500. short CFlx::WriteFinish(
  501. FLX_BUF* pbufFirst, // Buffer of first frame that was written or NULL
  502. FLX_BUF* pbufLast) // Buffer of last frame that was written or NULL
  503. {
  504. short sError = 0;
  505. // Verify open for writing, min 1 frame written and header not written yet
  506. if (m_bOpenForWrite && (m_sFrameNum >= 1) && (m_filehdr.sFlags != 3))
  507. {
  508. // Write out the ring frame (delta between the last and the first frames)
  509. // unless the user doesn't want a ring frame!
  510. if ((pbufFirst != NULL) && (pbufLast != NULL))
  511. {
  512. sError = DoWriteFrame(pbufFirst, pbufLast);
  513. m_sFrameNum -= 1; // Ring frame doesn't count!
  514. }
  515. if (sError == 0)
  516. {
  517. // Update file header and write it out
  518. m_filehdr.lEntireFileSize = m_file.Tell(); // Set file size
  519. m_filehdr.sNumFrames = m_sFrameNum; // Set total frames
  520. m_filehdr.sFlags = 3; // 3 means header is valid
  521. sError = WriteHeader();
  522. }
  523. }
  524. else
  525. sError = 1;
  526. return sError;
  527. }
  528. ///////////////////////////////////////////////////////////////////////////////
  529. //
  530. // Create a FLX_BUF based on the specified width, height, and number of colors.
  531. // Returns 0 if successfull, non-zero otherwise.
  532. //
  533. ///////////////////////////////////////////////////////////////////////////////
  534. short CFlx::CreateBuf(FLX_BUF* pbuf, short sWidth, short sHeight, short sColors)
  535. {
  536. InitBuf(pbuf);
  537. return AllocBuf(pbuf, sWidth, sHeight, sColors);
  538. }
  539. ///////////////////////////////////////////////////////////////////////////////
  540. //
  541. // Destroy a FLX_BUF that was previously created using CreateBuf().
  542. // The FLX_BUF must not be used after this call!
  543. //
  544. ///////////////////////////////////////////////////////////////////////////////
  545. void CFlx::DestroyBuf(FLX_BUF* pbuf)
  546. {
  547. FreeBuf(pbuf);
  548. }
  549. ///////////////////////////////////////////////////////////////////////////////
  550. // EOF
  551. ///////////////////////////////////////////////////////////////////////////////