gosu 0.7.10.3 → 0.7.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (545) hide show
  1. data/Gosu/AutoLink.hpp +0 -0
  2. data/Gosu/ButtonsMac.hpp +26 -0
  3. data/Gosu/ButtonsWin.hpp +26 -0
  4. data/Gosu/ButtonsX.hpp +26 -0
  5. data/Gosu/Gosu.hpp +1 -0
  6. data/Gosu/Graphics.hpp +1 -1
  7. data/Gosu/Input.hpp +4 -5
  8. data/Gosu/Math.hpp +11 -0
  9. data/Gosu/Text.hpp +59 -47
  10. data/Gosu/Utility.hpp +6 -5
  11. data/GosuImpl/Graphics/DrawOp.hpp +0 -0
  12. data/GosuImpl/Graphics/Font.cpp +45 -4
  13. data/GosuImpl/Graphics/Graphics.cpp +25 -0
  14. data/GosuImpl/Graphics/TexChunk.cpp +0 -0
  15. data/GosuImpl/Graphics/TexChunk.hpp +0 -0
  16. data/GosuImpl/Graphics/Text.cpp +26 -2
  17. data/GosuImpl/Graphics/TextMac.cpp +8 -2
  18. data/GosuImpl/Graphics/TextPangoFT.cpp +0 -0
  19. data/GosuImpl/Graphics/Texture.cpp +0 -0
  20. data/GosuImpl/Graphics/Texture.hpp +0 -0
  21. data/GosuImpl/Iconv.hpp +62 -0
  22. data/GosuImpl/InputMac.mm +3 -0
  23. data/GosuImpl/InputWin.cpp +5 -1
  24. data/GosuImpl/InputX.cpp +50 -8
  25. data/GosuImpl/Math.cpp +1 -1
  26. data/GosuImpl/RubyGosu.swg +24 -5
  27. data/GosuImpl/RubyGosu_wrap.cxx +181 -10
  28. data/GosuImpl/Utility.cpp +32 -75
  29. data/GosuImpl/Utility.cpp~RF6c566.TMP +95 -0
  30. data/GosuImpl/WindowX.cpp +2 -2
  31. data/Rakefile +57 -10
  32. data/examples/Tutorial.cpp +0 -0
  33. data/examples/media/Beep.wav +0 -0
  34. data/examples/media/CptnRuby Map.txt b/data/examples/media/CptnRuby → Map.txt +0 -0
  35. data/examples/media/Explosion.wav +0 -0
  36. data/examples/media/Space.png +0 -0
  37. data/examples/media/Star.png +0 -0
  38. data/examples/media/Starfighter.bmp +0 -0
  39. data/linux/Makefile.in +0 -0
  40. data/linux/configure +0 -0
  41. data/linux/configure.ac +0 -0
  42. data/mac/Gosu.xcodeproj/jlnr.mode1v3 +1421 -0
  43. data/mac/Gosu.xcodeproj/jlnr.mode2v3 +1464 -0
  44. data/mac/Gosu.xcodeproj/jlnr.pbxuser +733 -0
  45. data/mac/Gosu.xcodeproj/project.pbxproj +4 -2
  46. data/reference/Async_8hpp-source.html +1 -1
  47. data/reference/Audio_8hpp-source.html +1 -1
  48. data/reference/Audio_8hpp.html +1 -1
  49. data/reference/AutoLink_8hpp-source.html +1 -1
  50. data/reference/AutoLink_8hpp.html +1 -1
  51. data/reference/Bitmap_8hpp-source.html +1 -1
  52. data/reference/Bitmap_8hpp.html +1 -1
  53. data/reference/ButtonsMac_8hpp-source.html +107 -81
  54. data/reference/ButtonsWin_8hpp-source.html +84 -58
  55. data/reference/ButtonsX_8hpp-source.html +131 -105
  56. data/reference/Color_8hpp-source.html +1 -1
  57. data/reference/Color_8hpp.html +1 -1
  58. data/reference/Directories_8hpp-source.html +1 -1
  59. data/reference/Directories_8hpp.html +1 -1
  60. data/reference/Font_8hpp-source.html +1 -1
  61. data/reference/Font_8hpp.html +1 -1
  62. data/reference/Fwd_8hpp-source.html +1 -1
  63. data/reference/Fwd_8hpp.html +1 -1
  64. data/reference/Gosu_8hpp-source.html +5 -4
  65. data/reference/Gosu_8hpp.html +1 -1
  66. data/reference/GraphicsBase_8hpp-source.html +1 -1
  67. data/reference/GraphicsBase_8hpp.html +1 -1
  68. data/reference/Graphics_8hpp-source.html +2 -2
  69. data/reference/Graphics_8hpp.html +1 -1
  70. data/reference/IO_8hpp-source.html +1 -1
  71. data/reference/IO_8hpp.html +1 -1
  72. data/reference/ImageData_8hpp-source.html +1 -1
  73. data/reference/ImageData_8hpp.html +1 -1
  74. data/reference/Image_8hpp-source.html +1 -1
  75. data/reference/Image_8hpp.html +1 -1
  76. data/reference/Input_8hpp-source.html +43 -43
  77. data/reference/Input_8hpp.html +2 -2
  78. data/reference/Math_8hpp-source.html +51 -42
  79. data/reference/Math_8hpp.html +5 -1
  80. data/reference/Platform_8hpp-source.html +1 -1
  81. data/reference/Platform_8hpp.html +1 -1
  82. data/reference/RotFlip_8hpp-source.html +1 -1
  83. data/reference/RotFlip_8hpp.html +1 -1
  84. data/reference/Sockets_8hpp-source.html +1 -1
  85. data/reference/Sockets_8hpp.html +1 -1
  86. data/reference/TextInput_8hpp-source.html +1 -1
  87. data/reference/TextInput_8hpp.html +1 -1
  88. data/reference/Text_8hpp-source.html +12 -8
  89. data/reference/Text_8hpp.html +3 -1
  90. data/reference/Timing_8hpp-source.html +1 -1
  91. data/reference/Timing_8hpp.html +1 -1
  92. data/reference/Utility_8hpp-source.html +9 -10
  93. data/reference/Utility_8hpp.html +5 -7
  94. data/reference/WinUtility_8hpp-source.html +1 -1
  95. data/reference/WinUtility_8hpp.html +1 -1
  96. data/reference/Window_8hpp-source.html +3 -3
  97. data/reference/Window_8hpp.html +1 -1
  98. data/reference/annotated.html +2 -2
  99. data/reference/classGosu_1_1Audio-members.html +1 -1
  100. data/reference/classGosu_1_1Audio.html +1 -1
  101. data/reference/classGosu_1_1Bitmap-members.html +1 -1
  102. data/reference/classGosu_1_1Bitmap.html +1 -1
  103. data/reference/classGosu_1_1Buffer-members.html +1 -1
  104. data/reference/classGosu_1_1Buffer.html +1 -1
  105. data/reference/classGosu_1_1Button-members.html +1 -1
  106. data/reference/classGosu_1_1Button.html +1 -1
  107. data/reference/classGosu_1_1Color-members.html +1 -1
  108. data/reference/classGosu_1_1Color.html +1 -1
  109. data/reference/classGosu_1_1File-members.html +1 -1
  110. data/reference/classGosu_1_1File.html +1 -1
  111. data/reference/classGosu_1_1Font-members.html +1 -1
  112. data/reference/classGosu_1_1Font.html +1 -1
  113. data/reference/classGosu_1_1Graphics-members.html +1 -1
  114. data/reference/classGosu_1_1Graphics.html +1 -1
  115. data/reference/classGosu_1_1Image-members.html +1 -1
  116. data/reference/classGosu_1_1Image.html +1 -1
  117. data/reference/classGosu_1_1ImageData-members.html +1 -1
  118. data/reference/classGosu_1_1ImageData.html +1 -1
  119. data/reference/classGosu_1_1Input-members.html +1 -1
  120. data/reference/classGosu_1_1Input.html +4 -4
  121. data/reference/classGosu_1_1MessageSocket-members.html +1 -1
  122. data/reference/classGosu_1_1MessageSocket.html +1 -1
  123. data/reference/classGosu_1_1Resource-members.html +1 -1
  124. data/reference/classGosu_1_1Resource.html +1 -1
  125. data/reference/classGosu_1_1Sample-members.html +1 -1
  126. data/reference/classGosu_1_1Sample.html +1 -1
  127. data/reference/classGosu_1_1SampleInstance-members.html +1 -1
  128. data/reference/classGosu_1_1SampleInstance.html +1 -1
  129. data/reference/classGosu_1_1Song-members.html +1 -1
  130. data/reference/classGosu_1_1Song.html +1 -1
  131. data/reference/classGosu_1_1TextInput-members.html +1 -1
  132. data/reference/classGosu_1_1TextInput.html +1 -1
  133. data/reference/classGosu_1_1Window-members.html +1 -1
  134. data/reference/classGosu_1_1Window.html +1 -1
  135. data/reference/files.html +1 -1
  136. data/reference/functions.html +1 -1
  137. data/reference/functions_enum.html +1 -1
  138. data/reference/functions_func.html +1 -1
  139. data/reference/functions_vars.html +1 -1
  140. data/reference/hierarchy.html +1 -1
  141. data/reference/index.html +1 -1
  142. data/reference/namespaceGosu.html +935 -492
  143. data/reference/namespaceGosu_1_1Colors.html +1 -1
  144. data/reference/namespaceGosu_1_1Win.html +1 -1
  145. data/reference/namespacemembers.html +13 -2
  146. data/reference/namespacemembers_enum.html +1 -1
  147. data/reference/namespacemembers_eval.html +1 -1
  148. data/reference/namespacemembers_func.html +13 -2
  149. data/reference/namespacemembers_type.html +1 -1
  150. data/reference/namespacemembers_vars.html +1 -1
  151. data/reference/namespaces.html +1 -1
  152. data/windows/Gosu.vcproj +4 -4
  153. data/windows/RubyGosu.vcproj +2 -1
  154. data/windows/zlib, libpng/libpng/ANNOUNCE +61 -0
  155. data/windows/zlib, libpng/libpng/CHANGES +2173 -0
  156. data/windows/zlib, libpng/libpng/INSTALL +199 -0
  157. data/windows/zlib, libpng/libpng/KNOWNBUG +22 -0
  158. data/windows/zlib, libpng/libpng/LICENSE +109 -0
  159. data/windows/zlib, libpng/libpng/README +264 -0
  160. data/windows/zlib, libpng/libpng/TODO +24 -0
  161. data/windows/zlib, libpng/libpng/Y2KINFO +55 -0
  162. data/windows/zlib, libpng/libpng/configure +13 -0
  163. data/windows/zlib, libpng/libpng/contrib/gregbook/COPYING +340 -0
  164. data/windows/zlib, libpng/libpng/contrib/gregbook/LICENSE +50 -0
  165. data/windows/zlib, libpng/libpng/contrib/gregbook/Makefile.mingw32 +130 -0
  166. data/windows/zlib, libpng/libpng/contrib/gregbook/Makefile.sgi +104 -0
  167. data/windows/zlib, libpng/libpng/contrib/gregbook/Makefile.unx +132 -0
  168. data/windows/zlib, libpng/libpng/contrib/gregbook/Makefile.w32 +113 -0
  169. data/windows/zlib, libpng/libpng/contrib/gregbook/README +186 -0
  170. data/windows/zlib, libpng/libpng/contrib/gregbook/makevms.com +132 -0
  171. data/windows/zlib, libpng/libpng/contrib/gregbook/readpng.c +304 -0
  172. data/windows/zlib, libpng/libpng/contrib/gregbook/readpng.h +88 -0
  173. data/windows/zlib, libpng/libpng/contrib/gregbook/readpng2.c +645 -0
  174. data/windows/zlib, libpng/libpng/contrib/gregbook/readpng2.h +121 -0
  175. data/windows/zlib, libpng/libpng/contrib/gregbook/readppm.c +179 -0
  176. data/windows/zlib, libpng/libpng/contrib/gregbook/rpng-win.c +684 -0
  177. data/windows/zlib, libpng/libpng/contrib/gregbook/rpng-x.c +904 -0
  178. data/windows/zlib, libpng/libpng/contrib/gregbook/rpng2-win.c +1225 -0
  179. data/windows/zlib, libpng/libpng/contrib/gregbook/rpng2-x.c +2127 -0
  180. data/windows/zlib, libpng/libpng/contrib/gregbook/toucan.png +0 -0
  181. data/windows/zlib, libpng/libpng/contrib/gregbook/wpng.c +853 -0
  182. data/windows/zlib, libpng/libpng/contrib/gregbook/writepng.c +392 -0
  183. data/windows/zlib, libpng/libpng/contrib/gregbook/writepng.h +133 -0
  184. data/windows/zlib, libpng/libpng/contrib/pngminim/decoder/README +6 -0
  185. data/windows/zlib, libpng/libpng/contrib/pngminim/decoder/gather.sh +8 -0
  186. data/windows/zlib, libpng/libpng/contrib/pngminim/decoder/makefile.std +44 -0
  187. data/windows/zlib, libpng/libpng/contrib/pngminim/decoder/pngusr.h +67 -0
  188. data/windows/zlib, libpng/libpng/contrib/pngminim/encoder/README +6 -0
  189. data/windows/zlib, libpng/libpng/contrib/pngminim/encoder/dummy_inflate.c +27 -0
  190. data/windows/zlib, libpng/libpng/contrib/pngminim/encoder/gather.sh +9 -0
  191. data/windows/zlib, libpng/libpng/contrib/pngminim/encoder/makefile.std +43 -0
  192. data/windows/zlib, libpng/libpng/contrib/pngminim/encoder/pngusr.h +66 -0
  193. data/windows/zlib, libpng/libpng/contrib/pngminus/README +153 -0
  194. data/windows/zlib, libpng/libpng/contrib/pngminus/makefile.std +65 -0
  195. data/windows/zlib, libpng/libpng/contrib/pngminus/makefile.tc3 +38 -0
  196. data/windows/zlib, libpng/libpng/contrib/pngminus/makevms.com +92 -0
  197. data/windows/zlib, libpng/libpng/contrib/pngminus/png2pnm.bat +41 -0
  198. data/windows/zlib, libpng/libpng/contrib/pngminus/png2pnm.c +430 -0
  199. data/windows/zlib, libpng/libpng/contrib/pngminus/png2pnm.sh +42 -0
  200. data/windows/zlib, libpng/libpng/contrib/pngminus/pngminus.bat +4 -0
  201. data/windows/zlib, libpng/libpng/contrib/pngminus/pngminus.sh +5 -0
  202. data/windows/zlib, libpng/libpng/contrib/pngminus/pnm2png.bat +41 -0
  203. data/windows/zlib, libpng/libpng/contrib/pngminus/pnm2png.c +533 -0
  204. data/windows/zlib, libpng/libpng/contrib/pngminus/pnm2png.sh +42 -0
  205. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn0g01.png +0 -0
  206. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn0g02.png +0 -0
  207. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn0g04.png +0 -0
  208. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn0g08.png +0 -0
  209. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn0g16.png +0 -0
  210. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn2c08.png +0 -0
  211. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn2c16.png +0 -0
  212. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn3p01.png +0 -0
  213. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn3p02.png +0 -0
  214. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn3p04.png +0 -0
  215. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn3p08.png +0 -0
  216. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn4a08.png +0 -0
  217. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn4a16.png +0 -0
  218. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn6a08.png +0 -0
  219. data/windows/zlib, libpng/libpng/contrib/pngsuite/basn6a16.png +0 -0
  220. data/windows/zlib, libpng/libpng/contrib/visupng/PngFile.c +439 -0
  221. data/windows/zlib, libpng/libpng/contrib/visupng/PngFile.h +27 -0
  222. data/windows/zlib, libpng/libpng/contrib/visupng/README.txt +58 -0
  223. data/windows/zlib, libpng/libpng/contrib/visupng/VisualPng.c +961 -0
  224. data/windows/zlib, libpng/libpng/contrib/visupng/VisualPng.dsp +147 -0
  225. data/windows/zlib, libpng/libpng/contrib/visupng/VisualPng.dsw +29 -0
  226. data/windows/zlib, libpng/libpng/contrib/visupng/VisualPng.ico +0 -0
  227. data/windows/zlib, libpng/libpng/contrib/visupng/VisualPng.png +0 -0
  228. data/windows/zlib, libpng/libpng/contrib/visupng/VisualPng.rc +152 -0
  229. data/windows/zlib, libpng/libpng/contrib/visupng/cexcept.h +243 -0
  230. data/windows/zlib, libpng/libpng/contrib/visupng/resource.h +23 -0
  231. data/windows/zlib, libpng/libpng/example.c +814 -0
  232. data/windows/zlib, libpng/libpng/libpng-1.2.29.txt +2906 -0
  233. data/windows/zlib, libpng/libpng/libpng.3 +3680 -0
  234. data/windows/zlib, libpng/libpng/libpngpf.3 +274 -0
  235. data/windows/zlib, libpng/libpng/png.5 +74 -0
  236. data/windows/zlib, libpng/libpng/png.c +798 -0
  237. data/windows/zlib, libpng/libpng/png.h +3569 -0
  238. data/windows/zlib, libpng/libpng/pngbar.jpg +0 -0
  239. data/windows/zlib, libpng/libpng/pngbar.png +0 -0
  240. data/windows/zlib, libpng/libpng/pngconf.h +1481 -0
  241. data/windows/zlib, libpng/libpng/pngerror.c +343 -0
  242. data/windows/zlib, libpng/libpng/pnggccrd.c +103 -0
  243. data/windows/zlib, libpng/libpng/pngget.c +901 -0
  244. data/windows/zlib, libpng/libpng/pngmem.c +608 -0
  245. data/windows/zlib, libpng/libpng/pngnow.png +0 -0
  246. data/windows/zlib, libpng/libpng/pngpread.c +1598 -0
  247. data/windows/zlib, libpng/libpng/pngread.c +1479 -0
  248. data/windows/zlib, libpng/libpng/pngrio.c +167 -0
  249. data/windows/zlib, libpng/libpng/pngrtran.c +4292 -0
  250. data/windows/zlib, libpng/libpng/pngrutil.c +3183 -0
  251. data/windows/zlib, libpng/libpng/pngset.c +1268 -0
  252. data/windows/zlib, libpng/libpng/pngtest.c +1563 -0
  253. data/windows/zlib, libpng/libpng/pngtest.png +0 -0
  254. data/windows/zlib, libpng/libpng/pngtrans.c +662 -0
  255. data/windows/zlib, libpng/libpng/pngvcrd.c +1 -0
  256. data/windows/zlib, libpng/libpng/pngwio.c +234 -0
  257. data/windows/zlib, libpng/libpng/pngwrite.c +1532 -0
  258. data/windows/zlib, libpng/libpng/pngwtran.c +572 -0
  259. data/windows/zlib, libpng/libpng/pngwutil.c +2802 -0
  260. data/windows/zlib, libpng/libpng/projects/beos/x86-shared.proj +0 -0
  261. data/windows/zlib, libpng/libpng/projects/beos/x86-shared.txt +22 -0
  262. data/windows/zlib, libpng/libpng/projects/beos/x86-static.proj +0 -0
  263. data/windows/zlib, libpng/libpng/projects/beos/x86-static.txt +22 -0
  264. data/windows/zlib, libpng/libpng/projects/cbuilder5/libpng.bpf +22 -0
  265. data/windows/zlib, libpng/libpng/projects/cbuilder5/libpng.bpg +25 -0
  266. data/windows/zlib, libpng/libpng/projects/cbuilder5/libpng.bpr +157 -0
  267. data/windows/zlib, libpng/libpng/projects/cbuilder5/libpng.cpp +29 -0
  268. data/windows/zlib, libpng/libpng/projects/cbuilder5/libpng.readme.txt +25 -0
  269. data/windows/zlib, libpng/libpng/projects/cbuilder5/libpngstat.bpf +22 -0
  270. data/windows/zlib, libpng/libpng/projects/cbuilder5/libpngstat.bpr +109 -0
  271. data/windows/zlib, libpng/libpng/projects/cbuilder5/zlib.readme.txt +14 -0
  272. data/windows/zlib, libpng/libpng/projects/netware.txt +6 -0
  273. data/windows/zlib, libpng/libpng/projects/visualc6/README.txt +57 -0
  274. data/windows/zlib, libpng/libpng/projects/visualc6/libpng.dsp +472 -0
  275. data/windows/zlib, libpng/libpng/projects/visualc6/libpng.dsw +59 -0
  276. data/windows/zlib, libpng/libpng/projects/visualc6/pngtest.dsp +314 -0
  277. data/windows/zlib, libpng/libpng/projects/visualc71/PRJ0041.mak +21 -0
  278. data/windows/zlib, libpng/libpng/projects/visualc71/README.txt +57 -0
  279. data/windows/zlib, libpng/libpng/projects/visualc71/README_zlib.txt +44 -0
  280. data/windows/zlib, libpng/libpng/projects/visualc71/libpng.sln +88 -0
  281. data/windows/zlib, libpng/libpng/projects/visualc71/libpng.vcproj +702 -0
  282. data/windows/zlib, libpng/libpng/projects/visualc71/pngtest.vcproj +459 -0
  283. data/windows/zlib, libpng/libpng/projects/visualc71/zlib.vcproj +670 -0
  284. data/windows/zlib, libpng/libpng/projects/wince.txt +6 -0
  285. data/windows/zlib, libpng/libpng/scripts/CMakeLists.txt +210 -0
  286. data/windows/zlib, libpng/libpng/scripts/SCOPTIONS.ppc +7 -0
  287. data/windows/zlib, libpng/libpng/scripts/descrip.mms +52 -0
  288. data/windows/zlib, libpng/libpng/scripts/libpng-config-body.in +96 -0
  289. data/windows/zlib, libpng/libpng/scripts/libpng-config-head.in +21 -0
  290. data/windows/zlib, libpng/libpng/scripts/libpng-config.in +124 -0
  291. data/windows/zlib, libpng/libpng/scripts/libpng.icc +44 -0
  292. data/windows/zlib, libpng/libpng/scripts/libpng.pc-configure.in +10 -0
  293. data/windows/zlib, libpng/libpng/scripts/libpng.pc.in +10 -0
  294. data/windows/zlib, libpng/libpng/scripts/makefile.32sunu +254 -0
  295. data/windows/zlib, libpng/libpng/scripts/makefile.64sunu +254 -0
  296. data/windows/zlib, libpng/libpng/scripts/makefile.acorn +51 -0
  297. data/windows/zlib, libpng/libpng/scripts/makefile.aix +113 -0
  298. data/windows/zlib, libpng/libpng/scripts/makefile.amiga +48 -0
  299. data/windows/zlib, libpng/libpng/scripts/makefile.atari +51 -0
  300. data/windows/zlib, libpng/libpng/scripts/makefile.bc32 +152 -0
  301. data/windows/zlib, libpng/libpng/scripts/makefile.beos +226 -0
  302. data/windows/zlib, libpng/libpng/scripts/makefile.bor +162 -0
  303. data/windows/zlib, libpng/libpng/scripts/makefile.cygwin +299 -0
  304. data/windows/zlib, libpng/libpng/scripts/makefile.darwin +234 -0
  305. data/windows/zlib, libpng/libpng/scripts/makefile.dec +214 -0
  306. data/windows/zlib, libpng/libpng/scripts/makefile.dj2 +55 -0
  307. data/windows/zlib, libpng/libpng/scripts/makefile.elf +275 -0
  308. data/windows/zlib, libpng/libpng/scripts/makefile.freebsd +48 -0
  309. data/windows/zlib, libpng/libpng/scripts/makefile.gcc +79 -0
  310. data/windows/zlib, libpng/libpng/scripts/makefile.gcmmx +271 -0
  311. data/windows/zlib, libpng/libpng/scripts/makefile.hp64 +235 -0
  312. data/windows/zlib, libpng/libpng/scripts/makefile.hpgcc +245 -0
  313. data/windows/zlib, libpng/libpng/scripts/makefile.hpux +232 -0
  314. data/windows/zlib, libpng/libpng/scripts/makefile.ibmc +71 -0
  315. data/windows/zlib, libpng/libpng/scripts/makefile.intel +102 -0
  316. data/windows/zlib, libpng/libpng/scripts/makefile.knr +99 -0
  317. data/windows/zlib, libpng/libpng/scripts/makefile.linux +249 -0
  318. data/windows/zlib, libpng/libpng/scripts/makefile.mingw +289 -0
  319. data/windows/zlib, libpng/libpng/scripts/makefile.mips +83 -0
  320. data/windows/zlib, libpng/libpng/scripts/makefile.msc +86 -0
  321. data/windows/zlib, libpng/libpng/scripts/makefile.ne12bsd +45 -0
  322. data/windows/zlib, libpng/libpng/scripts/makefile.netbsd +45 -0
  323. data/windows/zlib, libpng/libpng/scripts/makefile.nommx +252 -0
  324. data/windows/zlib, libpng/libpng/scripts/makefile.openbsd +73 -0
  325. data/windows/zlib, libpng/libpng/scripts/makefile.os2 +69 -0
  326. data/windows/zlib, libpng/libpng/scripts/makefile.sco +229 -0
  327. data/windows/zlib, libpng/libpng/scripts/makefile.sggcc +242 -0
  328. data/windows/zlib, libpng/libpng/scripts/makefile.sgi +245 -0
  329. data/windows/zlib, libpng/libpng/scripts/makefile.so9 +251 -0
  330. data/windows/zlib, libpng/libpng/scripts/makefile.solaris +249 -0
  331. data/windows/zlib, libpng/libpng/scripts/makefile.solaris-x86 +248 -0
  332. data/windows/zlib, libpng/libpng/scripts/makefile.std +92 -0
  333. data/windows/zlib, libpng/libpng/scripts/makefile.sunos +97 -0
  334. data/windows/zlib, libpng/libpng/scripts/makefile.tc3 +89 -0
  335. data/windows/zlib, libpng/libpng/scripts/makefile.vcawin32 +99 -0
  336. data/windows/zlib, libpng/libpng/scripts/makefile.vcwin32 +99 -0
  337. data/windows/zlib, libpng/libpng/scripts/makefile.watcom +109 -0
  338. data/windows/zlib, libpng/libpng/scripts/makevms.com +144 -0
  339. data/windows/zlib, libpng/libpng/scripts/pngos2.def +257 -0
  340. data/windows/zlib, libpng/libpng/scripts/pngw32.def +238 -0
  341. data/windows/zlib, libpng/libpng/scripts/pngw32.rc +112 -0
  342. data/windows/zlib, libpng/libpng/scripts/smakefile.ppc +30 -0
  343. data/windows/zlib, libpng/zlib/ChangeLog +855 -0
  344. data/windows/zlib, libpng/zlib/FAQ +339 -0
  345. data/windows/zlib, libpng/zlib/INDEX +51 -0
  346. data/windows/zlib, libpng/zlib/Makefile +154 -0
  347. data/windows/zlib, libpng/zlib/Makefile.in +154 -0
  348. data/windows/zlib, libpng/zlib/README +125 -0
  349. data/windows/zlib, libpng/zlib/adler32.c +149 -0
  350. data/windows/zlib, libpng/zlib/algorithm.txt +209 -0
  351. data/windows/zlib, libpng/zlib/amiga/Makefile.pup +66 -0
  352. data/windows/zlib, libpng/zlib/amiga/Makefile.sas +65 -0
  353. data/windows/zlib, libpng/zlib/as400/bndsrc +132 -0
  354. data/windows/zlib, libpng/zlib/as400/compile.clp +123 -0
  355. data/windows/zlib, libpng/zlib/as400/readme.txt +111 -0
  356. data/windows/zlib, libpng/zlib/as400/zlib.inc +331 -0
  357. data/windows/zlib, libpng/zlib/compress.c +79 -0
  358. data/windows/zlib, libpng/zlib/configure +459 -0
  359. data/windows/zlib, libpng/zlib/contrib/README.contrib +71 -0
  360. data/windows/zlib, libpng/zlib/contrib/ada/buffer_demo.adb +106 -0
  361. data/windows/zlib, libpng/zlib/contrib/ada/mtest.adb +156 -0
  362. data/windows/zlib, libpng/zlib/contrib/ada/read.adb +156 -0
  363. data/windows/zlib, libpng/zlib/contrib/ada/readme.txt +65 -0
  364. data/windows/zlib, libpng/zlib/contrib/ada/test.adb +463 -0
  365. data/windows/zlib, libpng/zlib/contrib/ada/zlib-streams.adb +225 -0
  366. data/windows/zlib, libpng/zlib/contrib/ada/zlib-streams.ads +114 -0
  367. data/windows/zlib, libpng/zlib/contrib/ada/zlib-thin.adb +141 -0
  368. data/windows/zlib, libpng/zlib/contrib/ada/zlib-thin.ads +450 -0
  369. data/windows/zlib, libpng/zlib/contrib/ada/zlib.adb +701 -0
  370. data/windows/zlib, libpng/zlib/contrib/ada/zlib.ads +328 -0
  371. data/windows/zlib, libpng/zlib/contrib/ada/zlib.gpr +20 -0
  372. data/windows/zlib, libpng/zlib/contrib/asm586/README.586 +43 -0
  373. data/windows/zlib, libpng/zlib/contrib/asm586/match.S +364 -0
  374. data/windows/zlib, libpng/zlib/contrib/asm686/README.686 +34 -0
  375. data/windows/zlib, libpng/zlib/contrib/asm686/match.S +329 -0
  376. data/windows/zlib, libpng/zlib/contrib/blast/Makefile +8 -0
  377. data/windows/zlib, libpng/zlib/contrib/blast/README +4 -0
  378. data/windows/zlib, libpng/zlib/contrib/blast/blast.c +444 -0
  379. data/windows/zlib, libpng/zlib/contrib/blast/blast.h +71 -0
  380. data/windows/zlib, libpng/zlib/contrib/blast/test.pk +0 -0
  381. data/windows/zlib, libpng/zlib/contrib/blast/test.txt +1 -0
  382. data/windows/zlib, libpng/zlib/contrib/delphi/ZLib.pas +557 -0
  383. data/windows/zlib, libpng/zlib/contrib/delphi/ZLibConst.pas +11 -0
  384. data/windows/zlib, libpng/zlib/contrib/delphi/readme.txt +76 -0
  385. data/windows/zlib, libpng/zlib/contrib/delphi/zlibd32.mak +93 -0
  386. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib.build +33 -0
  387. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib.chm +0 -0
  388. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib.sln +21 -0
  389. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs +58 -0
  390. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs +202 -0
  391. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs +83 -0
  392. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/CodecBase.cs +198 -0
  393. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/Deflater.cs +106 -0
  394. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/DotZLib.cs +288 -0
  395. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj +141 -0
  396. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/GZipStream.cs +301 -0
  397. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/Inflater.cs +105 -0
  398. data/windows/zlib, libpng/zlib/contrib/dotzlib/DotZLib/UnitTests.cs +274 -0
  399. data/windows/zlib, libpng/zlib/contrib/dotzlib/LICENSE_1_0.txt +23 -0
  400. data/windows/zlib, libpng/zlib/contrib/dotzlib/readme.txt +58 -0
  401. data/windows/zlib, libpng/zlib/contrib/infback9/README +1 -0
  402. data/windows/zlib, libpng/zlib/contrib/infback9/infback9.c +608 -0
  403. data/windows/zlib, libpng/zlib/contrib/infback9/infback9.h +37 -0
  404. data/windows/zlib, libpng/zlib/contrib/infback9/inffix9.h +107 -0
  405. data/windows/zlib, libpng/zlib/contrib/infback9/inflate9.h +47 -0
  406. data/windows/zlib, libpng/zlib/contrib/infback9/inftree9.c +323 -0
  407. data/windows/zlib, libpng/zlib/contrib/infback9/inftree9.h +55 -0
  408. data/windows/zlib, libpng/zlib/contrib/inflate86/inffas86.c +1157 -0
  409. data/windows/zlib, libpng/zlib/contrib/inflate86/inffast.S +1368 -0
  410. data/windows/zlib, libpng/zlib/contrib/iostream/test.cpp +24 -0
  411. data/windows/zlib, libpng/zlib/contrib/iostream/zfstream.cpp +329 -0
  412. data/windows/zlib, libpng/zlib/contrib/iostream/zfstream.h +128 -0
  413. data/windows/zlib, libpng/zlib/contrib/iostream2/zstream.h +307 -0
  414. data/windows/zlib, libpng/zlib/contrib/iostream2/zstream_test.cpp +25 -0
  415. data/windows/zlib, libpng/zlib/contrib/iostream3/README +35 -0
  416. data/windows/zlib, libpng/zlib/contrib/iostream3/TODO +17 -0
  417. data/windows/zlib, libpng/zlib/contrib/iostream3/test.cc +50 -0
  418. data/windows/zlib, libpng/zlib/contrib/iostream3/zfstream.cc +479 -0
  419. data/windows/zlib, libpng/zlib/contrib/iostream3/zfstream.h +466 -0
  420. data/windows/zlib, libpng/zlib/contrib/masm686/match.asm +413 -0
  421. data/windows/zlib, libpng/zlib/contrib/masmx64/bld_ml64.bat +2 -0
  422. data/windows/zlib, libpng/zlib/contrib/masmx64/gvmat64.asm +513 -0
  423. data/windows/zlib, libpng/zlib/contrib/masmx64/gvmat64.obj +0 -0
  424. data/windows/zlib, libpng/zlib/contrib/masmx64/inffas8664.c +186 -0
  425. data/windows/zlib, libpng/zlib/contrib/masmx64/inffasx64.asm +392 -0
  426. data/windows/zlib, libpng/zlib/contrib/masmx64/inffasx64.obj +0 -0
  427. data/windows/zlib, libpng/zlib/contrib/masmx64/readme.txt +28 -0
  428. data/windows/zlib, libpng/zlib/contrib/masmx86/bld_ml32.bat +2 -0
  429. data/windows/zlib, libpng/zlib/contrib/masmx86/gvmat32.asm +972 -0
  430. data/windows/zlib, libpng/zlib/contrib/masmx86/gvmat32.obj +0 -0
  431. data/windows/zlib, libpng/zlib/contrib/masmx86/gvmat32c.c +62 -0
  432. data/windows/zlib, libpng/zlib/contrib/masmx86/inffas32.asm +1083 -0
  433. data/windows/zlib, libpng/zlib/contrib/masmx86/inffas32.obj +0 -0
  434. data/windows/zlib, libpng/zlib/contrib/masmx86/mkasm.bat +3 -0
  435. data/windows/zlib, libpng/zlib/contrib/masmx86/readme.txt +21 -0
  436. data/windows/zlib, libpng/zlib/contrib/minizip/ChangeLogUnzip +67 -0
  437. data/windows/zlib, libpng/zlib/contrib/minizip/Makefile +25 -0
  438. data/windows/zlib, libpng/zlib/contrib/minizip/crypt.h +132 -0
  439. data/windows/zlib, libpng/zlib/contrib/minizip/ioapi.c +177 -0
  440. data/windows/zlib, libpng/zlib/contrib/minizip/ioapi.h +75 -0
  441. data/windows/zlib, libpng/zlib/contrib/minizip/iowin32.c +270 -0
  442. data/windows/zlib, libpng/zlib/contrib/minizip/iowin32.h +21 -0
  443. data/windows/zlib, libpng/zlib/contrib/minizip/miniunz.c +585 -0
  444. data/windows/zlib, libpng/zlib/contrib/minizip/minizip.c +420 -0
  445. data/windows/zlib, libpng/zlib/contrib/minizip/mztools.c +281 -0
  446. data/windows/zlib, libpng/zlib/contrib/minizip/mztools.h +31 -0
  447. data/windows/zlib, libpng/zlib/contrib/minizip/unzip.c +1598 -0
  448. data/windows/zlib, libpng/zlib/contrib/minizip/unzip.h +354 -0
  449. data/windows/zlib, libpng/zlib/contrib/minizip/zip.c +1219 -0
  450. data/windows/zlib, libpng/zlib/contrib/minizip/zip.h +235 -0
  451. data/windows/zlib, libpng/zlib/contrib/pascal/example.pas +599 -0
  452. data/windows/zlib, libpng/zlib/contrib/pascal/readme.txt +76 -0
  453. data/windows/zlib, libpng/zlib/contrib/pascal/zlibd32.mak +93 -0
  454. data/windows/zlib, libpng/zlib/contrib/pascal/zlibpas.pas +236 -0
  455. data/windows/zlib, libpng/zlib/contrib/puff/Makefile +8 -0
  456. data/windows/zlib, libpng/zlib/contrib/puff/README +63 -0
  457. data/windows/zlib, libpng/zlib/contrib/puff/puff.c +837 -0
  458. data/windows/zlib, libpng/zlib/contrib/puff/puff.h +31 -0
  459. data/windows/zlib, libpng/zlib/contrib/puff/zeros.raw +0 -0
  460. data/windows/zlib, libpng/zlib/contrib/testzlib/testzlib.c +275 -0
  461. data/windows/zlib, libpng/zlib/contrib/testzlib/testzlib.txt +10 -0
  462. data/windows/zlib, libpng/zlib/contrib/untgz/Makefile +14 -0
  463. data/windows/zlib, libpng/zlib/contrib/untgz/Makefile.msc +17 -0
  464. data/windows/zlib, libpng/zlib/contrib/untgz/untgz.c +674 -0
  465. data/windows/zlib, libpng/zlib/contrib/vstudio/readme.txt +73 -0
  466. data/windows/zlib, libpng/zlib/contrib/vstudio/vc7/miniunz.vcproj +126 -0
  467. data/windows/zlib, libpng/zlib/contrib/vstudio/vc7/minizip.vcproj +126 -0
  468. data/windows/zlib, libpng/zlib/contrib/vstudio/vc7/testzlib.vcproj +126 -0
  469. data/windows/zlib, libpng/zlib/contrib/vstudio/vc7/zlib.rc +32 -0
  470. data/windows/zlib, libpng/zlib/contrib/vstudio/vc7/zlibstat.vcproj +246 -0
  471. data/windows/zlib, libpng/zlib/contrib/vstudio/vc7/zlibvc.def +92 -0
  472. data/windows/zlib, libpng/zlib/contrib/vstudio/vc7/zlibvc.sln +78 -0
  473. data/windows/zlib, libpng/zlib/contrib/vstudio/vc7/zlibvc.vcproj +445 -0
  474. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/miniunz.vcproj +566 -0
  475. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/minizip.vcproj +563 -0
  476. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/testzlib.vcproj +948 -0
  477. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/testzlibdll.vcproj +567 -0
  478. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/zlib.rc +32 -0
  479. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/zlibstat.vcproj +870 -0
  480. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/zlibvc.def +92 -0
  481. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/zlibvc.sln +144 -0
  482. data/windows/zlib, libpng/zlib/contrib/vstudio/vc8/zlibvc.vcproj +1219 -0
  483. data/windows/zlib, libpng/zlib/crc32.c +423 -0
  484. data/windows/zlib, libpng/zlib/crc32.h +441 -0
  485. data/windows/zlib, libpng/zlib/deflate.c +1736 -0
  486. data/windows/zlib, libpng/zlib/deflate.h +331 -0
  487. data/windows/zlib, libpng/zlib/example.c +565 -0
  488. data/windows/zlib, libpng/zlib/examples/README.examples +42 -0
  489. data/windows/zlib, libpng/zlib/examples/fitblk.c +233 -0
  490. data/windows/zlib, libpng/zlib/examples/gun.c +693 -0
  491. data/windows/zlib, libpng/zlib/examples/gzappend.c +500 -0
  492. data/windows/zlib, libpng/zlib/examples/gzjoin.c +448 -0
  493. data/windows/zlib, libpng/zlib/examples/gzlog.c +413 -0
  494. data/windows/zlib, libpng/zlib/examples/gzlog.h +58 -0
  495. data/windows/zlib, libpng/zlib/examples/zlib_how.html +523 -0
  496. data/windows/zlib, libpng/zlib/examples/zpipe.c +191 -0
  497. data/windows/zlib, libpng/zlib/examples/zran.c +404 -0
  498. data/windows/zlib, libpng/zlib/gzio.c +1026 -0
  499. data/windows/zlib, libpng/zlib/infback.c +623 -0
  500. data/windows/zlib, libpng/zlib/inffast.c +318 -0
  501. data/windows/zlib, libpng/zlib/inffast.h +11 -0
  502. data/windows/zlib, libpng/zlib/inffixed.h +94 -0
  503. data/windows/zlib, libpng/zlib/inflate.c +1368 -0
  504. data/windows/zlib, libpng/zlib/inflate.h +115 -0
  505. data/windows/zlib, libpng/zlib/inftrees.c +329 -0
  506. data/windows/zlib, libpng/zlib/inftrees.h +55 -0
  507. data/windows/zlib, libpng/zlib/make_vms.com +461 -0
  508. data/windows/zlib, libpng/zlib/minigzip.c +322 -0
  509. data/windows/zlib, libpng/zlib/msdos/Makefile.bor +109 -0
  510. data/windows/zlib, libpng/zlib/msdos/Makefile.dj2 +104 -0
  511. data/windows/zlib, libpng/zlib/msdos/Makefile.emx +69 -0
  512. data/windows/zlib, libpng/zlib/msdos/Makefile.msc +106 -0
  513. data/windows/zlib, libpng/zlib/msdos/Makefile.tc +94 -0
  514. data/windows/zlib, libpng/zlib/old/Makefile.riscos +151 -0
  515. data/windows/zlib, libpng/zlib/old/README +3 -0
  516. data/windows/zlib, libpng/zlib/old/descrip.mms +48 -0
  517. data/windows/zlib, libpng/zlib/old/os2/Makefile.os2 +136 -0
  518. data/windows/zlib, libpng/zlib/old/os2/zlib.def +51 -0
  519. data/windows/zlib, libpng/zlib/old/visual-basic.txt +160 -0
  520. data/windows/zlib, libpng/zlib/old/zlib.html +971 -0
  521. data/windows/zlib, libpng/zlib/projects/README.projects +41 -0
  522. data/windows/zlib, libpng/zlib/projects/visualc6/README.txt +73 -0
  523. data/windows/zlib, libpng/zlib/projects/visualc6/example.dsp +278 -0
  524. data/windows/zlib, libpng/zlib/projects/visualc6/minigzip.dsp +278 -0
  525. data/windows/zlib, libpng/zlib/projects/visualc6/zlib.dsp +609 -0
  526. data/windows/zlib, libpng/zlib/projects/visualc6/zlib.dsw +59 -0
  527. data/windows/zlib, libpng/zlib/qnx/package.qpg +141 -0
  528. data/windows/zlib, libpng/zlib/trees.c +1219 -0
  529. data/windows/zlib, libpng/zlib/trees.h +128 -0
  530. data/windows/zlib, libpng/zlib/uncompr.c +61 -0
  531. data/windows/zlib, libpng/zlib/win32/DLL_FAQ.txt +397 -0
  532. data/windows/zlib, libpng/zlib/win32/Makefile.bor +107 -0
  533. data/windows/zlib, libpng/zlib/win32/Makefile.emx +69 -0
  534. data/windows/zlib, libpng/zlib/win32/Makefile.gcc +141 -0
  535. data/windows/zlib, libpng/zlib/win32/Makefile.msc +126 -0
  536. data/windows/zlib, libpng/zlib/win32/VisualC.txt +3 -0
  537. data/windows/zlib, libpng/zlib/win32/zlib.def +60 -0
  538. data/windows/zlib, libpng/zlib/win32/zlib1.rc +39 -0
  539. data/windows/zlib, libpng/zlib/zconf.h +332 -0
  540. data/windows/zlib, libpng/zlib/zconf.in.h +332 -0
  541. data/windows/zlib, libpng/zlib/zlib.3 +159 -0
  542. data/windows/zlib, libpng/zlib/zlib.h +1357 -0
  543. data/windows/zlib, libpng/zlib/zutil.c +318 -0
  544. data/windows/zlib, libpng/zlib/zutil.h +269 -0
  545. metadata +669 -216
@@ -0,0 +1,2802 @@
1
+
2
+ /* pngwutil.c - utilities to write a PNG file
3
+ *
4
+ * Last changed in libpng 1.2.27 [April 29, 2008]
5
+ * For conditions of distribution and use, see copyright notice in png.h
6
+ * Copyright (c) 1998-2008 Glenn Randers-Pehrson
7
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9
+ */
10
+
11
+ #define PNG_INTERNAL
12
+ #include "png.h"
13
+ #ifdef PNG_WRITE_SUPPORTED
14
+
15
+ /* Place a 32-bit number into a buffer in PNG byte order. We work
16
+ * with unsigned numbers for convenience, although one supported
17
+ * ancillary chunk uses signed (two's complement) numbers.
18
+ */
19
+ void PNGAPI
20
+ png_save_uint_32(png_bytep buf, png_uint_32 i)
21
+ {
22
+ buf[0] = (png_byte)((i >> 24) & 0xff);
23
+ buf[1] = (png_byte)((i >> 16) & 0xff);
24
+ buf[2] = (png_byte)((i >> 8) & 0xff);
25
+ buf[3] = (png_byte)(i & 0xff);
26
+ }
27
+
28
+ /* The png_save_int_32 function assumes integers are stored in two's
29
+ * complement format. If this isn't the case, then this routine needs to
30
+ * be modified to write data in two's complement format.
31
+ */
32
+ void PNGAPI
33
+ png_save_int_32(png_bytep buf, png_int_32 i)
34
+ {
35
+ buf[0] = (png_byte)((i >> 24) & 0xff);
36
+ buf[1] = (png_byte)((i >> 16) & 0xff);
37
+ buf[2] = (png_byte)((i >> 8) & 0xff);
38
+ buf[3] = (png_byte)(i & 0xff);
39
+ }
40
+
41
+ /* Place a 16-bit number into a buffer in PNG byte order.
42
+ * The parameter is declared unsigned int, not png_uint_16,
43
+ * just to avoid potential problems on pre-ANSI C compilers.
44
+ */
45
+ void PNGAPI
46
+ png_save_uint_16(png_bytep buf, unsigned int i)
47
+ {
48
+ buf[0] = (png_byte)((i >> 8) & 0xff);
49
+ buf[1] = (png_byte)(i & 0xff);
50
+ }
51
+
52
+ /* Write a PNG chunk all at once. The type is an array of ASCII characters
53
+ * representing the chunk name. The array must be at least 4 bytes in
54
+ * length, and does not need to be null terminated. To be safe, pass the
55
+ * pre-defined chunk names here, and if you need a new one, define it
56
+ * where the others are defined. The length is the length of the data.
57
+ * All the data must be present. If that is not possible, use the
58
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
59
+ * functions instead.
60
+ */
61
+ void PNGAPI
62
+ png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
63
+ png_bytep data, png_size_t length)
64
+ {
65
+ if(png_ptr == NULL) return;
66
+ png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
67
+ png_write_chunk_data(png_ptr, data, length);
68
+ png_write_chunk_end(png_ptr);
69
+ }
70
+
71
+ /* Write the start of a PNG chunk. The type is the chunk type.
72
+ * The total_length is the sum of the lengths of all the data you will be
73
+ * passing in png_write_chunk_data().
74
+ */
75
+ void PNGAPI
76
+ png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
77
+ png_uint_32 length)
78
+ {
79
+ png_byte buf[4];
80
+ png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length);
81
+ if(png_ptr == NULL) return;
82
+
83
+ /* write the length */
84
+ png_save_uint_32(buf, length);
85
+ png_write_data(png_ptr, buf, (png_size_t)4);
86
+
87
+ /* write the chunk name */
88
+ png_write_data(png_ptr, chunk_name, (png_size_t)4);
89
+ /* reset the crc and run it over the chunk name */
90
+ png_reset_crc(png_ptr);
91
+ png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
92
+ }
93
+
94
+ /* Write the data of a PNG chunk started with png_write_chunk_start().
95
+ * Note that multiple calls to this function are allowed, and that the
96
+ * sum of the lengths from these calls *must* add up to the total_length
97
+ * given to png_write_chunk_start().
98
+ */
99
+ void PNGAPI
100
+ png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
101
+ {
102
+ /* write the data, and run the CRC over it */
103
+ if(png_ptr == NULL) return;
104
+ if (data != NULL && length > 0)
105
+ {
106
+ png_calculate_crc(png_ptr, data, length);
107
+ png_write_data(png_ptr, data, length);
108
+ }
109
+ }
110
+
111
+ /* Finish a chunk started with png_write_chunk_start(). */
112
+ void PNGAPI
113
+ png_write_chunk_end(png_structp png_ptr)
114
+ {
115
+ png_byte buf[4];
116
+
117
+ if(png_ptr == NULL) return;
118
+
119
+ /* write the crc */
120
+ png_save_uint_32(buf, png_ptr->crc);
121
+
122
+ png_write_data(png_ptr, buf, (png_size_t)4);
123
+ }
124
+
125
+ /* Simple function to write the signature. If we have already written
126
+ * the magic bytes of the signature, or more likely, the PNG stream is
127
+ * being embedded into another stream and doesn't need its own signature,
128
+ * we should call png_set_sig_bytes() to tell libpng how many of the
129
+ * bytes have already been written.
130
+ */
131
+ void /* PRIVATE */
132
+ png_write_sig(png_structp png_ptr)
133
+ {
134
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
135
+ /* write the rest of the 8 byte signature */
136
+ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
137
+ (png_size_t)8 - png_ptr->sig_bytes);
138
+ if(png_ptr->sig_bytes < 3)
139
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
140
+ }
141
+
142
+ #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
143
+ /*
144
+ * This pair of functions encapsulates the operation of (a) compressing a
145
+ * text string, and (b) issuing it later as a series of chunk data writes.
146
+ * The compression_state structure is shared context for these functions
147
+ * set up by the caller in order to make the whole mess thread-safe.
148
+ */
149
+
150
+ typedef struct
151
+ {
152
+ char *input; /* the uncompressed input data */
153
+ int input_len; /* its length */
154
+ int num_output_ptr; /* number of output pointers used */
155
+ int max_output_ptr; /* size of output_ptr */
156
+ png_charpp output_ptr; /* array of pointers to output */
157
+ } compression_state;
158
+
159
+ /* compress given text into storage in the png_ptr structure */
160
+ static int /* PRIVATE */
161
+ png_text_compress(png_structp png_ptr,
162
+ png_charp text, png_size_t text_len, int compression,
163
+ compression_state *comp)
164
+ {
165
+ int ret;
166
+
167
+ comp->num_output_ptr = 0;
168
+ comp->max_output_ptr = 0;
169
+ comp->output_ptr = NULL;
170
+ comp->input = NULL;
171
+ comp->input_len = 0;
172
+
173
+ /* we may just want to pass the text right through */
174
+ if (compression == PNG_TEXT_COMPRESSION_NONE)
175
+ {
176
+ comp->input = text;
177
+ comp->input_len = text_len;
178
+ return((int)text_len);
179
+ }
180
+
181
+ if (compression >= PNG_TEXT_COMPRESSION_LAST)
182
+ {
183
+ #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
184
+ char msg[50];
185
+ png_snprintf(msg, 50, "Unknown compression type %d", compression);
186
+ png_warning(png_ptr, msg);
187
+ #else
188
+ png_warning(png_ptr, "Unknown compression type");
189
+ #endif
190
+ }
191
+
192
+ /* We can't write the chunk until we find out how much data we have,
193
+ * which means we need to run the compressor first and save the
194
+ * output. This shouldn't be a problem, as the vast majority of
195
+ * comments should be reasonable, but we will set up an array of
196
+ * malloc'd pointers to be sure.
197
+ *
198
+ * If we knew the application was well behaved, we could simplify this
199
+ * greatly by assuming we can always malloc an output buffer large
200
+ * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
201
+ * and malloc this directly. The only time this would be a bad idea is
202
+ * if we can't malloc more than 64K and we have 64K of random input
203
+ * data, or if the input string is incredibly large (although this
204
+ * wouldn't cause a failure, just a slowdown due to swapping).
205
+ */
206
+
207
+ /* set up the compression buffers */
208
+ png_ptr->zstream.avail_in = (uInt)text_len;
209
+ png_ptr->zstream.next_in = (Bytef *)text;
210
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
211
+ png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
212
+
213
+ /* this is the same compression loop as in png_write_row() */
214
+ do
215
+ {
216
+ /* compress the data */
217
+ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
218
+ if (ret != Z_OK)
219
+ {
220
+ /* error */
221
+ if (png_ptr->zstream.msg != NULL)
222
+ png_error(png_ptr, png_ptr->zstream.msg);
223
+ else
224
+ png_error(png_ptr, "zlib error");
225
+ }
226
+ /* check to see if we need more room */
227
+ if (!(png_ptr->zstream.avail_out))
228
+ {
229
+ /* make sure the output array has room */
230
+ if (comp->num_output_ptr >= comp->max_output_ptr)
231
+ {
232
+ int old_max;
233
+
234
+ old_max = comp->max_output_ptr;
235
+ comp->max_output_ptr = comp->num_output_ptr + 4;
236
+ if (comp->output_ptr != NULL)
237
+ {
238
+ png_charpp old_ptr;
239
+
240
+ old_ptr = comp->output_ptr;
241
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
242
+ (png_uint_32)(comp->max_output_ptr *
243
+ png_sizeof (png_charpp)));
244
+ png_memcpy(comp->output_ptr, old_ptr, old_max
245
+ * png_sizeof (png_charp));
246
+ png_free(png_ptr, old_ptr);
247
+ }
248
+ else
249
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
250
+ (png_uint_32)(comp->max_output_ptr *
251
+ png_sizeof (png_charp)));
252
+ }
253
+
254
+ /* save the data */
255
+ comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
256
+ (png_uint_32)png_ptr->zbuf_size);
257
+ png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
258
+ png_ptr->zbuf_size);
259
+ comp->num_output_ptr++;
260
+
261
+ /* and reset the buffer */
262
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
263
+ png_ptr->zstream.next_out = png_ptr->zbuf;
264
+ }
265
+ /* continue until we don't have any more to compress */
266
+ } while (png_ptr->zstream.avail_in);
267
+
268
+ /* finish the compression */
269
+ do
270
+ {
271
+ /* tell zlib we are finished */
272
+ ret = deflate(&png_ptr->zstream, Z_FINISH);
273
+
274
+ if (ret == Z_OK)
275
+ {
276
+ /* check to see if we need more room */
277
+ if (!(png_ptr->zstream.avail_out))
278
+ {
279
+ /* check to make sure our output array has room */
280
+ if (comp->num_output_ptr >= comp->max_output_ptr)
281
+ {
282
+ int old_max;
283
+
284
+ old_max = comp->max_output_ptr;
285
+ comp->max_output_ptr = comp->num_output_ptr + 4;
286
+ if (comp->output_ptr != NULL)
287
+ {
288
+ png_charpp old_ptr;
289
+
290
+ old_ptr = comp->output_ptr;
291
+ /* This could be optimized to realloc() */
292
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
293
+ (png_uint_32)(comp->max_output_ptr *
294
+ png_sizeof (png_charpp)));
295
+ png_memcpy(comp->output_ptr, old_ptr,
296
+ old_max * png_sizeof (png_charp));
297
+ png_free(png_ptr, old_ptr);
298
+ }
299
+ else
300
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
301
+ (png_uint_32)(comp->max_output_ptr *
302
+ png_sizeof (png_charp)));
303
+ }
304
+
305
+ /* save off the data */
306
+ comp->output_ptr[comp->num_output_ptr] =
307
+ (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size);
308
+ png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
309
+ png_ptr->zbuf_size);
310
+ comp->num_output_ptr++;
311
+
312
+ /* and reset the buffer pointers */
313
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
314
+ png_ptr->zstream.next_out = png_ptr->zbuf;
315
+ }
316
+ }
317
+ else if (ret != Z_STREAM_END)
318
+ {
319
+ /* we got an error */
320
+ if (png_ptr->zstream.msg != NULL)
321
+ png_error(png_ptr, png_ptr->zstream.msg);
322
+ else
323
+ png_error(png_ptr, "zlib error");
324
+ }
325
+ } while (ret != Z_STREAM_END);
326
+
327
+ /* text length is number of buffers plus last buffer */
328
+ text_len = png_ptr->zbuf_size * comp->num_output_ptr;
329
+ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
330
+ text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
331
+
332
+ return((int)text_len);
333
+ }
334
+
335
+ /* ship the compressed text out via chunk writes */
336
+ static void /* PRIVATE */
337
+ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
338
+ {
339
+ int i;
340
+
341
+ /* handle the no-compression case */
342
+ if (comp->input)
343
+ {
344
+ png_write_chunk_data(png_ptr, (png_bytep)comp->input,
345
+ (png_size_t)comp->input_len);
346
+ return;
347
+ }
348
+
349
+ /* write saved output buffers, if any */
350
+ for (i = 0; i < comp->num_output_ptr; i++)
351
+ {
352
+ png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],
353
+ png_ptr->zbuf_size);
354
+ png_free(png_ptr, comp->output_ptr[i]);
355
+ comp->output_ptr[i]=NULL;
356
+ }
357
+ if (comp->max_output_ptr != 0)
358
+ png_free(png_ptr, comp->output_ptr);
359
+ comp->output_ptr=NULL;
360
+ /* write anything left in zbuf */
361
+ if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
362
+ png_write_chunk_data(png_ptr, png_ptr->zbuf,
363
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
364
+
365
+ /* reset zlib for another zTXt/iTXt or image data */
366
+ deflateReset(&png_ptr->zstream);
367
+ png_ptr->zstream.data_type = Z_BINARY;
368
+ }
369
+ #endif
370
+
371
+ /* Write the IHDR chunk, and update the png_struct with the necessary
372
+ * information. Note that the rest of this code depends upon this
373
+ * information being correct.
374
+ */
375
+ void /* PRIVATE */
376
+ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
377
+ int bit_depth, int color_type, int compression_type, int filter_type,
378
+ int interlace_type)
379
+ {
380
+ #ifdef PNG_USE_LOCAL_ARRAYS
381
+ PNG_IHDR;
382
+ #endif
383
+ int ret;
384
+
385
+ png_byte buf[13]; /* buffer to store the IHDR info */
386
+
387
+ png_debug(1, "in png_write_IHDR\n");
388
+ /* Check that we have valid input data from the application info */
389
+ switch (color_type)
390
+ {
391
+ case PNG_COLOR_TYPE_GRAY:
392
+ switch (bit_depth)
393
+ {
394
+ case 1:
395
+ case 2:
396
+ case 4:
397
+ case 8:
398
+ case 16: png_ptr->channels = 1; break;
399
+ default: png_error(png_ptr,"Invalid bit depth for grayscale image");
400
+ }
401
+ break;
402
+ case PNG_COLOR_TYPE_RGB:
403
+ if (bit_depth != 8 && bit_depth != 16)
404
+ png_error(png_ptr, "Invalid bit depth for RGB image");
405
+ png_ptr->channels = 3;
406
+ break;
407
+ case PNG_COLOR_TYPE_PALETTE:
408
+ switch (bit_depth)
409
+ {
410
+ case 1:
411
+ case 2:
412
+ case 4:
413
+ case 8: png_ptr->channels = 1; break;
414
+ default: png_error(png_ptr, "Invalid bit depth for paletted image");
415
+ }
416
+ break;
417
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
418
+ if (bit_depth != 8 && bit_depth != 16)
419
+ png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
420
+ png_ptr->channels = 2;
421
+ break;
422
+ case PNG_COLOR_TYPE_RGB_ALPHA:
423
+ if (bit_depth != 8 && bit_depth != 16)
424
+ png_error(png_ptr, "Invalid bit depth for RGBA image");
425
+ png_ptr->channels = 4;
426
+ break;
427
+ default:
428
+ png_error(png_ptr, "Invalid image color type specified");
429
+ }
430
+
431
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
432
+ {
433
+ png_warning(png_ptr, "Invalid compression type specified");
434
+ compression_type = PNG_COMPRESSION_TYPE_BASE;
435
+ }
436
+
437
+ /* Write filter_method 64 (intrapixel differencing) only if
438
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
439
+ * 2. Libpng did not write a PNG signature (this filter_method is only
440
+ * used in PNG datastreams that are embedded in MNG datastreams) and
441
+ * 3. The application called png_permit_mng_features with a mask that
442
+ * included PNG_FLAG_MNG_FILTER_64 and
443
+ * 4. The filter_method is 64 and
444
+ * 5. The color_type is RGB or RGBA
445
+ */
446
+ if (
447
+ #if defined(PNG_MNG_FEATURES_SUPPORTED)
448
+ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
449
+ ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
450
+ (color_type == PNG_COLOR_TYPE_RGB ||
451
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
452
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
453
+ #endif
454
+ filter_type != PNG_FILTER_TYPE_BASE)
455
+ {
456
+ png_warning(png_ptr, "Invalid filter type specified");
457
+ filter_type = PNG_FILTER_TYPE_BASE;
458
+ }
459
+
460
+ #ifdef PNG_WRITE_INTERLACING_SUPPORTED
461
+ if (interlace_type != PNG_INTERLACE_NONE &&
462
+ interlace_type != PNG_INTERLACE_ADAM7)
463
+ {
464
+ png_warning(png_ptr, "Invalid interlace type specified");
465
+ interlace_type = PNG_INTERLACE_ADAM7;
466
+ }
467
+ #else
468
+ interlace_type=PNG_INTERLACE_NONE;
469
+ #endif
470
+
471
+ /* save off the relevent information */
472
+ png_ptr->bit_depth = (png_byte)bit_depth;
473
+ png_ptr->color_type = (png_byte)color_type;
474
+ png_ptr->interlaced = (png_byte)interlace_type;
475
+ #if defined(PNG_MNG_FEATURES_SUPPORTED)
476
+ png_ptr->filter_type = (png_byte)filter_type;
477
+ #endif
478
+ png_ptr->compression_type = (png_byte)compression_type;
479
+ png_ptr->width = width;
480
+ png_ptr->height = height;
481
+
482
+ png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
483
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
484
+ /* set the usr info, so any transformations can modify it */
485
+ png_ptr->usr_width = png_ptr->width;
486
+ png_ptr->usr_bit_depth = png_ptr->bit_depth;
487
+ png_ptr->usr_channels = png_ptr->channels;
488
+
489
+ /* pack the header information into the buffer */
490
+ png_save_uint_32(buf, width);
491
+ png_save_uint_32(buf + 4, height);
492
+ buf[8] = (png_byte)bit_depth;
493
+ buf[9] = (png_byte)color_type;
494
+ buf[10] = (png_byte)compression_type;
495
+ buf[11] = (png_byte)filter_type;
496
+ buf[12] = (png_byte)interlace_type;
497
+
498
+ /* write the chunk */
499
+ png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
500
+
501
+ /* initialize zlib with PNG info */
502
+ png_ptr->zstream.zalloc = png_zalloc;
503
+ png_ptr->zstream.zfree = png_zfree;
504
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
505
+ if (!(png_ptr->do_filter))
506
+ {
507
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
508
+ png_ptr->bit_depth < 8)
509
+ png_ptr->do_filter = PNG_FILTER_NONE;
510
+ else
511
+ png_ptr->do_filter = PNG_ALL_FILTERS;
512
+ }
513
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
514
+ {
515
+ if (png_ptr->do_filter != PNG_FILTER_NONE)
516
+ png_ptr->zlib_strategy = Z_FILTERED;
517
+ else
518
+ png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
519
+ }
520
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
521
+ png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
522
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
523
+ png_ptr->zlib_mem_level = 8;
524
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
525
+ png_ptr->zlib_window_bits = 15;
526
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
527
+ png_ptr->zlib_method = 8;
528
+ ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
529
+ png_ptr->zlib_method, png_ptr->zlib_window_bits,
530
+ png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
531
+ if (ret != Z_OK)
532
+ {
533
+ if (ret == Z_VERSION_ERROR) png_error(png_ptr,
534
+ "zlib failed to initialize compressor -- version error");
535
+ if (ret == Z_STREAM_ERROR) png_error(png_ptr,
536
+ "zlib failed to initialize compressor -- stream error");
537
+ if (ret == Z_MEM_ERROR) png_error(png_ptr,
538
+ "zlib failed to initialize compressor -- mem error");
539
+ png_error(png_ptr, "zlib failed to initialize compressor");
540
+ }
541
+ png_ptr->zstream.next_out = png_ptr->zbuf;
542
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
543
+ /* libpng is not interested in zstream.data_type */
544
+ /* set it to a predefined value, to avoid its evaluation inside zlib */
545
+ png_ptr->zstream.data_type = Z_BINARY;
546
+
547
+ png_ptr->mode = PNG_HAVE_IHDR;
548
+ }
549
+
550
+ /* write the palette. We are careful not to trust png_color to be in the
551
+ * correct order for PNG, so people can redefine it to any convenient
552
+ * structure.
553
+ */
554
+ void /* PRIVATE */
555
+ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
556
+ {
557
+ #ifdef PNG_USE_LOCAL_ARRAYS
558
+ PNG_PLTE;
559
+ #endif
560
+ png_uint_32 i;
561
+ png_colorp pal_ptr;
562
+ png_byte buf[3];
563
+
564
+ png_debug(1, "in png_write_PLTE\n");
565
+ if ((
566
+ #if defined(PNG_MNG_FEATURES_SUPPORTED)
567
+ !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
568
+ #endif
569
+ num_pal == 0) || num_pal > 256)
570
+ {
571
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
572
+ {
573
+ png_error(png_ptr, "Invalid number of colors in palette");
574
+ }
575
+ else
576
+ {
577
+ png_warning(png_ptr, "Invalid number of colors in palette");
578
+ return;
579
+ }
580
+ }
581
+
582
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
583
+ {
584
+ png_warning(png_ptr,
585
+ "Ignoring request to write a PLTE chunk in grayscale PNG");
586
+ return;
587
+ }
588
+
589
+ png_ptr->num_palette = (png_uint_16)num_pal;
590
+ png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
591
+
592
+ png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3);
593
+ #ifndef PNG_NO_POINTER_INDEXING
594
+ for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
595
+ {
596
+ buf[0] = pal_ptr->red;
597
+ buf[1] = pal_ptr->green;
598
+ buf[2] = pal_ptr->blue;
599
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
600
+ }
601
+ #else
602
+ /* This is a little slower but some buggy compilers need to do this instead */
603
+ pal_ptr=palette;
604
+ for (i = 0; i < num_pal; i++)
605
+ {
606
+ buf[0] = pal_ptr[i].red;
607
+ buf[1] = pal_ptr[i].green;
608
+ buf[2] = pal_ptr[i].blue;
609
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
610
+ }
611
+ #endif
612
+ png_write_chunk_end(png_ptr);
613
+ png_ptr->mode |= PNG_HAVE_PLTE;
614
+ }
615
+
616
+ /* write an IDAT chunk */
617
+ void /* PRIVATE */
618
+ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
619
+ {
620
+ #ifdef PNG_USE_LOCAL_ARRAYS
621
+ PNG_IDAT;
622
+ #endif
623
+ png_debug(1, "in png_write_IDAT\n");
624
+
625
+ /* Optimize the CMF field in the zlib stream. */
626
+ /* This hack of the zlib stream is compliant to the stream specification. */
627
+ if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
628
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
629
+ {
630
+ unsigned int z_cmf = data[0]; /* zlib compression method and flags */
631
+ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
632
+ {
633
+ /* Avoid memory underflows and multiplication overflows. */
634
+ /* The conditions below are practically always satisfied;
635
+ however, they still must be checked. */
636
+ if (length >= 2 &&
637
+ png_ptr->height < 16384 && png_ptr->width < 16384)
638
+ {
639
+ png_uint_32 uncompressed_idat_size = png_ptr->height *
640
+ ((png_ptr->width *
641
+ png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
642
+ unsigned int z_cinfo = z_cmf >> 4;
643
+ unsigned int half_z_window_size = 1 << (z_cinfo + 7);
644
+ while (uncompressed_idat_size <= half_z_window_size &&
645
+ half_z_window_size >= 256)
646
+ {
647
+ z_cinfo--;
648
+ half_z_window_size >>= 1;
649
+ }
650
+ z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
651
+ if (data[0] != (png_byte)z_cmf)
652
+ {
653
+ data[0] = (png_byte)z_cmf;
654
+ data[1] &= 0xe0;
655
+ data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f);
656
+ }
657
+ }
658
+ }
659
+ else
660
+ png_error(png_ptr,
661
+ "Invalid zlib compression method or flags in IDAT");
662
+ }
663
+
664
+ png_write_chunk(png_ptr, png_IDAT, data, length);
665
+ png_ptr->mode |= PNG_HAVE_IDAT;
666
+ }
667
+
668
+ /* write an IEND chunk */
669
+ void /* PRIVATE */
670
+ png_write_IEND(png_structp png_ptr)
671
+ {
672
+ #ifdef PNG_USE_LOCAL_ARRAYS
673
+ PNG_IEND;
674
+ #endif
675
+ png_debug(1, "in png_write_IEND\n");
676
+ png_write_chunk(png_ptr, png_IEND, png_bytep_NULL,
677
+ (png_size_t)0);
678
+ png_ptr->mode |= PNG_HAVE_IEND;
679
+ }
680
+
681
+ #if defined(PNG_WRITE_gAMA_SUPPORTED)
682
+ /* write a gAMA chunk */
683
+ #ifdef PNG_FLOATING_POINT_SUPPORTED
684
+ void /* PRIVATE */
685
+ png_write_gAMA(png_structp png_ptr, double file_gamma)
686
+ {
687
+ #ifdef PNG_USE_LOCAL_ARRAYS
688
+ PNG_gAMA;
689
+ #endif
690
+ png_uint_32 igamma;
691
+ png_byte buf[4];
692
+
693
+ png_debug(1, "in png_write_gAMA\n");
694
+ /* file_gamma is saved in 1/100,000ths */
695
+ igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
696
+ png_save_uint_32(buf, igamma);
697
+ png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
698
+ }
699
+ #endif
700
+ #ifdef PNG_FIXED_POINT_SUPPORTED
701
+ void /* PRIVATE */
702
+ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
703
+ {
704
+ #ifdef PNG_USE_LOCAL_ARRAYS
705
+ PNG_gAMA;
706
+ #endif
707
+ png_byte buf[4];
708
+
709
+ png_debug(1, "in png_write_gAMA\n");
710
+ /* file_gamma is saved in 1/100,000ths */
711
+ png_save_uint_32(buf, (png_uint_32)file_gamma);
712
+ png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
713
+ }
714
+ #endif
715
+ #endif
716
+
717
+ #if defined(PNG_WRITE_sRGB_SUPPORTED)
718
+ /* write a sRGB chunk */
719
+ void /* PRIVATE */
720
+ png_write_sRGB(png_structp png_ptr, int srgb_intent)
721
+ {
722
+ #ifdef PNG_USE_LOCAL_ARRAYS
723
+ PNG_sRGB;
724
+ #endif
725
+ png_byte buf[1];
726
+
727
+ png_debug(1, "in png_write_sRGB\n");
728
+ if(srgb_intent >= PNG_sRGB_INTENT_LAST)
729
+ png_warning(png_ptr,
730
+ "Invalid sRGB rendering intent specified");
731
+ buf[0]=(png_byte)srgb_intent;
732
+ png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
733
+ }
734
+ #endif
735
+
736
+ #if defined(PNG_WRITE_iCCP_SUPPORTED)
737
+ /* write an iCCP chunk */
738
+ void /* PRIVATE */
739
+ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
740
+ png_charp profile, int profile_len)
741
+ {
742
+ #ifdef PNG_USE_LOCAL_ARRAYS
743
+ PNG_iCCP;
744
+ #endif
745
+ png_size_t name_len;
746
+ png_charp new_name;
747
+ compression_state comp;
748
+ int embedded_profile_len = 0;
749
+
750
+ png_debug(1, "in png_write_iCCP\n");
751
+
752
+ comp.num_output_ptr = 0;
753
+ comp.max_output_ptr = 0;
754
+ comp.output_ptr = NULL;
755
+ comp.input = NULL;
756
+ comp.input_len = 0;
757
+
758
+ if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
759
+ &new_name)) == 0)
760
+ {
761
+ png_warning(png_ptr, "Empty keyword in iCCP chunk");
762
+ return;
763
+ }
764
+
765
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
766
+ png_warning(png_ptr, "Unknown compression type in iCCP chunk");
767
+
768
+ if (profile == NULL)
769
+ profile_len = 0;
770
+
771
+ if (profile_len > 3)
772
+ embedded_profile_len =
773
+ ((*( (png_bytep)profile ))<<24) |
774
+ ((*( (png_bytep)profile+1))<<16) |
775
+ ((*( (png_bytep)profile+2))<< 8) |
776
+ ((*( (png_bytep)profile+3)) );
777
+
778
+ if (profile_len < embedded_profile_len)
779
+ {
780
+ png_warning(png_ptr,
781
+ "Embedded profile length too large in iCCP chunk");
782
+ return;
783
+ }
784
+
785
+ if (profile_len > embedded_profile_len)
786
+ {
787
+ png_warning(png_ptr,
788
+ "Truncating profile to actual length in iCCP chunk");
789
+ profile_len = embedded_profile_len;
790
+ }
791
+
792
+ if (profile_len)
793
+ profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len,
794
+ PNG_COMPRESSION_TYPE_BASE, &comp);
795
+
796
+ /* make sure we include the NULL after the name and the compression type */
797
+ png_write_chunk_start(png_ptr, png_iCCP,
798
+ (png_uint_32)name_len+profile_len+2);
799
+ new_name[name_len+1]=0x00;
800
+ png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
801
+
802
+ if (profile_len)
803
+ png_write_compressed_data_out(png_ptr, &comp);
804
+
805
+ png_write_chunk_end(png_ptr);
806
+ png_free(png_ptr, new_name);
807
+ }
808
+ #endif
809
+
810
+ #if defined(PNG_WRITE_sPLT_SUPPORTED)
811
+ /* write a sPLT chunk */
812
+ void /* PRIVATE */
813
+ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
814
+ {
815
+ #ifdef PNG_USE_LOCAL_ARRAYS
816
+ PNG_sPLT;
817
+ #endif
818
+ png_size_t name_len;
819
+ png_charp new_name;
820
+ png_byte entrybuf[10];
821
+ int entry_size = (spalette->depth == 8 ? 6 : 10);
822
+ int palette_size = entry_size * spalette->nentries;
823
+ png_sPLT_entryp ep;
824
+ #ifdef PNG_NO_POINTER_INDEXING
825
+ int i;
826
+ #endif
827
+
828
+ png_debug(1, "in png_write_sPLT\n");
829
+ if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
830
+ spalette->name, &new_name))==0)
831
+ {
832
+ png_warning(png_ptr, "Empty keyword in sPLT chunk");
833
+ return;
834
+ }
835
+
836
+ /* make sure we include the NULL after the name */
837
+ png_write_chunk_start(png_ptr, png_sPLT,
838
+ (png_uint_32)(name_len + 2 + palette_size));
839
+ png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
840
+ png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1);
841
+
842
+ /* loop through each palette entry, writing appropriately */
843
+ #ifndef PNG_NO_POINTER_INDEXING
844
+ for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
845
+ {
846
+ if (spalette->depth == 8)
847
+ {
848
+ entrybuf[0] = (png_byte)ep->red;
849
+ entrybuf[1] = (png_byte)ep->green;
850
+ entrybuf[2] = (png_byte)ep->blue;
851
+ entrybuf[3] = (png_byte)ep->alpha;
852
+ png_save_uint_16(entrybuf + 4, ep->frequency);
853
+ }
854
+ else
855
+ {
856
+ png_save_uint_16(entrybuf + 0, ep->red);
857
+ png_save_uint_16(entrybuf + 2, ep->green);
858
+ png_save_uint_16(entrybuf + 4, ep->blue);
859
+ png_save_uint_16(entrybuf + 6, ep->alpha);
860
+ png_save_uint_16(entrybuf + 8, ep->frequency);
861
+ }
862
+ png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
863
+ }
864
+ #else
865
+ ep=spalette->entries;
866
+ for (i=0; i>spalette->nentries; i++)
867
+ {
868
+ if (spalette->depth == 8)
869
+ {
870
+ entrybuf[0] = (png_byte)ep[i].red;
871
+ entrybuf[1] = (png_byte)ep[i].green;
872
+ entrybuf[2] = (png_byte)ep[i].blue;
873
+ entrybuf[3] = (png_byte)ep[i].alpha;
874
+ png_save_uint_16(entrybuf + 4, ep[i].frequency);
875
+ }
876
+ else
877
+ {
878
+ png_save_uint_16(entrybuf + 0, ep[i].red);
879
+ png_save_uint_16(entrybuf + 2, ep[i].green);
880
+ png_save_uint_16(entrybuf + 4, ep[i].blue);
881
+ png_save_uint_16(entrybuf + 6, ep[i].alpha);
882
+ png_save_uint_16(entrybuf + 8, ep[i].frequency);
883
+ }
884
+ png_write_chunk_data(png_ptr, entrybuf, entry_size);
885
+ }
886
+ #endif
887
+
888
+ png_write_chunk_end(png_ptr);
889
+ png_free(png_ptr, new_name);
890
+ }
891
+ #endif
892
+
893
+ #if defined(PNG_WRITE_sBIT_SUPPORTED)
894
+ /* write the sBIT chunk */
895
+ void /* PRIVATE */
896
+ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
897
+ {
898
+ #ifdef PNG_USE_LOCAL_ARRAYS
899
+ PNG_sBIT;
900
+ #endif
901
+ png_byte buf[4];
902
+ png_size_t size;
903
+
904
+ png_debug(1, "in png_write_sBIT\n");
905
+ /* make sure we don't depend upon the order of PNG_COLOR_8 */
906
+ if (color_type & PNG_COLOR_MASK_COLOR)
907
+ {
908
+ png_byte maxbits;
909
+
910
+ maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
911
+ png_ptr->usr_bit_depth);
912
+ if (sbit->red == 0 || sbit->red > maxbits ||
913
+ sbit->green == 0 || sbit->green > maxbits ||
914
+ sbit->blue == 0 || sbit->blue > maxbits)
915
+ {
916
+ png_warning(png_ptr, "Invalid sBIT depth specified");
917
+ return;
918
+ }
919
+ buf[0] = sbit->red;
920
+ buf[1] = sbit->green;
921
+ buf[2] = sbit->blue;
922
+ size = 3;
923
+ }
924
+ else
925
+ {
926
+ if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
927
+ {
928
+ png_warning(png_ptr, "Invalid sBIT depth specified");
929
+ return;
930
+ }
931
+ buf[0] = sbit->gray;
932
+ size = 1;
933
+ }
934
+
935
+ if (color_type & PNG_COLOR_MASK_ALPHA)
936
+ {
937
+ if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
938
+ {
939
+ png_warning(png_ptr, "Invalid sBIT depth specified");
940
+ return;
941
+ }
942
+ buf[size++] = sbit->alpha;
943
+ }
944
+
945
+ png_write_chunk(png_ptr, png_sBIT, buf, size);
946
+ }
947
+ #endif
948
+
949
+ #if defined(PNG_WRITE_cHRM_SUPPORTED)
950
+ /* write the cHRM chunk */
951
+ #ifdef PNG_FLOATING_POINT_SUPPORTED
952
+ void /* PRIVATE */
953
+ png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
954
+ double red_x, double red_y, double green_x, double green_y,
955
+ double blue_x, double blue_y)
956
+ {
957
+ #ifdef PNG_USE_LOCAL_ARRAYS
958
+ PNG_cHRM;
959
+ #endif
960
+ png_byte buf[32];
961
+ png_uint_32 itemp;
962
+
963
+ png_debug(1, "in png_write_cHRM\n");
964
+ /* each value is saved in 1/100,000ths */
965
+ if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
966
+ white_x + white_y > 1.0)
967
+ {
968
+ png_warning(png_ptr, "Invalid cHRM white point specified");
969
+ #if !defined(PNG_NO_CONSOLE_IO)
970
+ fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y);
971
+ #endif
972
+ return;
973
+ }
974
+ itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
975
+ png_save_uint_32(buf, itemp);
976
+ itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
977
+ png_save_uint_32(buf + 4, itemp);
978
+
979
+ if (red_x < 0 || red_y < 0 || red_x + red_y > 1.0)
980
+ {
981
+ png_warning(png_ptr, "Invalid cHRM red point specified");
982
+ return;
983
+ }
984
+ itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
985
+ png_save_uint_32(buf + 8, itemp);
986
+ itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
987
+ png_save_uint_32(buf + 12, itemp);
988
+
989
+ if (green_x < 0 || green_y < 0 || green_x + green_y > 1.0)
990
+ {
991
+ png_warning(png_ptr, "Invalid cHRM green point specified");
992
+ return;
993
+ }
994
+ itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
995
+ png_save_uint_32(buf + 16, itemp);
996
+ itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
997
+ png_save_uint_32(buf + 20, itemp);
998
+
999
+ if (blue_x < 0 || blue_y < 0 || blue_x + blue_y > 1.0)
1000
+ {
1001
+ png_warning(png_ptr, "Invalid cHRM blue point specified");
1002
+ return;
1003
+ }
1004
+ itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
1005
+ png_save_uint_32(buf + 24, itemp);
1006
+ itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
1007
+ png_save_uint_32(buf + 28, itemp);
1008
+
1009
+ png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
1010
+ }
1011
+ #endif
1012
+ #ifdef PNG_FIXED_POINT_SUPPORTED
1013
+ void /* PRIVATE */
1014
+ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
1015
+ png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
1016
+ png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
1017
+ png_fixed_point blue_y)
1018
+ {
1019
+ #ifdef PNG_USE_LOCAL_ARRAYS
1020
+ PNG_cHRM;
1021
+ #endif
1022
+ png_byte buf[32];
1023
+
1024
+ png_debug(1, "in png_write_cHRM\n");
1025
+ /* each value is saved in 1/100,000ths */
1026
+ if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L)
1027
+ {
1028
+ png_warning(png_ptr, "Invalid fixed cHRM white point specified");
1029
+ #if !defined(PNG_NO_CONSOLE_IO)
1030
+ fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y);
1031
+ #endif
1032
+ return;
1033
+ }
1034
+ png_save_uint_32(buf, (png_uint_32)white_x);
1035
+ png_save_uint_32(buf + 4, (png_uint_32)white_y);
1036
+
1037
+ if (red_x + red_y > 100000L)
1038
+ {
1039
+ png_warning(png_ptr, "Invalid cHRM fixed red point specified");
1040
+ return;
1041
+ }
1042
+ png_save_uint_32(buf + 8, (png_uint_32)red_x);
1043
+ png_save_uint_32(buf + 12, (png_uint_32)red_y);
1044
+
1045
+ if (green_x + green_y > 100000L)
1046
+ {
1047
+ png_warning(png_ptr, "Invalid fixed cHRM green point specified");
1048
+ return;
1049
+ }
1050
+ png_save_uint_32(buf + 16, (png_uint_32)green_x);
1051
+ png_save_uint_32(buf + 20, (png_uint_32)green_y);
1052
+
1053
+ if (blue_x + blue_y > 100000L)
1054
+ {
1055
+ png_warning(png_ptr, "Invalid fixed cHRM blue point specified");
1056
+ return;
1057
+ }
1058
+ png_save_uint_32(buf + 24, (png_uint_32)blue_x);
1059
+ png_save_uint_32(buf + 28, (png_uint_32)blue_y);
1060
+
1061
+ png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
1062
+ }
1063
+ #endif
1064
+ #endif
1065
+
1066
+ #if defined(PNG_WRITE_tRNS_SUPPORTED)
1067
+ /* write the tRNS chunk */
1068
+ void /* PRIVATE */
1069
+ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
1070
+ int num_trans, int color_type)
1071
+ {
1072
+ #ifdef PNG_USE_LOCAL_ARRAYS
1073
+ PNG_tRNS;
1074
+ #endif
1075
+ png_byte buf[6];
1076
+
1077
+ png_debug(1, "in png_write_tRNS\n");
1078
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
1079
+ {
1080
+ if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
1081
+ {
1082
+ png_warning(png_ptr,"Invalid number of transparent colors specified");
1083
+ return;
1084
+ }
1085
+ /* write the chunk out as it is */
1086
+ png_write_chunk(png_ptr, png_tRNS, trans, (png_size_t)num_trans);
1087
+ }
1088
+ else if (color_type == PNG_COLOR_TYPE_GRAY)
1089
+ {
1090
+ /* one 16 bit value */
1091
+ if(tran->gray >= (1 << png_ptr->bit_depth))
1092
+ {
1093
+ png_warning(png_ptr,
1094
+ "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
1095
+ return;
1096
+ }
1097
+ png_save_uint_16(buf, tran->gray);
1098
+ png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
1099
+ }
1100
+ else if (color_type == PNG_COLOR_TYPE_RGB)
1101
+ {
1102
+ /* three 16 bit values */
1103
+ png_save_uint_16(buf, tran->red);
1104
+ png_save_uint_16(buf + 2, tran->green);
1105
+ png_save_uint_16(buf + 4, tran->blue);
1106
+ if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1107
+ {
1108
+ png_warning(png_ptr,
1109
+ "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
1110
+ return;
1111
+ }
1112
+ png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
1113
+ }
1114
+ else
1115
+ {
1116
+ png_warning(png_ptr, "Can't write tRNS with an alpha channel");
1117
+ }
1118
+ }
1119
+ #endif
1120
+
1121
+ #if defined(PNG_WRITE_bKGD_SUPPORTED)
1122
+ /* write the background chunk */
1123
+ void /* PRIVATE */
1124
+ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
1125
+ {
1126
+ #ifdef PNG_USE_LOCAL_ARRAYS
1127
+ PNG_bKGD;
1128
+ #endif
1129
+ png_byte buf[6];
1130
+
1131
+ png_debug(1, "in png_write_bKGD\n");
1132
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
1133
+ {
1134
+ if (
1135
+ #if defined(PNG_MNG_FEATURES_SUPPORTED)
1136
+ (png_ptr->num_palette ||
1137
+ (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
1138
+ #endif
1139
+ back->index > png_ptr->num_palette)
1140
+ {
1141
+ png_warning(png_ptr, "Invalid background palette index");
1142
+ return;
1143
+ }
1144
+ buf[0] = back->index;
1145
+ png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
1146
+ }
1147
+ else if (color_type & PNG_COLOR_MASK_COLOR)
1148
+ {
1149
+ png_save_uint_16(buf, back->red);
1150
+ png_save_uint_16(buf + 2, back->green);
1151
+ png_save_uint_16(buf + 4, back->blue);
1152
+ if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1153
+ {
1154
+ png_warning(png_ptr,
1155
+ "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
1156
+ return;
1157
+ }
1158
+ png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
1159
+ }
1160
+ else
1161
+ {
1162
+ if(back->gray >= (1 << png_ptr->bit_depth))
1163
+ {
1164
+ png_warning(png_ptr,
1165
+ "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
1166
+ return;
1167
+ }
1168
+ png_save_uint_16(buf, back->gray);
1169
+ png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
1170
+ }
1171
+ }
1172
+ #endif
1173
+
1174
+ #if defined(PNG_WRITE_hIST_SUPPORTED)
1175
+ /* write the histogram */
1176
+ void /* PRIVATE */
1177
+ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
1178
+ {
1179
+ #ifdef PNG_USE_LOCAL_ARRAYS
1180
+ PNG_hIST;
1181
+ #endif
1182
+ int i;
1183
+ png_byte buf[3];
1184
+
1185
+ png_debug(1, "in png_write_hIST\n");
1186
+ if (num_hist > (int)png_ptr->num_palette)
1187
+ {
1188
+ png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
1189
+ png_ptr->num_palette);
1190
+ png_warning(png_ptr, "Invalid number of histogram entries specified");
1191
+ return;
1192
+ }
1193
+
1194
+ png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
1195
+ for (i = 0; i < num_hist; i++)
1196
+ {
1197
+ png_save_uint_16(buf, hist[i]);
1198
+ png_write_chunk_data(png_ptr, buf, (png_size_t)2);
1199
+ }
1200
+ png_write_chunk_end(png_ptr);
1201
+ }
1202
+ #endif
1203
+
1204
+ #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
1205
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
1206
+ /* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
1207
+ * and if invalid, correct the keyword rather than discarding the entire
1208
+ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
1209
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
1210
+ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
1211
+ *
1212
+ * The new_key is allocated to hold the corrected keyword and must be freed
1213
+ * by the calling routine. This avoids problems with trying to write to
1214
+ * static keywords without having to have duplicate copies of the strings.
1215
+ */
1216
+ png_size_t /* PRIVATE */
1217
+ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
1218
+ {
1219
+ png_size_t key_len;
1220
+ png_charp kp, dp;
1221
+ int kflag;
1222
+ int kwarn=0;
1223
+
1224
+ png_debug(1, "in png_check_keyword\n");
1225
+ *new_key = NULL;
1226
+
1227
+ if (key == NULL || (key_len = png_strlen(key)) == 0)
1228
+ {
1229
+ png_warning(png_ptr, "zero length keyword");
1230
+ return ((png_size_t)0);
1231
+ }
1232
+
1233
+ png_debug1(2, "Keyword to be checked is '%s'\n", key);
1234
+
1235
+ *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2));
1236
+ if (*new_key == NULL)
1237
+ {
1238
+ png_warning(png_ptr, "Out of memory while procesing keyword");
1239
+ return ((png_size_t)0);
1240
+ }
1241
+
1242
+ /* Replace non-printing characters with a blank and print a warning */
1243
+ for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
1244
+ {
1245
+ if ((png_byte)*kp < 0x20 ||
1246
+ ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1))
1247
+ {
1248
+ #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1249
+ char msg[40];
1250
+
1251
+ png_snprintf(msg, 40,
1252
+ "invalid keyword character 0x%02X", (png_byte)*kp);
1253
+ png_warning(png_ptr, msg);
1254
+ #else
1255
+ png_warning(png_ptr, "invalid character in keyword");
1256
+ #endif
1257
+ *dp = ' ';
1258
+ }
1259
+ else
1260
+ {
1261
+ *dp = *kp;
1262
+ }
1263
+ }
1264
+ *dp = '\0';
1265
+
1266
+ /* Remove any trailing white space. */
1267
+ kp = *new_key + key_len - 1;
1268
+ if (*kp == ' ')
1269
+ {
1270
+ png_warning(png_ptr, "trailing spaces removed from keyword");
1271
+
1272
+ while (*kp == ' ')
1273
+ {
1274
+ *(kp--) = '\0';
1275
+ key_len--;
1276
+ }
1277
+ }
1278
+
1279
+ /* Remove any leading white space. */
1280
+ kp = *new_key;
1281
+ if (*kp == ' ')
1282
+ {
1283
+ png_warning(png_ptr, "leading spaces removed from keyword");
1284
+
1285
+ while (*kp == ' ')
1286
+ {
1287
+ kp++;
1288
+ key_len--;
1289
+ }
1290
+ }
1291
+
1292
+ png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
1293
+
1294
+ /* Remove multiple internal spaces. */
1295
+ for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
1296
+ {
1297
+ if (*kp == ' ' && kflag == 0)
1298
+ {
1299
+ *(dp++) = *kp;
1300
+ kflag = 1;
1301
+ }
1302
+ else if (*kp == ' ')
1303
+ {
1304
+ key_len--;
1305
+ kwarn=1;
1306
+ }
1307
+ else
1308
+ {
1309
+ *(dp++) = *kp;
1310
+ kflag = 0;
1311
+ }
1312
+ }
1313
+ *dp = '\0';
1314
+ if(kwarn)
1315
+ png_warning(png_ptr, "extra interior spaces removed from keyword");
1316
+
1317
+ if (key_len == 0)
1318
+ {
1319
+ png_free(png_ptr, *new_key);
1320
+ *new_key=NULL;
1321
+ png_warning(png_ptr, "Zero length keyword");
1322
+ }
1323
+
1324
+ if (key_len > 79)
1325
+ {
1326
+ png_warning(png_ptr, "keyword length must be 1 - 79 characters");
1327
+ new_key[79] = '\0';
1328
+ key_len = 79;
1329
+ }
1330
+
1331
+ return (key_len);
1332
+ }
1333
+ #endif
1334
+
1335
+ #if defined(PNG_WRITE_tEXt_SUPPORTED)
1336
+ /* write a tEXt chunk */
1337
+ void /* PRIVATE */
1338
+ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
1339
+ png_size_t text_len)
1340
+ {
1341
+ #ifdef PNG_USE_LOCAL_ARRAYS
1342
+ PNG_tEXt;
1343
+ #endif
1344
+ png_size_t key_len;
1345
+ png_charp new_key;
1346
+
1347
+ png_debug(1, "in png_write_tEXt\n");
1348
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
1349
+ {
1350
+ png_warning(png_ptr, "Empty keyword in tEXt chunk");
1351
+ return;
1352
+ }
1353
+
1354
+ if (text == NULL || *text == '\0')
1355
+ text_len = 0;
1356
+ else
1357
+ text_len = png_strlen(text);
1358
+
1359
+ /* make sure we include the 0 after the key */
1360
+ png_write_chunk_start(png_ptr, png_tEXt, (png_uint_32)key_len+text_len+1);
1361
+ /*
1362
+ * We leave it to the application to meet PNG-1.0 requirements on the
1363
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
1364
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
1365
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1366
+ */
1367
+ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
1368
+ if (text_len)
1369
+ png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
1370
+
1371
+ png_write_chunk_end(png_ptr);
1372
+ png_free(png_ptr, new_key);
1373
+ }
1374
+ #endif
1375
+
1376
+ #if defined(PNG_WRITE_zTXt_SUPPORTED)
1377
+ /* write a compressed text chunk */
1378
+ void /* PRIVATE */
1379
+ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
1380
+ png_size_t text_len, int compression)
1381
+ {
1382
+ #ifdef PNG_USE_LOCAL_ARRAYS
1383
+ PNG_zTXt;
1384
+ #endif
1385
+ png_size_t key_len;
1386
+ char buf[1];
1387
+ png_charp new_key;
1388
+ compression_state comp;
1389
+
1390
+ png_debug(1, "in png_write_zTXt\n");
1391
+
1392
+ comp.num_output_ptr = 0;
1393
+ comp.max_output_ptr = 0;
1394
+ comp.output_ptr = NULL;
1395
+ comp.input = NULL;
1396
+ comp.input_len = 0;
1397
+
1398
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
1399
+ {
1400
+ png_warning(png_ptr, "Empty keyword in zTXt chunk");
1401
+ return;
1402
+ }
1403
+
1404
+ if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
1405
+ {
1406
+ png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
1407
+ png_free(png_ptr, new_key);
1408
+ return;
1409
+ }
1410
+
1411
+ text_len = png_strlen(text);
1412
+
1413
+ /* compute the compressed data; do it now for the length */
1414
+ text_len = png_text_compress(png_ptr, text, text_len, compression,
1415
+ &comp);
1416
+
1417
+ /* write start of chunk */
1418
+ png_write_chunk_start(png_ptr, png_zTXt, (png_uint_32)
1419
+ (key_len+text_len+2));
1420
+ /* write key */
1421
+ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
1422
+ png_free(png_ptr, new_key);
1423
+
1424
+ buf[0] = (png_byte)compression;
1425
+ /* write compression */
1426
+ png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
1427
+ /* write the compressed data */
1428
+ png_write_compressed_data_out(png_ptr, &comp);
1429
+
1430
+ /* close the chunk */
1431
+ png_write_chunk_end(png_ptr);
1432
+ }
1433
+ #endif
1434
+
1435
+ #if defined(PNG_WRITE_iTXt_SUPPORTED)
1436
+ /* write an iTXt chunk */
1437
+ void /* PRIVATE */
1438
+ png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
1439
+ png_charp lang, png_charp lang_key, png_charp text)
1440
+ {
1441
+ #ifdef PNG_USE_LOCAL_ARRAYS
1442
+ PNG_iTXt;
1443
+ #endif
1444
+ png_size_t lang_len, key_len, lang_key_len, text_len;
1445
+ png_charp new_lang, new_key;
1446
+ png_byte cbuf[2];
1447
+ compression_state comp;
1448
+
1449
+ png_debug(1, "in png_write_iTXt\n");
1450
+
1451
+ comp.num_output_ptr = 0;
1452
+ comp.max_output_ptr = 0;
1453
+ comp.output_ptr = NULL;
1454
+ comp.input = NULL;
1455
+
1456
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
1457
+ {
1458
+ png_warning(png_ptr, "Empty keyword in iTXt chunk");
1459
+ return;
1460
+ }
1461
+ if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
1462
+ {
1463
+ png_warning(png_ptr, "Empty language field in iTXt chunk");
1464
+ new_lang = NULL;
1465
+ lang_len = 0;
1466
+ }
1467
+
1468
+ if (lang_key == NULL)
1469
+ lang_key_len = 0;
1470
+ else
1471
+ lang_key_len = png_strlen(lang_key);
1472
+
1473
+ if (text == NULL)
1474
+ text_len = 0;
1475
+ else
1476
+ text_len = png_strlen(text);
1477
+
1478
+ /* compute the compressed data; do it now for the length */
1479
+ text_len = png_text_compress(png_ptr, text, text_len, compression-2,
1480
+ &comp);
1481
+
1482
+
1483
+ /* make sure we include the compression flag, the compression byte,
1484
+ * and the NULs after the key, lang, and lang_key parts */
1485
+
1486
+ png_write_chunk_start(png_ptr, png_iTXt,
1487
+ (png_uint_32)(
1488
+ 5 /* comp byte, comp flag, terminators for key, lang and lang_key */
1489
+ + key_len
1490
+ + lang_len
1491
+ + lang_key_len
1492
+ + text_len));
1493
+
1494
+ /*
1495
+ * We leave it to the application to meet PNG-1.0 requirements on the
1496
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
1497
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
1498
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1499
+ */
1500
+ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
1501
+
1502
+ /* set the compression flag */
1503
+ if (compression == PNG_ITXT_COMPRESSION_NONE || \
1504
+ compression == PNG_TEXT_COMPRESSION_NONE)
1505
+ cbuf[0] = 0;
1506
+ else /* compression == PNG_ITXT_COMPRESSION_zTXt */
1507
+ cbuf[0] = 1;
1508
+ /* set the compression method */
1509
+ cbuf[1] = 0;
1510
+ png_write_chunk_data(png_ptr, cbuf, 2);
1511
+
1512
+ cbuf[0] = 0;
1513
+ png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1);
1514
+ png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1);
1515
+ png_write_compressed_data_out(png_ptr, &comp);
1516
+
1517
+ png_write_chunk_end(png_ptr);
1518
+ png_free(png_ptr, new_key);
1519
+ png_free(png_ptr, new_lang);
1520
+ }
1521
+ #endif
1522
+
1523
+ #if defined(PNG_WRITE_oFFs_SUPPORTED)
1524
+ /* write the oFFs chunk */
1525
+ void /* PRIVATE */
1526
+ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
1527
+ int unit_type)
1528
+ {
1529
+ #ifdef PNG_USE_LOCAL_ARRAYS
1530
+ PNG_oFFs;
1531
+ #endif
1532
+ png_byte buf[9];
1533
+
1534
+ png_debug(1, "in png_write_oFFs\n");
1535
+ if (unit_type >= PNG_OFFSET_LAST)
1536
+ png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
1537
+
1538
+ png_save_int_32(buf, x_offset);
1539
+ png_save_int_32(buf + 4, y_offset);
1540
+ buf[8] = (png_byte)unit_type;
1541
+
1542
+ png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
1543
+ }
1544
+ #endif
1545
+ #if defined(PNG_WRITE_pCAL_SUPPORTED)
1546
+ /* write the pCAL chunk (described in the PNG extensions document) */
1547
+ void /* PRIVATE */
1548
+ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
1549
+ png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
1550
+ {
1551
+ #ifdef PNG_USE_LOCAL_ARRAYS
1552
+ PNG_pCAL;
1553
+ #endif
1554
+ png_size_t purpose_len, units_len, total_len;
1555
+ png_uint_32p params_len;
1556
+ png_byte buf[10];
1557
+ png_charp new_purpose;
1558
+ int i;
1559
+
1560
+ png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
1561
+ if (type >= PNG_EQUATION_LAST)
1562
+ png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1563
+
1564
+ purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
1565
+ png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len);
1566
+ units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
1567
+ png_debug1(3, "pCAL units length = %d\n", (int)units_len);
1568
+ total_len = purpose_len + units_len + 10;
1569
+
1570
+ params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
1571
+ *png_sizeof(png_uint_32)));
1572
+
1573
+ /* Find the length of each parameter, making sure we don't count the
1574
+ null terminator for the last parameter. */
1575
+ for (i = 0; i < nparams; i++)
1576
+ {
1577
+ params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
1578
+ png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]);
1579
+ total_len += (png_size_t)params_len[i];
1580
+ }
1581
+
1582
+ png_debug1(3, "pCAL total length = %d\n", (int)total_len);
1583
+ png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
1584
+ png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
1585
+ png_save_int_32(buf, X0);
1586
+ png_save_int_32(buf + 4, X1);
1587
+ buf[8] = (png_byte)type;
1588
+ buf[9] = (png_byte)nparams;
1589
+ png_write_chunk_data(png_ptr, buf, (png_size_t)10);
1590
+ png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
1591
+
1592
+ png_free(png_ptr, new_purpose);
1593
+
1594
+ for (i = 0; i < nparams; i++)
1595
+ {
1596
+ png_write_chunk_data(png_ptr, (png_bytep)params[i],
1597
+ (png_size_t)params_len[i]);
1598
+ }
1599
+
1600
+ png_free(png_ptr, params_len);
1601
+ png_write_chunk_end(png_ptr);
1602
+ }
1603
+ #endif
1604
+
1605
+ #if defined(PNG_WRITE_sCAL_SUPPORTED)
1606
+ /* write the sCAL chunk */
1607
+ #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
1608
+ void /* PRIVATE */
1609
+ png_write_sCAL(png_structp png_ptr, int unit, double width, double height)
1610
+ {
1611
+ #ifdef PNG_USE_LOCAL_ARRAYS
1612
+ PNG_sCAL;
1613
+ #endif
1614
+ char buf[64];
1615
+ png_size_t total_len;
1616
+
1617
+ png_debug(1, "in png_write_sCAL\n");
1618
+
1619
+ buf[0] = (char)unit;
1620
+ #if defined(_WIN32_WCE)
1621
+ /* sprintf() function is not supported on WindowsCE */
1622
+ {
1623
+ wchar_t wc_buf[32];
1624
+ size_t wc_len;
1625
+ swprintf(wc_buf, TEXT("%12.12e"), width);
1626
+ wc_len = wcslen(wc_buf);
1627
+ WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL);
1628
+ total_len = wc_len + 2;
1629
+ swprintf(wc_buf, TEXT("%12.12e"), height);
1630
+ wc_len = wcslen(wc_buf);
1631
+ WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len,
1632
+ NULL, NULL);
1633
+ total_len += wc_len;
1634
+ }
1635
+ #else
1636
+ png_snprintf(buf + 1, 63, "%12.12e", width);
1637
+ total_len = 1 + png_strlen(buf + 1) + 1;
1638
+ png_snprintf(buf + total_len, 64-total_len, "%12.12e", height);
1639
+ total_len += png_strlen(buf + total_len);
1640
+ #endif
1641
+
1642
+ png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
1643
+ png_write_chunk(png_ptr, png_sCAL, (png_bytep)buf, total_len);
1644
+ }
1645
+ #else
1646
+ #ifdef PNG_FIXED_POINT_SUPPORTED
1647
+ void /* PRIVATE */
1648
+ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
1649
+ png_charp height)
1650
+ {
1651
+ #ifdef PNG_USE_LOCAL_ARRAYS
1652
+ PNG_sCAL;
1653
+ #endif
1654
+ png_byte buf[64];
1655
+ png_size_t wlen, hlen, total_len;
1656
+
1657
+ png_debug(1, "in png_write_sCAL_s\n");
1658
+
1659
+ wlen = png_strlen(width);
1660
+ hlen = png_strlen(height);
1661
+ total_len = wlen + hlen + 2;
1662
+ if (total_len > 64)
1663
+ {
1664
+ png_warning(png_ptr, "Can't write sCAL (buffer too small)");
1665
+ return;
1666
+ }
1667
+
1668
+ buf[0] = (png_byte)unit;
1669
+ png_memcpy(buf + 1, width, wlen + 1); /* append the '\0' here */
1670
+ png_memcpy(buf + wlen + 2, height, hlen); /* do NOT append the '\0' here */
1671
+
1672
+ png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len);
1673
+ png_write_chunk(png_ptr, png_sCAL, buf, total_len);
1674
+ }
1675
+ #endif
1676
+ #endif
1677
+ #endif
1678
+
1679
+ #if defined(PNG_WRITE_pHYs_SUPPORTED)
1680
+ /* write the pHYs chunk */
1681
+ void /* PRIVATE */
1682
+ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
1683
+ png_uint_32 y_pixels_per_unit,
1684
+ int unit_type)
1685
+ {
1686
+ #ifdef PNG_USE_LOCAL_ARRAYS
1687
+ PNG_pHYs;
1688
+ #endif
1689
+ png_byte buf[9];
1690
+
1691
+ png_debug(1, "in png_write_pHYs\n");
1692
+ if (unit_type >= PNG_RESOLUTION_LAST)
1693
+ png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
1694
+
1695
+ png_save_uint_32(buf, x_pixels_per_unit);
1696
+ png_save_uint_32(buf + 4, y_pixels_per_unit);
1697
+ buf[8] = (png_byte)unit_type;
1698
+
1699
+ png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
1700
+ }
1701
+ #endif
1702
+
1703
+ #if defined(PNG_WRITE_tIME_SUPPORTED)
1704
+ /* Write the tIME chunk. Use either png_convert_from_struct_tm()
1705
+ * or png_convert_from_time_t(), or fill in the structure yourself.
1706
+ */
1707
+ void /* PRIVATE */
1708
+ png_write_tIME(png_structp png_ptr, png_timep mod_time)
1709
+ {
1710
+ #ifdef PNG_USE_LOCAL_ARRAYS
1711
+ PNG_tIME;
1712
+ #endif
1713
+ png_byte buf[7];
1714
+
1715
+ png_debug(1, "in png_write_tIME\n");
1716
+ if (mod_time->month > 12 || mod_time->month < 1 ||
1717
+ mod_time->day > 31 || mod_time->day < 1 ||
1718
+ mod_time->hour > 23 || mod_time->second > 60)
1719
+ {
1720
+ png_warning(png_ptr, "Invalid time specified for tIME chunk");
1721
+ return;
1722
+ }
1723
+
1724
+ png_save_uint_16(buf, mod_time->year);
1725
+ buf[2] = mod_time->month;
1726
+ buf[3] = mod_time->day;
1727
+ buf[4] = mod_time->hour;
1728
+ buf[5] = mod_time->minute;
1729
+ buf[6] = mod_time->second;
1730
+
1731
+ png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
1732
+ }
1733
+ #endif
1734
+
1735
+ /* initializes the row writing capability of libpng */
1736
+ void /* PRIVATE */
1737
+ png_write_start_row(png_structp png_ptr)
1738
+ {
1739
+ #ifdef PNG_WRITE_INTERLACING_SUPPORTED
1740
+ #ifdef PNG_USE_LOCAL_ARRAYS
1741
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1742
+
1743
+ /* start of interlace block */
1744
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1745
+
1746
+ /* offset to next interlace block */
1747
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1748
+
1749
+ /* start of interlace block in the y direction */
1750
+ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
1751
+
1752
+ /* offset to next interlace block in the y direction */
1753
+ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
1754
+ #endif
1755
+ #endif
1756
+
1757
+ png_size_t buf_size;
1758
+
1759
+ png_debug(1, "in png_write_start_row\n");
1760
+ buf_size = (png_size_t)(PNG_ROWBYTES(
1761
+ png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1);
1762
+
1763
+ /* set up row buffer */
1764
+ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
1765
+ png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
1766
+
1767
+ #ifndef PNG_NO_WRITE_FILTERING
1768
+ /* set up filtering buffer, if using this filter */
1769
+ if (png_ptr->do_filter & PNG_FILTER_SUB)
1770
+ {
1771
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
1772
+ (png_ptr->rowbytes + 1));
1773
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
1774
+ }
1775
+
1776
+ /* We only need to keep the previous row if we are using one of these. */
1777
+ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
1778
+ {
1779
+ /* set up previous row buffer */
1780
+ png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
1781
+ png_memset(png_ptr->prev_row, 0, buf_size);
1782
+
1783
+ if (png_ptr->do_filter & PNG_FILTER_UP)
1784
+ {
1785
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
1786
+ (png_ptr->rowbytes + 1));
1787
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
1788
+ }
1789
+
1790
+ if (png_ptr->do_filter & PNG_FILTER_AVG)
1791
+ {
1792
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
1793
+ (png_ptr->rowbytes + 1));
1794
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
1795
+ }
1796
+
1797
+ if (png_ptr->do_filter & PNG_FILTER_PAETH)
1798
+ {
1799
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
1800
+ (png_ptr->rowbytes + 1));
1801
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
1802
+ }
1803
+ #endif /* PNG_NO_WRITE_FILTERING */
1804
+ }
1805
+
1806
+ #ifdef PNG_WRITE_INTERLACING_SUPPORTED
1807
+ /* if interlaced, we need to set up width and height of pass */
1808
+ if (png_ptr->interlaced)
1809
+ {
1810
+ if (!(png_ptr->transformations & PNG_INTERLACE))
1811
+ {
1812
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
1813
+ png_pass_ystart[0]) / png_pass_yinc[0];
1814
+ png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
1815
+ png_pass_start[0]) / png_pass_inc[0];
1816
+ }
1817
+ else
1818
+ {
1819
+ png_ptr->num_rows = png_ptr->height;
1820
+ png_ptr->usr_width = png_ptr->width;
1821
+ }
1822
+ }
1823
+ else
1824
+ #endif
1825
+ {
1826
+ png_ptr->num_rows = png_ptr->height;
1827
+ png_ptr->usr_width = png_ptr->width;
1828
+ }
1829
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1830
+ png_ptr->zstream.next_out = png_ptr->zbuf;
1831
+ }
1832
+
1833
+ /* Internal use only. Called when finished processing a row of data. */
1834
+ void /* PRIVATE */
1835
+ png_write_finish_row(png_structp png_ptr)
1836
+ {
1837
+ #ifdef PNG_WRITE_INTERLACING_SUPPORTED
1838
+ #ifdef PNG_USE_LOCAL_ARRAYS
1839
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1840
+
1841
+ /* start of interlace block */
1842
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1843
+
1844
+ /* offset to next interlace block */
1845
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1846
+
1847
+ /* start of interlace block in the y direction */
1848
+ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
1849
+
1850
+ /* offset to next interlace block in the y direction */
1851
+ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
1852
+ #endif
1853
+ #endif
1854
+
1855
+ int ret;
1856
+
1857
+ png_debug(1, "in png_write_finish_row\n");
1858
+ /* next row */
1859
+ png_ptr->row_number++;
1860
+
1861
+ /* see if we are done */
1862
+ if (png_ptr->row_number < png_ptr->num_rows)
1863
+ return;
1864
+
1865
+ #ifdef PNG_WRITE_INTERLACING_SUPPORTED
1866
+ /* if interlaced, go to next pass */
1867
+ if (png_ptr->interlaced)
1868
+ {
1869
+ png_ptr->row_number = 0;
1870
+ if (png_ptr->transformations & PNG_INTERLACE)
1871
+ {
1872
+ png_ptr->pass++;
1873
+ }
1874
+ else
1875
+ {
1876
+ /* loop until we find a non-zero width or height pass */
1877
+ do
1878
+ {
1879
+ png_ptr->pass++;
1880
+ if (png_ptr->pass >= 7)
1881
+ break;
1882
+ png_ptr->usr_width = (png_ptr->width +
1883
+ png_pass_inc[png_ptr->pass] - 1 -
1884
+ png_pass_start[png_ptr->pass]) /
1885
+ png_pass_inc[png_ptr->pass];
1886
+ png_ptr->num_rows = (png_ptr->height +
1887
+ png_pass_yinc[png_ptr->pass] - 1 -
1888
+ png_pass_ystart[png_ptr->pass]) /
1889
+ png_pass_yinc[png_ptr->pass];
1890
+ if (png_ptr->transformations & PNG_INTERLACE)
1891
+ break;
1892
+ } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
1893
+
1894
+ }
1895
+
1896
+ /* reset the row above the image for the next pass */
1897
+ if (png_ptr->pass < 7)
1898
+ {
1899
+ if (png_ptr->prev_row != NULL)
1900
+ png_memset(png_ptr->prev_row, 0,
1901
+ (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
1902
+ png_ptr->usr_bit_depth,png_ptr->width))+1);
1903
+ return;
1904
+ }
1905
+ }
1906
+ #endif
1907
+
1908
+ /* if we get here, we've just written the last row, so we need
1909
+ to flush the compressor */
1910
+ do
1911
+ {
1912
+ /* tell the compressor we are done */
1913
+ ret = deflate(&png_ptr->zstream, Z_FINISH);
1914
+ /* check for an error */
1915
+ if (ret == Z_OK)
1916
+ {
1917
+ /* check to see if we need more room */
1918
+ if (!(png_ptr->zstream.avail_out))
1919
+ {
1920
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
1921
+ png_ptr->zstream.next_out = png_ptr->zbuf;
1922
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1923
+ }
1924
+ }
1925
+ else if (ret != Z_STREAM_END)
1926
+ {
1927
+ if (png_ptr->zstream.msg != NULL)
1928
+ png_error(png_ptr, png_ptr->zstream.msg);
1929
+ else
1930
+ png_error(png_ptr, "zlib error");
1931
+ }
1932
+ } while (ret != Z_STREAM_END);
1933
+
1934
+ /* write any extra space */
1935
+ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
1936
+ {
1937
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
1938
+ png_ptr->zstream.avail_out);
1939
+ }
1940
+
1941
+ deflateReset(&png_ptr->zstream);
1942
+ png_ptr->zstream.data_type = Z_BINARY;
1943
+ }
1944
+
1945
+ #if defined(PNG_WRITE_INTERLACING_SUPPORTED)
1946
+ /* Pick out the correct pixels for the interlace pass.
1947
+ * The basic idea here is to go through the row with a source
1948
+ * pointer and a destination pointer (sp and dp), and copy the
1949
+ * correct pixels for the pass. As the row gets compacted,
1950
+ * sp will always be >= dp, so we should never overwrite anything.
1951
+ * See the default: case for the easiest code to understand.
1952
+ */
1953
+ void /* PRIVATE */
1954
+ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
1955
+ {
1956
+ #ifdef PNG_USE_LOCAL_ARRAYS
1957
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1958
+
1959
+ /* start of interlace block */
1960
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1961
+
1962
+ /* offset to next interlace block */
1963
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1964
+ #endif
1965
+
1966
+ png_debug(1, "in png_do_write_interlace\n");
1967
+ /* we don't have to do anything on the last pass (6) */
1968
+ #if defined(PNG_USELESS_TESTS_SUPPORTED)
1969
+ if (row != NULL && row_info != NULL && pass < 6)
1970
+ #else
1971
+ if (pass < 6)
1972
+ #endif
1973
+ {
1974
+ /* each pixel depth is handled separately */
1975
+ switch (row_info->pixel_depth)
1976
+ {
1977
+ case 1:
1978
+ {
1979
+ png_bytep sp;
1980
+ png_bytep dp;
1981
+ int shift;
1982
+ int d;
1983
+ int value;
1984
+ png_uint_32 i;
1985
+ png_uint_32 row_width = row_info->width;
1986
+
1987
+ dp = row;
1988
+ d = 0;
1989
+ shift = 7;
1990
+ for (i = png_pass_start[pass]; i < row_width;
1991
+ i += png_pass_inc[pass])
1992
+ {
1993
+ sp = row + (png_size_t)(i >> 3);
1994
+ value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
1995
+ d |= (value << shift);
1996
+
1997
+ if (shift == 0)
1998
+ {
1999
+ shift = 7;
2000
+ *dp++ = (png_byte)d;
2001
+ d = 0;
2002
+ }
2003
+ else
2004
+ shift--;
2005
+
2006
+ }
2007
+ if (shift != 7)
2008
+ *dp = (png_byte)d;
2009
+ break;
2010
+ }
2011
+ case 2:
2012
+ {
2013
+ png_bytep sp;
2014
+ png_bytep dp;
2015
+ int shift;
2016
+ int d;
2017
+ int value;
2018
+ png_uint_32 i;
2019
+ png_uint_32 row_width = row_info->width;
2020
+
2021
+ dp = row;
2022
+ shift = 6;
2023
+ d = 0;
2024
+ for (i = png_pass_start[pass]; i < row_width;
2025
+ i += png_pass_inc[pass])
2026
+ {
2027
+ sp = row + (png_size_t)(i >> 2);
2028
+ value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
2029
+ d |= (value << shift);
2030
+
2031
+ if (shift == 0)
2032
+ {
2033
+ shift = 6;
2034
+ *dp++ = (png_byte)d;
2035
+ d = 0;
2036
+ }
2037
+ else
2038
+ shift -= 2;
2039
+ }
2040
+ if (shift != 6)
2041
+ *dp = (png_byte)d;
2042
+ break;
2043
+ }
2044
+ case 4:
2045
+ {
2046
+ png_bytep sp;
2047
+ png_bytep dp;
2048
+ int shift;
2049
+ int d;
2050
+ int value;
2051
+ png_uint_32 i;
2052
+ png_uint_32 row_width = row_info->width;
2053
+
2054
+ dp = row;
2055
+ shift = 4;
2056
+ d = 0;
2057
+ for (i = png_pass_start[pass]; i < row_width;
2058
+ i += png_pass_inc[pass])
2059
+ {
2060
+ sp = row + (png_size_t)(i >> 1);
2061
+ value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
2062
+ d |= (value << shift);
2063
+
2064
+ if (shift == 0)
2065
+ {
2066
+ shift = 4;
2067
+ *dp++ = (png_byte)d;
2068
+ d = 0;
2069
+ }
2070
+ else
2071
+ shift -= 4;
2072
+ }
2073
+ if (shift != 4)
2074
+ *dp = (png_byte)d;
2075
+ break;
2076
+ }
2077
+ default:
2078
+ {
2079
+ png_bytep sp;
2080
+ png_bytep dp;
2081
+ png_uint_32 i;
2082
+ png_uint_32 row_width = row_info->width;
2083
+ png_size_t pixel_bytes;
2084
+
2085
+ /* start at the beginning */
2086
+ dp = row;
2087
+ /* find out how many bytes each pixel takes up */
2088
+ pixel_bytes = (row_info->pixel_depth >> 3);
2089
+ /* loop through the row, only looking at the pixels that
2090
+ matter */
2091
+ for (i = png_pass_start[pass]; i < row_width;
2092
+ i += png_pass_inc[pass])
2093
+ {
2094
+ /* find out where the original pixel is */
2095
+ sp = row + (png_size_t)i * pixel_bytes;
2096
+ /* move the pixel */
2097
+ if (dp != sp)
2098
+ png_memcpy(dp, sp, pixel_bytes);
2099
+ /* next pixel */
2100
+ dp += pixel_bytes;
2101
+ }
2102
+ break;
2103
+ }
2104
+ }
2105
+ /* set new row width */
2106
+ row_info->width = (row_info->width +
2107
+ png_pass_inc[pass] - 1 -
2108
+ png_pass_start[pass]) /
2109
+ png_pass_inc[pass];
2110
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
2111
+ row_info->width);
2112
+ }
2113
+ }
2114
+ #endif
2115
+
2116
+ /* This filters the row, chooses which filter to use, if it has not already
2117
+ * been specified by the application, and then writes the row out with the
2118
+ * chosen filter.
2119
+ */
2120
+ #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
2121
+ #define PNG_HISHIFT 10
2122
+ #define PNG_LOMASK ((png_uint_32)0xffffL)
2123
+ #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
2124
+ void /* PRIVATE */
2125
+ png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
2126
+ {
2127
+ png_bytep best_row;
2128
+ #ifndef PNG_NO_WRITE_FILTER
2129
+ png_bytep prev_row, row_buf;
2130
+ png_uint_32 mins, bpp;
2131
+ png_byte filter_to_do = png_ptr->do_filter;
2132
+ png_uint_32 row_bytes = row_info->rowbytes;
2133
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2134
+ int num_p_filters = (int)png_ptr->num_prev_filters;
2135
+ #endif
2136
+
2137
+ png_debug(1, "in png_write_find_filter\n");
2138
+ /* find out how many bytes offset each pixel is */
2139
+ bpp = (row_info->pixel_depth + 7) >> 3;
2140
+
2141
+ prev_row = png_ptr->prev_row;
2142
+ #endif
2143
+ best_row = png_ptr->row_buf;
2144
+ #ifndef PNG_NO_WRITE_FILTER
2145
+ row_buf = best_row;
2146
+ mins = PNG_MAXSUM;
2147
+
2148
+ /* The prediction method we use is to find which method provides the
2149
+ * smallest value when summing the absolute values of the distances
2150
+ * from zero, using anything >= 128 as negative numbers. This is known
2151
+ * as the "minimum sum of absolute differences" heuristic. Other
2152
+ * heuristics are the "weighted minimum sum of absolute differences"
2153
+ * (experimental and can in theory improve compression), and the "zlib
2154
+ * predictive" method (not implemented yet), which does test compressions
2155
+ * of lines using different filter methods, and then chooses the
2156
+ * (series of) filter(s) that give minimum compressed data size (VERY
2157
+ * computationally expensive).
2158
+ *
2159
+ * GRR 980525: consider also
2160
+ * (1) minimum sum of absolute differences from running average (i.e.,
2161
+ * keep running sum of non-absolute differences & count of bytes)
2162
+ * [track dispersion, too? restart average if dispersion too large?]
2163
+ * (1b) minimum sum of absolute differences from sliding average, probably
2164
+ * with window size <= deflate window (usually 32K)
2165
+ * (2) minimum sum of squared differences from zero or running average
2166
+ * (i.e., ~ root-mean-square approach)
2167
+ */
2168
+
2169
+
2170
+ /* We don't need to test the 'no filter' case if this is the only filter
2171
+ * that has been chosen, as it doesn't actually do anything to the data.
2172
+ */
2173
+ if ((filter_to_do & PNG_FILTER_NONE) &&
2174
+ filter_to_do != PNG_FILTER_NONE)
2175
+ {
2176
+ png_bytep rp;
2177
+ png_uint_32 sum = 0;
2178
+ png_uint_32 i;
2179
+ int v;
2180
+
2181
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
2182
+ {
2183
+ v = *rp;
2184
+ sum += (v < 128) ? v : 256 - v;
2185
+ }
2186
+
2187
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2188
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2189
+ {
2190
+ png_uint_32 sumhi, sumlo;
2191
+ int j;
2192
+ sumlo = sum & PNG_LOMASK;
2193
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
2194
+
2195
+ /* Reduce the sum if we match any of the previous rows */
2196
+ for (j = 0; j < num_p_filters; j++)
2197
+ {
2198
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
2199
+ {
2200
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2201
+ PNG_WEIGHT_SHIFT;
2202
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2203
+ PNG_WEIGHT_SHIFT;
2204
+ }
2205
+ }
2206
+
2207
+ /* Factor in the cost of this filter (this is here for completeness,
2208
+ * but it makes no sense to have a "cost" for the NONE filter, as
2209
+ * it has the minimum possible computational cost - none).
2210
+ */
2211
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2212
+ PNG_COST_SHIFT;
2213
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2214
+ PNG_COST_SHIFT;
2215
+
2216
+ if (sumhi > PNG_HIMASK)
2217
+ sum = PNG_MAXSUM;
2218
+ else
2219
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
2220
+ }
2221
+ #endif
2222
+ mins = sum;
2223
+ }
2224
+
2225
+ /* sub filter */
2226
+ if (filter_to_do == PNG_FILTER_SUB)
2227
+ /* it's the only filter so no testing is needed */
2228
+ {
2229
+ png_bytep rp, lp, dp;
2230
+ png_uint_32 i;
2231
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
2232
+ i++, rp++, dp++)
2233
+ {
2234
+ *dp = *rp;
2235
+ }
2236
+ for (lp = row_buf + 1; i < row_bytes;
2237
+ i++, rp++, lp++, dp++)
2238
+ {
2239
+ *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2240
+ }
2241
+ best_row = png_ptr->sub_row;
2242
+ }
2243
+
2244
+ else if (filter_to_do & PNG_FILTER_SUB)
2245
+ {
2246
+ png_bytep rp, dp, lp;
2247
+ png_uint_32 sum = 0, lmins = mins;
2248
+ png_uint_32 i;
2249
+ int v;
2250
+
2251
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2252
+ /* We temporarily increase the "minimum sum" by the factor we
2253
+ * would reduce the sum of this filter, so that we can do the
2254
+ * early exit comparison without scaling the sum each time.
2255
+ */
2256
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2257
+ {
2258
+ int j;
2259
+ png_uint_32 lmhi, lmlo;
2260
+ lmlo = lmins & PNG_LOMASK;
2261
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2262
+
2263
+ for (j = 0; j < num_p_filters; j++)
2264
+ {
2265
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
2266
+ {
2267
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2268
+ PNG_WEIGHT_SHIFT;
2269
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2270
+ PNG_WEIGHT_SHIFT;
2271
+ }
2272
+ }
2273
+
2274
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2275
+ PNG_COST_SHIFT;
2276
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2277
+ PNG_COST_SHIFT;
2278
+
2279
+ if (lmhi > PNG_HIMASK)
2280
+ lmins = PNG_MAXSUM;
2281
+ else
2282
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
2283
+ }
2284
+ #endif
2285
+
2286
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
2287
+ i++, rp++, dp++)
2288
+ {
2289
+ v = *dp = *rp;
2290
+
2291
+ sum += (v < 128) ? v : 256 - v;
2292
+ }
2293
+ for (lp = row_buf + 1; i < row_bytes;
2294
+ i++, rp++, lp++, dp++)
2295
+ {
2296
+ v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2297
+
2298
+ sum += (v < 128) ? v : 256 - v;
2299
+
2300
+ if (sum > lmins) /* We are already worse, don't continue. */
2301
+ break;
2302
+ }
2303
+
2304
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2305
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2306
+ {
2307
+ int j;
2308
+ png_uint_32 sumhi, sumlo;
2309
+ sumlo = sum & PNG_LOMASK;
2310
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2311
+
2312
+ for (j = 0; j < num_p_filters; j++)
2313
+ {
2314
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
2315
+ {
2316
+ sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
2317
+ PNG_WEIGHT_SHIFT;
2318
+ sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
2319
+ PNG_WEIGHT_SHIFT;
2320
+ }
2321
+ }
2322
+
2323
+ sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2324
+ PNG_COST_SHIFT;
2325
+ sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2326
+ PNG_COST_SHIFT;
2327
+
2328
+ if (sumhi > PNG_HIMASK)
2329
+ sum = PNG_MAXSUM;
2330
+ else
2331
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
2332
+ }
2333
+ #endif
2334
+
2335
+ if (sum < mins)
2336
+ {
2337
+ mins = sum;
2338
+ best_row = png_ptr->sub_row;
2339
+ }
2340
+ }
2341
+
2342
+ /* up filter */
2343
+ if (filter_to_do == PNG_FILTER_UP)
2344
+ {
2345
+ png_bytep rp, dp, pp;
2346
+ png_uint_32 i;
2347
+
2348
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2349
+ pp = prev_row + 1; i < row_bytes;
2350
+ i++, rp++, pp++, dp++)
2351
+ {
2352
+ *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
2353
+ }
2354
+ best_row = png_ptr->up_row;
2355
+ }
2356
+
2357
+ else if (filter_to_do & PNG_FILTER_UP)
2358
+ {
2359
+ png_bytep rp, dp, pp;
2360
+ png_uint_32 sum = 0, lmins = mins;
2361
+ png_uint_32 i;
2362
+ int v;
2363
+
2364
+
2365
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2366
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2367
+ {
2368
+ int j;
2369
+ png_uint_32 lmhi, lmlo;
2370
+ lmlo = lmins & PNG_LOMASK;
2371
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2372
+
2373
+ for (j = 0; j < num_p_filters; j++)
2374
+ {
2375
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
2376
+ {
2377
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2378
+ PNG_WEIGHT_SHIFT;
2379
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2380
+ PNG_WEIGHT_SHIFT;
2381
+ }
2382
+ }
2383
+
2384
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2385
+ PNG_COST_SHIFT;
2386
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2387
+ PNG_COST_SHIFT;
2388
+
2389
+ if (lmhi > PNG_HIMASK)
2390
+ lmins = PNG_MAXSUM;
2391
+ else
2392
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
2393
+ }
2394
+ #endif
2395
+
2396
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2397
+ pp = prev_row + 1; i < row_bytes; i++)
2398
+ {
2399
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2400
+
2401
+ sum += (v < 128) ? v : 256 - v;
2402
+
2403
+ if (sum > lmins) /* We are already worse, don't continue. */
2404
+ break;
2405
+ }
2406
+
2407
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2408
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2409
+ {
2410
+ int j;
2411
+ png_uint_32 sumhi, sumlo;
2412
+ sumlo = sum & PNG_LOMASK;
2413
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2414
+
2415
+ for (j = 0; j < num_p_filters; j++)
2416
+ {
2417
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
2418
+ {
2419
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2420
+ PNG_WEIGHT_SHIFT;
2421
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2422
+ PNG_WEIGHT_SHIFT;
2423
+ }
2424
+ }
2425
+
2426
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2427
+ PNG_COST_SHIFT;
2428
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2429
+ PNG_COST_SHIFT;
2430
+
2431
+ if (sumhi > PNG_HIMASK)
2432
+ sum = PNG_MAXSUM;
2433
+ else
2434
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
2435
+ }
2436
+ #endif
2437
+
2438
+ if (sum < mins)
2439
+ {
2440
+ mins = sum;
2441
+ best_row = png_ptr->up_row;
2442
+ }
2443
+ }
2444
+
2445
+ /* avg filter */
2446
+ if (filter_to_do == PNG_FILTER_AVG)
2447
+ {
2448
+ png_bytep rp, dp, pp, lp;
2449
+ png_uint_32 i;
2450
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2451
+ pp = prev_row + 1; i < bpp; i++)
2452
+ {
2453
+ *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2454
+ }
2455
+ for (lp = row_buf + 1; i < row_bytes; i++)
2456
+ {
2457
+ *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
2458
+ & 0xff);
2459
+ }
2460
+ best_row = png_ptr->avg_row;
2461
+ }
2462
+
2463
+ else if (filter_to_do & PNG_FILTER_AVG)
2464
+ {
2465
+ png_bytep rp, dp, pp, lp;
2466
+ png_uint_32 sum = 0, lmins = mins;
2467
+ png_uint_32 i;
2468
+ int v;
2469
+
2470
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2471
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2472
+ {
2473
+ int j;
2474
+ png_uint_32 lmhi, lmlo;
2475
+ lmlo = lmins & PNG_LOMASK;
2476
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2477
+
2478
+ for (j = 0; j < num_p_filters; j++)
2479
+ {
2480
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
2481
+ {
2482
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2483
+ PNG_WEIGHT_SHIFT;
2484
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2485
+ PNG_WEIGHT_SHIFT;
2486
+ }
2487
+ }
2488
+
2489
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2490
+ PNG_COST_SHIFT;
2491
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2492
+ PNG_COST_SHIFT;
2493
+
2494
+ if (lmhi > PNG_HIMASK)
2495
+ lmins = PNG_MAXSUM;
2496
+ else
2497
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
2498
+ }
2499
+ #endif
2500
+
2501
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2502
+ pp = prev_row + 1; i < bpp; i++)
2503
+ {
2504
+ v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2505
+
2506
+ sum += (v < 128) ? v : 256 - v;
2507
+ }
2508
+ for (lp = row_buf + 1; i < row_bytes; i++)
2509
+ {
2510
+ v = *dp++ =
2511
+ (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
2512
+
2513
+ sum += (v < 128) ? v : 256 - v;
2514
+
2515
+ if (sum > lmins) /* We are already worse, don't continue. */
2516
+ break;
2517
+ }
2518
+
2519
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2520
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2521
+ {
2522
+ int j;
2523
+ png_uint_32 sumhi, sumlo;
2524
+ sumlo = sum & PNG_LOMASK;
2525
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2526
+
2527
+ for (j = 0; j < num_p_filters; j++)
2528
+ {
2529
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
2530
+ {
2531
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2532
+ PNG_WEIGHT_SHIFT;
2533
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2534
+ PNG_WEIGHT_SHIFT;
2535
+ }
2536
+ }
2537
+
2538
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2539
+ PNG_COST_SHIFT;
2540
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2541
+ PNG_COST_SHIFT;
2542
+
2543
+ if (sumhi > PNG_HIMASK)
2544
+ sum = PNG_MAXSUM;
2545
+ else
2546
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
2547
+ }
2548
+ #endif
2549
+
2550
+ if (sum < mins)
2551
+ {
2552
+ mins = sum;
2553
+ best_row = png_ptr->avg_row;
2554
+ }
2555
+ }
2556
+
2557
+ /* Paeth filter */
2558
+ if (filter_to_do == PNG_FILTER_PAETH)
2559
+ {
2560
+ png_bytep rp, dp, pp, cp, lp;
2561
+ png_uint_32 i;
2562
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2563
+ pp = prev_row + 1; i < bpp; i++)
2564
+ {
2565
+ *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2566
+ }
2567
+
2568
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
2569
+ {
2570
+ int a, b, c, pa, pb, pc, p;
2571
+
2572
+ b = *pp++;
2573
+ c = *cp++;
2574
+ a = *lp++;
2575
+
2576
+ p = b - c;
2577
+ pc = a - c;
2578
+
2579
+ #ifdef PNG_USE_ABS
2580
+ pa = abs(p);
2581
+ pb = abs(pc);
2582
+ pc = abs(p + pc);
2583
+ #else
2584
+ pa = p < 0 ? -p : p;
2585
+ pb = pc < 0 ? -pc : pc;
2586
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2587
+ #endif
2588
+
2589
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2590
+
2591
+ *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
2592
+ }
2593
+ best_row = png_ptr->paeth_row;
2594
+ }
2595
+
2596
+ else if (filter_to_do & PNG_FILTER_PAETH)
2597
+ {
2598
+ png_bytep rp, dp, pp, cp, lp;
2599
+ png_uint_32 sum = 0, lmins = mins;
2600
+ png_uint_32 i;
2601
+ int v;
2602
+
2603
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2604
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2605
+ {
2606
+ int j;
2607
+ png_uint_32 lmhi, lmlo;
2608
+ lmlo = lmins & PNG_LOMASK;
2609
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2610
+
2611
+ for (j = 0; j < num_p_filters; j++)
2612
+ {
2613
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
2614
+ {
2615
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2616
+ PNG_WEIGHT_SHIFT;
2617
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2618
+ PNG_WEIGHT_SHIFT;
2619
+ }
2620
+ }
2621
+
2622
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2623
+ PNG_COST_SHIFT;
2624
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2625
+ PNG_COST_SHIFT;
2626
+
2627
+ if (lmhi > PNG_HIMASK)
2628
+ lmins = PNG_MAXSUM;
2629
+ else
2630
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
2631
+ }
2632
+ #endif
2633
+
2634
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2635
+ pp = prev_row + 1; i < bpp; i++)
2636
+ {
2637
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2638
+
2639
+ sum += (v < 128) ? v : 256 - v;
2640
+ }
2641
+
2642
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
2643
+ {
2644
+ int a, b, c, pa, pb, pc, p;
2645
+
2646
+ b = *pp++;
2647
+ c = *cp++;
2648
+ a = *lp++;
2649
+
2650
+ #ifndef PNG_SLOW_PAETH
2651
+ p = b - c;
2652
+ pc = a - c;
2653
+ #ifdef PNG_USE_ABS
2654
+ pa = abs(p);
2655
+ pb = abs(pc);
2656
+ pc = abs(p + pc);
2657
+ #else
2658
+ pa = p < 0 ? -p : p;
2659
+ pb = pc < 0 ? -pc : pc;
2660
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2661
+ #endif
2662
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2663
+ #else /* PNG_SLOW_PAETH */
2664
+ p = a + b - c;
2665
+ pa = abs(p - a);
2666
+ pb = abs(p - b);
2667
+ pc = abs(p - c);
2668
+ if (pa <= pb && pa <= pc)
2669
+ p = a;
2670
+ else if (pb <= pc)
2671
+ p = b;
2672
+ else
2673
+ p = c;
2674
+ #endif /* PNG_SLOW_PAETH */
2675
+
2676
+ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
2677
+
2678
+ sum += (v < 128) ? v : 256 - v;
2679
+
2680
+ if (sum > lmins) /* We are already worse, don't continue. */
2681
+ break;
2682
+ }
2683
+
2684
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2685
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2686
+ {
2687
+ int j;
2688
+ png_uint_32 sumhi, sumlo;
2689
+ sumlo = sum & PNG_LOMASK;
2690
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2691
+
2692
+ for (j = 0; j < num_p_filters; j++)
2693
+ {
2694
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
2695
+ {
2696
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2697
+ PNG_WEIGHT_SHIFT;
2698
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2699
+ PNG_WEIGHT_SHIFT;
2700
+ }
2701
+ }
2702
+
2703
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2704
+ PNG_COST_SHIFT;
2705
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2706
+ PNG_COST_SHIFT;
2707
+
2708
+ if (sumhi > PNG_HIMASK)
2709
+ sum = PNG_MAXSUM;
2710
+ else
2711
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
2712
+ }
2713
+ #endif
2714
+
2715
+ if (sum < mins)
2716
+ {
2717
+ best_row = png_ptr->paeth_row;
2718
+ }
2719
+ }
2720
+ #endif /* PNG_NO_WRITE_FILTER */
2721
+ /* Do the actual writing of the filtered row data from the chosen filter. */
2722
+
2723
+ png_write_filtered_row(png_ptr, best_row);
2724
+
2725
+ #ifndef PNG_NO_WRITE_FILTER
2726
+ #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
2727
+ /* Save the type of filter we picked this time for future calculations */
2728
+ if (png_ptr->num_prev_filters > 0)
2729
+ {
2730
+ int j;
2731
+ for (j = 1; j < num_p_filters; j++)
2732
+ {
2733
+ png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
2734
+ }
2735
+ png_ptr->prev_filters[j] = best_row[0];
2736
+ }
2737
+ #endif
2738
+ #endif /* PNG_NO_WRITE_FILTER */
2739
+ }
2740
+
2741
+
2742
+ /* Do the actual writing of a previously filtered row. */
2743
+ void /* PRIVATE */
2744
+ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
2745
+ {
2746
+ png_debug(1, "in png_write_filtered_row\n");
2747
+ png_debug1(2, "filter = %d\n", filtered_row[0]);
2748
+ /* set up the zlib input buffer */
2749
+
2750
+ png_ptr->zstream.next_in = filtered_row;
2751
+ png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
2752
+ /* repeat until we have compressed all the data */
2753
+ do
2754
+ {
2755
+ int ret; /* return of zlib */
2756
+
2757
+ /* compress the data */
2758
+ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
2759
+ /* check for compression errors */
2760
+ if (ret != Z_OK)
2761
+ {
2762
+ if (png_ptr->zstream.msg != NULL)
2763
+ png_error(png_ptr, png_ptr->zstream.msg);
2764
+ else
2765
+ png_error(png_ptr, "zlib error");
2766
+ }
2767
+
2768
+ /* see if it is time to write another IDAT */
2769
+ if (!(png_ptr->zstream.avail_out))
2770
+ {
2771
+ /* write the IDAT and reset the zlib output buffer */
2772
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
2773
+ png_ptr->zstream.next_out = png_ptr->zbuf;
2774
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
2775
+ }
2776
+ /* repeat until all data has been compressed */
2777
+ } while (png_ptr->zstream.avail_in);
2778
+
2779
+ /* swap the current and previous rows */
2780
+ if (png_ptr->prev_row != NULL)
2781
+ {
2782
+ png_bytep tptr;
2783
+
2784
+ tptr = png_ptr->prev_row;
2785
+ png_ptr->prev_row = png_ptr->row_buf;
2786
+ png_ptr->row_buf = tptr;
2787
+ }
2788
+
2789
+ /* finish row - updates counters and flushes zlib if last row */
2790
+ png_write_finish_row(png_ptr);
2791
+
2792
+ #if defined(PNG_WRITE_FLUSH_SUPPORTED)
2793
+ png_ptr->flush_rows++;
2794
+
2795
+ if (png_ptr->flush_dist > 0 &&
2796
+ png_ptr->flush_rows >= png_ptr->flush_dist)
2797
+ {
2798
+ png_write_flush(png_ptr);
2799
+ }
2800
+ #endif
2801
+ }
2802
+ #endif /* PNG_WRITE_SUPPORTED */