libmng_write.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* ************************************************************************** */
  2. /* * For conditions of distribution and use, * */
  3. /* * see copyright notice in libmng.h * */
  4. /* ************************************************************************** */
  5. /* * * */
  6. /* * project : libmng * */
  7. /* * file : libmng_write.c copyright (c) 2000-2004 G.Juyn * */
  8. /* * version : 1.0.9 * */
  9. /* * * */
  10. /* * purpose : Write management (implementation) * */
  11. /* * * */
  12. /* * author : G.Juyn * */
  13. /* * * */
  14. /* * comment : implementation of the write management routines * */
  15. /* * * */
  16. /* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
  17. /* * - changed strict-ANSI stuff * */
  18. /* * 0.5.1 - 05/12/2000 - G.Juyn * */
  19. /* * - changed trace to macro for callback error-reporting * */
  20. /* * 0.5.1 - 05/16/2000 - G.Juyn * */
  21. /* * - moved the actual write_graphic functionality from * */
  22. /* * mng_hlapi to its appropriate function here * */
  23. /* * * */
  24. /* * 0.9.1 - 07/19/2000 - G.Juyn * */
  25. /* * - fixed writing of signature * */
  26. /* * * */
  27. /* * 0.9.2 - 08/05/2000 - G.Juyn * */
  28. /* * - changed file-prefixes * */
  29. /* * * */
  30. /* * 1.0.5 - 08/19/2002 - G.Juyn * */
  31. /* * - B597134 - libmng pollutes the linker namespace * */
  32. /* * * */
  33. /* * 1.0.8 - 07/06/2004 - G.R-P * */
  34. /* * - added conditionals around openstream/closestream * */
  35. /* * - defend against using undefined Open/Closestream function * */
  36. /* * 1.0.8 - 08/02/2004 - G.Juyn * */
  37. /* * - added conditional to allow easier writing of large MNG's * */
  38. /* * * */
  39. /* * 1.0.9 - 09/25/2004 - G.Juyn * */
  40. /* * - replaced MNG_TWEAK_LARGE_FILES with permanent solution * */
  41. /* * 1.0.9 - 12/20/2004 - G.Juyn * */
  42. /* * - cleaned up macro-invocations (thanks to D. Airlie) * */
  43. /* * * */
  44. /* ************************************************************************** */
  45. #include "libmng.h"
  46. #include "libmng_data.h"
  47. #include "libmng_error.h"
  48. #include "libmng_trace.h"
  49. #ifdef __BORLANDC__
  50. #pragma hdrstop
  51. #endif
  52. #include "libmng_memory.h"
  53. #include "libmng_chunks.h"
  54. #include "libmng_chunk_io.h"
  55. #include "libmng_write.h"
  56. #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
  57. #pragma option -A /* force ANSI-C */
  58. #endif
  59. /* ************************************************************************** */
  60. #if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
  61. mng_retcode mng_drop_chunks (mng_datap pData)
  62. {
  63. mng_chunkp pChunk;
  64. mng_chunkp pNext;
  65. mng_cleanupchunk fCleanup;
  66. #ifdef MNG_SUPPORT_TRACE
  67. MNG_TRACE (pData, MNG_FN_DROP_CHUNKS, MNG_LC_START);
  68. #endif
  69. pChunk = pData->pFirstchunk; /* and get first stored chunk (if any) */
  70. while (pChunk) /* more chunks to discard ? */
  71. {
  72. pNext = ((mng_chunk_headerp)pChunk)->pNext;
  73. /* call appropriate cleanup */
  74. fCleanup = ((mng_chunk_headerp)pChunk)->fCleanup;
  75. fCleanup (pData, pChunk);
  76. pChunk = pNext; /* neeeext */
  77. }
  78. pData->pFirstchunk = MNG_NULL;
  79. pData->pLastchunk = MNG_NULL;
  80. #ifdef MNG_SUPPORT_TRACE
  81. MNG_TRACE (pData, MNG_FN_DROP_CHUNKS, MNG_LC_END);
  82. #endif
  83. return MNG_NOERROR;
  84. }
  85. #endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
  86. /* ************************************************************************** */
  87. #ifdef MNG_INCLUDE_WRITE_PROCS
  88. /* ************************************************************************** */
  89. mng_retcode mng_write_graphic (mng_datap pData)
  90. {
  91. mng_chunkp pChunk;
  92. mng_retcode iRetcode;
  93. mng_uint32 iWritten;
  94. #ifdef MNG_SUPPORT_TRACE
  95. MNG_TRACE (pData, MNG_FN_WRITE_GRAPHIC, MNG_LC_START);
  96. #endif
  97. pChunk = pData->pFirstchunk; /* we'll start with the first, thank you */
  98. if (pChunk) /* is there anything to write ? */
  99. { /* open the file */
  100. if (!pData->bWriting)
  101. {
  102. #ifndef MNG_NO_OPEN_CLOSE_STREAM
  103. if (pData->fOpenstream && !pData->fOpenstream ((mng_handle)pData))
  104. MNG_ERROR (pData, MNG_APPIOERROR);
  105. #endif
  106. {
  107. pData->bWriting = MNG_TRUE; /* indicate writing */
  108. pData->iWritebufsize = 32768; /* get a temporary write buffer */
  109. /* reserve 12 bytes for length, chunkname & crc */
  110. MNG_ALLOC (pData, pData->pWritebuf, pData->iWritebufsize+12);
  111. /* write the signature */
  112. if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_IHDR)
  113. mng_put_uint32 (pData->pWritebuf, PNG_SIG);
  114. else
  115. if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_JHDR)
  116. mng_put_uint32 (pData->pWritebuf, JNG_SIG);
  117. else
  118. mng_put_uint32 (pData->pWritebuf, MNG_SIG);
  119. mng_put_uint32 (pData->pWritebuf+4, POST_SIG);
  120. if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten))
  121. {
  122. MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12);
  123. MNG_ERROR (pData, MNG_APPIOERROR);
  124. }
  125. if (iWritten != 8) /* disk full ? */
  126. {
  127. MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12);
  128. MNG_ERROR (pData, MNG_OUTPUTERROR);
  129. }
  130. }
  131. }
  132. while (pChunk) /* so long as there's something to write */
  133. { /* let's call its output routine */
  134. iRetcode = ((mng_chunk_headerp)pChunk)->fWrite (pData, pChunk);
  135. if (iRetcode) /* on error bail out */
  136. return iRetcode;
  137. /* neeeext */
  138. pChunk = ((mng_chunk_headerp)pChunk)->pNext;
  139. }
  140. if (!pData->bCreating)
  141. { /* free the temporary buffer */
  142. MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12);
  143. pData->bWriting = MNG_FALSE; /* done writing */
  144. /* close the stream now */
  145. #ifndef MNG_NO_OPEN_CLOSE_STREAM
  146. if (pData->fClosestream && !pData->fClosestream ((mng_handle)pData))
  147. MNG_ERROR (pData, MNG_APPIOERROR);
  148. #endif
  149. } else {
  150. /* cleanup the written chunks */
  151. iRetcode = mng_drop_chunks (pData);
  152. if (iRetcode) /* on error bail out */
  153. return iRetcode;
  154. }
  155. }
  156. #ifdef MNG_SUPPORT_TRACE
  157. MNG_TRACE (pData, MNG_FN_WRITE_GRAPHIC, MNG_LC_END);
  158. #endif
  159. return MNG_NOERROR;
  160. }
  161. /* ************************************************************************** */
  162. #endif /* MNG_INCLUDE_WRITE_PROCS */
  163. /* ************************************************************************** */
  164. /* * end of file * */
  165. /* ************************************************************************** */