pngcp.c 72 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453
  1. /* pngcp.c
  2. *
  3. * Copyright (c) 2016 John Cunningham Bowler
  4. *
  5. * Last changed in libpng 1.6.24 [August 4, 2016]
  6. *
  7. * This code is released under the libpng license.
  8. * For conditions of distribution and use, see the disclaimer
  9. * and license in png.h
  10. *
  11. * This is an example of copying a PNG without changes using the png_read_png
  12. * and png_write_png interfaces. A considerable number of options are provided
  13. * to manipulate the compression of the PNG data and other compressed chunks.
  14. *
  15. * For a more extensive example that uses the transforms see
  16. * contrib/libtests/pngimage.c in the libpng distribution.
  17. */
  18. #include "pnglibconf.h" /* To find how libpng was configured. */
  19. #ifdef PNG_PNGCP_TIMING_SUPPORTED
  20. /* WARNING:
  21. *
  22. * This test is here to allow POSIX.1b extensions to be used if enabled in
  23. * the compile; specifically the code requires_POSIX_C_SOURCE support of
  24. * 199309L or later to enable clock_gettime use.
  25. *
  26. * IF this causes problems THEN compile with a strict ANSI C compiler and let
  27. * this code turn on the POSIX features that it minimally requires.
  28. *
  29. * IF this does not work there is probably a bug in your ANSI C compiler or
  30. * your POSIX implementation.
  31. */
  32. # define _POSIX_C_SOURCE 199309L
  33. #else /* No timing support required */
  34. # define _POSIX_SOURCE 1
  35. #endif
  36. #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
  37. # include <config.h>
  38. #endif
  39. #include <stdio.h>
  40. /* Define the following to use this test against your installed libpng, rather
  41. * than the one being built here:
  42. */
  43. #ifdef PNG_FREESTANDING_TESTS
  44. # include <png.h>
  45. #else
  46. # include "../../png.h"
  47. #endif
  48. #if PNG_LIBPNG_VER < 10700
  49. /* READ_PNG and WRITE_PNG were not defined, so: */
  50. # ifdef PNG_INFO_IMAGE_SUPPORTED
  51. # ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  52. # define PNG_READ_PNG_SUPPORTED
  53. # endif /* SEQUENTIAL_READ */
  54. # ifdef PNG_WRITE_SUPPORTED
  55. # define PNG_WRITE_PNG_SUPPORTED
  56. # endif /* WRITE */
  57. # endif /* INFO_IMAGE */
  58. #endif /* pre 1.7.0 */
  59. #if (defined(PNG_READ_PNG_SUPPORTED)) && (defined(PNG_WRITE_PNG_SUPPORTED))
  60. #include <stdarg.h>
  61. #include <stdlib.h>
  62. #include <string.h>
  63. #include <errno.h>
  64. #include <limits.h>
  65. #include <assert.h>
  66. #include <unistd.h>
  67. #include <sys/stat.h>
  68. #include <zlib.h>
  69. #ifndef PNG_SETJMP_SUPPORTED
  70. # include <setjmp.h> /* because png.h did *not* include this */
  71. #endif
  72. #ifdef __cplusplus
  73. # define voidcast(type, value) static_cast<type>(value)
  74. #else
  75. # define voidcast(type, value) (value)
  76. #endif /* __cplusplus */
  77. #ifdef __GNUC__
  78. /* Many versions of GCC erroneously report that local variables unmodified
  79. * within the scope of a setjmp may be clobbered. This hacks round the
  80. * problem (sometimes) without harming other compilers.
  81. */
  82. # define gv volatile
  83. #else
  84. # define gv
  85. #endif
  86. /* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime. It
  87. * need not be supported even when clock_gettime is available. It returns the
  88. * 'CPU' time the process has consumed. 'CPU' time is assumed to include time
  89. * when the CPU is actually blocked by a pending cache fill but not time
  90. * waiting for page faults. The attempt is to get a measure of the actual time
  91. * the implementation takes to read a PNG ignoring the potentially very large IO
  92. * overhead.
  93. */
  94. #ifdef PNG_PNGCP_TIMING_SUPPORTED
  95. # include <time.h> /* clock_gettime and associated definitions */
  96. # ifndef CLOCK_PROCESS_CPUTIME_ID
  97. /* Prevent inclusion of the spurious code: */
  98. # undef PNG_PNGCP_TIMING_SUPPORTED
  99. # endif
  100. #endif /* PNGCP_TIMING */
  101. /* So if the timing feature has been activated: */
  102. /* This structure is used to control the test of a single file. */
  103. typedef enum
  104. {
  105. VERBOSE, /* switches on all messages */
  106. INFORMATION,
  107. WARNINGS, /* switches on warnings */
  108. LIBPNG_WARNING,
  109. APP_WARNING,
  110. ERRORS, /* just errors */
  111. APP_FAIL, /* continuable error - no need to longjmp */
  112. LIBPNG_ERROR, /* this and higher cause a longjmp */
  113. LIBPNG_BUG, /* erroneous behavior in libpng */
  114. APP_ERROR, /* such as out-of-memory in a callback */
  115. QUIET, /* no normal messages */
  116. USER_ERROR, /* such as file-not-found */
  117. INTERNAL_ERROR
  118. } error_level;
  119. #define LEVEL_MASK 0xf /* where the level is in 'options' */
  120. #define STRICT 0x010 /* Fail on warnings as well as errors */
  121. #define LOG 0x020 /* Log pass/fail to stdout */
  122. #define CONTINUE 0x040 /* Continue on APP_FAIL errors */
  123. #define SIZES 0x080 /* Report input and output sizes */
  124. #define SEARCH 0x100 /* Search IDAT compression options */
  125. #define NOWRITE 0x200 /* Do not write an output file */
  126. #ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
  127. # define IGNORE_INDEX 0x400 /* Ignore out of range palette indices (BAD!) */
  128. # ifdef PNG_GET_PALETTE_MAX_SUPPORTED
  129. # define FIX_INDEX 0x800 /* 'Fix' out of range palette indices (OK) */
  130. # endif /* GET_PALETTE_MAX */
  131. #endif /* CHECK_FOR_INVALID_INDEX */
  132. #define OPTION 0x80000000 /* Used for handling options */
  133. #define LIST 0x80000001 /* Used for handling options */
  134. /* Result masks apply to the result bits in the 'results' field below; these
  135. * bits are simple 1U<<error_level. A pass requires either nothing worse than
  136. * warnings (--relaxes) or nothing worse than information (--strict)
  137. */
  138. #define RESULT_STRICT(r) (((r) & ~((1U<<WARNINGS)-1)) == 0)
  139. #define RESULT_RELAXED(r) (((r) & ~((1U<<ERRORS)-1)) == 0)
  140. /* OPTION DEFINITIONS */
  141. static const char range_lo[] = "low";
  142. static const char range_hi[] = "high";
  143. static const char all[] = "all";
  144. #define RANGE(lo,hi) { range_lo, lo }, { range_hi, hi }
  145. typedef struct value_list
  146. {
  147. const char *name; /* the command line name of the value */
  148. int value; /* the actual value to use */
  149. } value_list;
  150. static const value_list
  151. #ifdef PNG_SW_COMPRESS_png_level
  152. vl_compression[] =
  153. {
  154. /* Overall compression control. The order controls the search order for
  155. * 'all'. Since the search is for the smallest the order used is low memory
  156. * then high speed.
  157. */
  158. { "low-memory", PNG_COMPRESSION_LOW_MEMORY },
  159. { "high-speed", PNG_COMPRESSION_HIGH_SPEED },
  160. { "high-read-speed", PNG_COMPRESSION_HIGH_READ_SPEED },
  161. { "low", PNG_COMPRESSION_LOW },
  162. { "medium", PNG_COMPRESSION_MEDIUM },
  163. { "old", PNG_COMPRESSION_COMPAT },
  164. { "high", PNG_COMPRESSION_HIGH },
  165. { all, 0 }
  166. },
  167. #endif /* SW_COMPRESS_png_level */
  168. #if defined(PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED) ||\
  169. defined(PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED)
  170. vl_strategy[] =
  171. {
  172. /* This controls the order of search. */
  173. { "huffman", Z_HUFFMAN_ONLY },
  174. { "RLE", Z_RLE },
  175. { "fixed", Z_FIXED }, /* the remainder do window searches */
  176. { "filtered", Z_FILTERED },
  177. { "default", Z_DEFAULT_STRATEGY },
  178. { all, 0 }
  179. },
  180. #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
  181. vl_windowBits_text[] =
  182. {
  183. { "default", MAX_WBITS/*from zlib*/ },
  184. { "minimum", 8 },
  185. RANGE(8, MAX_WBITS/*from zlib*/),
  186. { all, 0 }
  187. },
  188. #endif /* text compression */
  189. vl_level[] =
  190. {
  191. { "default", Z_DEFAULT_COMPRESSION /* this is -1 */ },
  192. { "none", Z_NO_COMPRESSION },
  193. { "speed", Z_BEST_SPEED },
  194. { "best", Z_BEST_COMPRESSION },
  195. { "0", Z_NO_COMPRESSION },
  196. RANGE(1, 9), /* this deliberately excludes '0' */
  197. { all, 0 }
  198. },
  199. vl_memLevel[] =
  200. {
  201. { "max", MAX_MEM_LEVEL }, /* zlib maximum */
  202. { "1", 1 }, /* zlib minimum */
  203. { "default", 8 }, /* zlib default */
  204. { "2", 2 },
  205. { "3", 3 },
  206. { "4", 4 },
  207. { "5", 5 }, /* for explicit testing */
  208. RANGE(6, MAX_MEM_LEVEL/*zlib*/), /* exclude 5 and below: zlib bugs */
  209. { all, 0 }
  210. },
  211. #endif /* WRITE_CUSTOMIZE_*COMPRESSION */
  212. #ifdef PNG_WRITE_FILTER_SUPPORTED
  213. vl_filter[] =
  214. {
  215. { all, PNG_ALL_FILTERS },
  216. { "off", PNG_NO_FILTERS },
  217. { "none", PNG_FILTER_NONE },
  218. { "sub", PNG_FILTER_SUB },
  219. { "up", PNG_FILTER_UP },
  220. { "avg", PNG_FILTER_AVG },
  221. { "paeth", PNG_FILTER_PAETH }
  222. },
  223. #endif /* WRITE_FILTER */
  224. #ifdef PNG_PNGCP_TIMING_SUPPORTED
  225. # define PNGCP_TIME_READ 1
  226. # define PNGCP_TIME_WRITE 2
  227. vl_time[] =
  228. {
  229. { "both", PNGCP_TIME_READ+PNGCP_TIME_WRITE },
  230. { "off", 0 },
  231. { "read", PNGCP_TIME_READ },
  232. { "write", PNGCP_TIME_WRITE }
  233. },
  234. #endif /* PNGCP_TIMING */
  235. vl_IDAT_size[] = /* for png_set_IDAT_size */
  236. {
  237. { "default", 0x7FFFFFFF },
  238. { "minimal", 1 },
  239. RANGE(1, 0x7FFFFFFF)
  240. },
  241. #ifndef PNG_SW_IDAT_size
  242. /* Pre 1.7 API: */
  243. # define png_set_IDAT_size(p,v) png_set_compression_buffer_size(p, v)
  244. #endif /* !SW_IDAT_size */
  245. #define SL 8 /* stack limit in display, below */
  246. vl_log_depth[] = { { "on", 1 }, { "off", 0 }, RANGE(0, SL) },
  247. vl_on_off[] = { { "on", 1 }, { "off", 0 } };
  248. #ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
  249. static value_list
  250. vl_windowBits_IDAT[] =
  251. {
  252. { "default", MAX_WBITS },
  253. { "small", 9 },
  254. RANGE(8, MAX_WBITS), /* modified by set_windowBits_hi */
  255. { all, 0 }
  256. };
  257. #endif /* IDAT compression */
  258. typedef struct option
  259. {
  260. const char *name; /* name of the option */
  261. png_uint_32 opt; /* an option, or OPTION or LIST */
  262. png_byte search; /* Search on --search */
  263. png_byte value_count; /* length of the list of values: */
  264. const value_list *values; /* values for OPTION or LIST */
  265. } option;
  266. static const option options[] =
  267. {
  268. /* struct display options, these are set when the command line is read */
  269. # define S(n,v) { #n, v, 0, 2, vl_on_off },
  270. S(verbose, VERBOSE)
  271. S(warnings, WARNINGS)
  272. S(errors, ERRORS)
  273. S(quiet, QUIET)
  274. S(strict, STRICT)
  275. S(log, LOG)
  276. S(continue, CONTINUE)
  277. S(sizes, SIZES)
  278. S(search, SEARCH)
  279. S(nowrite, NOWRITE)
  280. # ifdef IGNORE_INDEX
  281. S(ignore-palette-index, IGNORE_INDEX)
  282. # endif /* IGNORE_INDEX */
  283. # ifdef FIX_INDEX
  284. S(fix-palette-index, FIX_INDEX)
  285. # endif /* FIX_INDEX */
  286. # undef S
  287. /* OPTION settings, these and LIST settings are read on demand */
  288. # define VLNAME(name) vl_ ## name
  289. # define VLSIZE(name) voidcast(png_byte,\
  290. (sizeof VLNAME(name))/(sizeof VLNAME(name)[0]))
  291. # define VL(oname, name, type, search)\
  292. { oname, type, search, VLSIZE(name), VLNAME(name) },
  293. # define VLO(oname, name, search) VL(oname, name, OPTION, search)
  294. # ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
  295. # define VLCIDAT(name) VLO(#name, name, 1/*search*/)
  296. # ifdef PNG_SW_COMPRESS_level
  297. # define VLCiCCP(name) VLO("ICC-profile-" #name, name, 0/*search*/)
  298. # else
  299. # define VLCiCCP(name)
  300. # endif
  301. # else
  302. # define VLCIDAT(name)
  303. # define VLCiCCP(name)
  304. # endif /* WRITE_CUSTOMIZE_COMPRESSION */
  305. # ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
  306. # define VLCzTXt(name) VLO("text-" #name, name, 0/*search*/)
  307. # else
  308. # define VLCzTXt(name)
  309. # endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
  310. # define VLC(name) VLCIDAT(name) VLCiCCP(name) VLCzTXt(name)
  311. # ifdef PNG_SW_COMPRESS_png_level
  312. /* The libpng compression level isn't searched because it justs sets the
  313. * other things that are searched!
  314. */
  315. VLO("compression", compression, 0)
  316. VLO("text-compression", compression, 0)
  317. VLO("ICC-profile-compression", compression, 0)
  318. # endif /* SW_COMPRESS_png_level */
  319. VLC(strategy)
  320. VLO("windowBits", windowBits_IDAT, 1)
  321. # ifdef PNG_SW_COMPRESS_windowBits
  322. VLO("ICC-profile-windowBits", windowBits_text/*sic*/, 0)
  323. # endif
  324. VLO("text-windowBits", windowBits_text, 0)
  325. VLC(level)
  326. VLC(memLevel)
  327. VLO("IDAT-size", IDAT_size, 0)
  328. VLO("log-depth", log_depth, 0)
  329. # undef VLO
  330. /* LIST settings */
  331. # define VLL(name, search) VL(#name, name, LIST, search)
  332. #ifdef PNG_WRITE_FILTER_SUPPORTED
  333. VLL(filter, 0)
  334. #endif /* WRITE_FILTER */
  335. #ifdef PNG_PNGCP_TIMING_SUPPORTED
  336. VLL(time, 0)
  337. #endif /* PNGCP_TIMING */
  338. # undef VLL
  339. # undef VL
  340. };
  341. #ifdef __cplusplus
  342. static const size_t option_count((sizeof options)/(sizeof options[0]));
  343. #else /* !__cplusplus */
  344. # define option_count ((sizeof options)/(sizeof options[0]))
  345. #endif /* !__cplusplus */
  346. static const char *
  347. cts(int ct)
  348. {
  349. switch (ct)
  350. {
  351. case PNG_COLOR_TYPE_PALETTE: return "P";
  352. case PNG_COLOR_TYPE_GRAY: return "G";
  353. case PNG_COLOR_TYPE_GRAY_ALPHA: return "GA";
  354. case PNG_COLOR_TYPE_RGB: return "RGB";
  355. case PNG_COLOR_TYPE_RGB_ALPHA: return "RGBA";
  356. default: return "INVALID";
  357. }
  358. }
  359. struct display
  360. {
  361. jmp_buf error_return; /* Where to go to on error */
  362. unsigned int errset; /* error_return is set */
  363. const char *operation; /* What is happening */
  364. const char *filename; /* The name of the original file */
  365. const char *output_file; /* The name of the output file */
  366. /* Used on both read and write: */
  367. FILE *fp;
  368. /* Used on a read, both the original read and when validating a written
  369. * image.
  370. */
  371. png_alloc_size_t read_size;
  372. png_structp read_pp;
  373. png_infop ip;
  374. # if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
  375. png_textp text_ptr; /* stash of text chunks */
  376. int num_text;
  377. int text_stashed;
  378. # endif /* pre 1.7 */
  379. # ifdef PNG_PNGCP_TIMING_SUPPORTED
  380. struct timespec read_time;
  381. struct timespec read_time_total;
  382. struct timespec write_time;
  383. struct timespec write_time_total;
  384. # endif /* PNGCP_TIMING */
  385. /* Used to write a new image (the original info_ptr is used) */
  386. # define MAX_SIZE ((png_alloc_size_t)(-1))
  387. png_alloc_size_t write_size;
  388. png_alloc_size_t best_size;
  389. png_structp write_pp;
  390. /* Base file information */
  391. png_alloc_size_t size;
  392. png_uint_32 w;
  393. png_uint_32 h;
  394. int bpp;
  395. png_byte ct;
  396. int no_warnings; /* Do not output libpng warnings */
  397. int min_windowBits; /* The windowBits range is 8..8 */
  398. /* Options handling */
  399. png_uint_32 results; /* A mask of errors seen */
  400. png_uint_32 options; /* See display_log below */
  401. png_byte entry[option_count]; /* The selected entry+1 of an option
  402. * that appears on the command line, or
  403. * 0 if it was not given. */
  404. int value[option_count]; /* Corresponding value */
  405. /* Compression exhaustive testing */
  406. /* Temporary variables used only while testing a single collection of
  407. * settings:
  408. */
  409. unsigned int csp; /* next stack entry to use */
  410. unsigned int nsp; /* highest active entry+1 found so far */
  411. /* Values used while iterating through all the combinations of settings for a
  412. * single file:
  413. */
  414. unsigned int tsp; /* nsp from the last run; this is the
  415. * index+1 of the highest active entry on
  416. * this run; this entry will be advanced.
  417. */
  418. int opt_string_start; /* Position in buffer for the first
  419. * searched option; non-zero if earlier
  420. * options were set on the command line.
  421. */
  422. struct stack
  423. {
  424. png_alloc_size_t best_size; /* Best so far for this option */
  425. png_alloc_size_t lo_size;
  426. png_alloc_size_t hi_size;
  427. int lo, hi; /* For binary chop of a range */
  428. int best_val; /* Best value found so far */
  429. int opt_string_end; /* End of the option string in 'curr' */
  430. png_byte opt; /* The option being tested */
  431. png_byte entry; /* The next value entry to be tested */
  432. png_byte end; /* This is the last entry */
  433. } stack[SL]; /* Stack of entries being tested */
  434. char curr[32*SL]; /* current options being tested */
  435. char best[32*SL]; /* best options */
  436. char namebuf[FILENAME_MAX]; /* output file name */
  437. };
  438. static void
  439. display_init(struct display *dp)
  440. /* Call this only once right at the start to initialize the control
  441. * structure, the (struct buffer) lists are maintained across calls - the
  442. * memory is not freed.
  443. */
  444. {
  445. memset(dp, 0, sizeof *dp);
  446. dp->operation = "internal error";
  447. dp->filename = "command line";
  448. dp->output_file = "no output file";
  449. dp->options = WARNINGS; /* default to !verbose, !quiet */
  450. dp->fp = NULL;
  451. dp->read_pp = NULL;
  452. dp->ip = NULL;
  453. dp->write_pp = NULL;
  454. dp->min_windowBits = -1; /* this is an OPTIND, so -1 won't match anything */
  455. # if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
  456. dp->text_ptr = NULL;
  457. dp->num_text = 0;
  458. dp->text_stashed = 0;
  459. # endif /* pre 1.7 */
  460. }
  461. static void
  462. display_clean_read(struct display *dp)
  463. {
  464. if (dp->read_pp != NULL)
  465. png_destroy_read_struct(&dp->read_pp, NULL, NULL);
  466. if (dp->fp != NULL)
  467. {
  468. FILE *fp = dp->fp;
  469. dp->fp = NULL;
  470. (void)fclose(fp);
  471. }
  472. }
  473. static void
  474. display_clean_write(struct display *dp)
  475. {
  476. if (dp->fp != NULL)
  477. {
  478. FILE *fp = dp->fp;
  479. dp->fp = NULL;
  480. (void)fclose(fp);
  481. }
  482. if (dp->write_pp != NULL)
  483. png_destroy_write_struct(&dp->write_pp, dp->tsp > 0 ? NULL : &dp->ip);
  484. }
  485. static void
  486. display_clean(struct display *dp)
  487. {
  488. display_clean_read(dp);
  489. display_clean_write(dp);
  490. dp->output_file = NULL;
  491. # if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
  492. /* This is actually created and used by the write code, but only
  493. * once; it has to be retained for subsequent writes of the same file.
  494. */
  495. if (dp->text_stashed)
  496. {
  497. dp->text_stashed = 0;
  498. dp->num_text = 0;
  499. free(dp->text_ptr);
  500. dp->text_ptr = NULL;
  501. }
  502. # endif /* pre 1.7 */
  503. /* leave the filename for error detection */
  504. dp->results = 0; /* reset for next time */
  505. }
  506. static void
  507. display_destroy(struct display *dp)
  508. {
  509. /* Release any memory held in the display. */
  510. display_clean(dp);
  511. }
  512. static struct display *
  513. get_dp(png_structp pp)
  514. /* The display pointer is always stored in the png_struct error pointer */
  515. {
  516. struct display *dp = (struct display*)png_get_error_ptr(pp);
  517. if (dp == NULL)
  518. {
  519. fprintf(stderr, "pngcp: internal error (no display)\n");
  520. exit(99); /* prevents a crash */
  521. }
  522. return dp;
  523. }
  524. /* error handling */
  525. #ifdef __GNUC__
  526. # define VGATTR __attribute__((__format__ (__printf__,3,4)))
  527. /* Required to quiet GNUC warnings when the compiler sees a stdarg function
  528. * that calls one of the stdio v APIs.
  529. */
  530. #else
  531. # define VGATTR
  532. #endif
  533. static void VGATTR
  534. display_log(struct display *dp, error_level level, const char *fmt, ...)
  535. /* 'level' is as above, fmt is a stdio style format string. This routine
  536. * does not return if level is above LIBPNG_WARNING
  537. */
  538. {
  539. dp->results |= 1U << level;
  540. if (level > (error_level)(dp->options & LEVEL_MASK))
  541. {
  542. const char *lp;
  543. va_list ap;
  544. switch (level)
  545. {
  546. case INFORMATION: lp = "information"; break;
  547. case LIBPNG_WARNING: lp = "warning(libpng)"; break;
  548. case APP_WARNING: lp = "warning(pngcp)"; break;
  549. case APP_FAIL: lp = "error(continuable)"; break;
  550. case LIBPNG_ERROR: lp = "error(libpng)"; break;
  551. case LIBPNG_BUG: lp = "bug(libpng)"; break;
  552. case APP_ERROR: lp = "error(pngcp)"; break;
  553. case USER_ERROR: lp = "error(user)"; break;
  554. case INTERNAL_ERROR: /* anything unexpected is an internal error: */
  555. case VERBOSE: case WARNINGS: case ERRORS: case QUIET:
  556. default: lp = "bug(pngcp)"; break;
  557. }
  558. fprintf(stderr, "%s: %s: %s",
  559. dp->filename != NULL ? dp->filename : "<stdin>", lp, dp->operation);
  560. fprintf(stderr, ": ");
  561. va_start(ap, fmt);
  562. vfprintf(stderr, fmt, ap);
  563. va_end(ap);
  564. fputc('\n', stderr);
  565. }
  566. /* else do not output any message */
  567. /* Errors cause this routine to exit to the fail code */
  568. if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
  569. {
  570. if (dp->errset)
  571. longjmp(dp->error_return, level);
  572. else
  573. exit(99);
  574. }
  575. }
  576. #if PNG_LIBPNG_VER < 10700 && defined PNG_TEXT_SUPPORTED
  577. static void
  578. text_stash(struct display *dp)
  579. {
  580. /* libpng 1.6 and earlier fixed a bug whereby text chunks were written
  581. * multiple times by png_write_png; the issue was that png_write_png passed
  582. * the same png_info to both png_write_info and png_write_end. Rather than
  583. * fixing it by recording the information in the png_struct, or by recording
  584. * where to write the chunks, the fix made was to change the 'compression'
  585. * field of the chunk to invalid values, rendering the png_info somewhat
  586. * useless.
  587. *
  588. * The only fix for this given that we use the png_info more than once is to
  589. * make a copy of the text chunks and png_set_text it each time. This adds a
  590. * text chunks, so they get replicated, but only the new set gets written
  591. * each time. This uses memory like crazy but there is no way to delete the
  592. * useless chunks from the png_info.
  593. *
  594. * To make this slightly more efficient only the top level structure is
  595. * copied; since the old strings are actually preserved (in 1.6 and earlier)
  596. * this happens to work.
  597. */
  598. png_textp chunks = NULL;
  599. dp->num_text = png_get_text(dp->write_pp, dp->ip, &chunks, NULL);
  600. if (dp->num_text > 0)
  601. {
  602. dp->text_ptr = voidcast(png_textp, malloc(dp->num_text * sizeof *chunks));
  603. if (dp->text_ptr == NULL)
  604. display_log(dp, APP_ERROR, "text chunks: stash malloc failed");
  605. else
  606. memcpy(dp->text_ptr, chunks, dp->num_text * sizeof *chunks);
  607. }
  608. dp->text_stashed = 1; /* regardless of whether there are chunks or not */
  609. }
  610. #define text_stash(dp) if (!dp->text_stashed) text_stash(dp)
  611. static void
  612. text_restore(struct display *dp)
  613. {
  614. /* libpng makes a copy, so this is fine: */
  615. if (dp->text_ptr != NULL)
  616. png_set_text(dp->write_pp, dp->ip, dp->text_ptr, dp->num_text);
  617. }
  618. #define text_restore(dp) if (dp->text_stashed) text_restore(dp)
  619. #else
  620. #define text_stash(dp) ((void)0)
  621. #define text_restore(dp) ((void)0)
  622. #endif /* pre 1.7 */
  623. /* OPTIONS:
  624. *
  625. * The command handles options of the forms:
  626. *
  627. * --option
  628. * Turn an option on (Option)
  629. * --no-option
  630. * Turn an option off (Option)
  631. * --option=value
  632. * Set an option to a value (Value)
  633. * --option=val1,val2,val3
  634. * Set an option to a bitmask constructed from the values (List)
  635. */
  636. static png_byte
  637. option_index(struct display *dp, const char *opt, size_t len)
  638. /* Return the index (in options[]) of the given option, outputs an error if
  639. * it does not exist. Takes the name of the option and a length (number of
  640. * characters in the name).
  641. */
  642. {
  643. png_byte j;
  644. for (j=0; j<option_count; ++j)
  645. if (strncmp(options[j].name, opt, len) == 0 && options[j].name[len] == 0)
  646. return j;
  647. /* If the setjmp buffer is set the code is asking for an option index; this
  648. * is bad. Otherwise this is the command line option parsing.
  649. */
  650. display_log(dp, dp->errset ? INTERNAL_ERROR : USER_ERROR,
  651. "%.*s: unknown option", (int)/*SAFE*/len, opt);
  652. abort(); /* NOT REACHED */
  653. }
  654. /* This works for an option name (no quotes): */
  655. #define OPTIND(dp, name) option_index(dp, #name, (sizeof #name)-1)
  656. static int
  657. get_option(struct display *dp, const char *opt, int *value)
  658. {
  659. png_byte i = option_index(dp, opt, strlen(opt));
  660. if (dp->entry[i]) /* option was set on command line */
  661. {
  662. *value = dp->value[i];
  663. return 1;
  664. }
  665. else
  666. return 0;
  667. }
  668. static int
  669. set_opt_string_(struct display *dp, unsigned int sp, png_byte opt,
  670. const char *entry_name)
  671. /* Add the appropriate option string to dp->curr. */
  672. {
  673. int offset, add;
  674. if (sp > 0)
  675. offset = dp->stack[sp-1].opt_string_end;
  676. else
  677. offset = dp->opt_string_start;
  678. if (entry_name == range_lo)
  679. add = sprintf(dp->curr+offset, " --%s=%d", options[opt].name,
  680. dp->value[opt]);
  681. else
  682. add = sprintf(dp->curr+offset, " --%s=%s", options[opt].name, entry_name);
  683. if (add < 0)
  684. display_log(dp, INTERNAL_ERROR, "sprintf failed");
  685. assert(offset+add < (int)/*SAFE*/sizeof dp->curr);
  686. return offset+add;
  687. }
  688. static void
  689. set_opt_string(struct display *dp, unsigned int sp)
  690. /* Add the appropriate option string to dp->curr. */
  691. {
  692. dp->stack[sp].opt_string_end = set_opt_string_(dp, sp, dp->stack[sp].opt,
  693. options[dp->stack[sp].opt].values[dp->stack[sp].entry].name);
  694. }
  695. static void
  696. record_opt(struct display *dp, png_byte opt, const char *entry_name)
  697. /* Record this option in dp->curr; called for an option not being searched,
  698. * the caller passes in the name of the value, or range_lo to use the
  699. * numerical value.
  700. */
  701. {
  702. unsigned int sp = dp->csp; /* stack entry of next searched option */
  703. if (sp >= dp->tsp)
  704. {
  705. /* At top of stack; add the opt string for this entry to the previous
  706. * searched entry or the start of the dp->curr buffer if there is nothing
  707. * on the stack yet (sp == 0).
  708. */
  709. int offset = set_opt_string_(dp, sp, opt, entry_name);
  710. if (sp > 0)
  711. dp->stack[sp-1].opt_string_end = offset;
  712. else
  713. dp->opt_string_start = offset;
  714. }
  715. /* else do nothing: option already recorded */
  716. }
  717. static int
  718. opt_list_end(struct display *dp, png_byte opt, png_byte entry)
  719. {
  720. if (options[opt].values[entry].name == range_lo)
  721. return entry+1U >= options[opt].value_count /* missing range_hi */ ||
  722. options[opt].values[entry+1U].name != range_hi /* likewise */ ||
  723. options[opt].values[entry+1U].value <= dp->value[opt] /* range end */;
  724. else
  725. return entry+1U >= options[opt].value_count /* missing 'all' */ ||
  726. options[opt].values[entry+1U].name == all /* last entry */;
  727. }
  728. static void
  729. push_opt(struct display *dp, unsigned int sp, png_byte opt, int search)
  730. /* Push a new option onto the stack, initializing the new stack entry
  731. * appropriately; this does all the work of next_opt (setting end/nsp) for
  732. * the first entry in the list.
  733. */
  734. {
  735. png_byte entry;
  736. const char *entry_name;
  737. assert(sp == dp->tsp && sp < SL);
  738. /* The starting entry is entry 0 unless there is a range in which case it is
  739. * the entry corresponding to range_lo:
  740. */
  741. entry = options[opt].value_count;
  742. assert(entry > 0U);
  743. do
  744. {
  745. entry_name = options[opt].values[--entry].name;
  746. if (entry_name == range_lo)
  747. break;
  748. }
  749. while (entry > 0U);
  750. dp->tsp = sp+1U;
  751. dp->stack[sp].best_size =
  752. dp->stack[sp].lo_size =
  753. dp->stack[sp].hi_size = MAX_SIZE;
  754. if (search && entry_name == range_lo) /* search this range */
  755. {
  756. dp->stack[sp].lo = options[opt].values[entry].value;
  757. /* check for a mal-formed RANGE above: */
  758. assert(entry+1 < options[opt].value_count &&
  759. options[opt].values[entry+1].name == range_hi);
  760. dp->stack[sp].hi = options[opt].values[entry+1].value;
  761. }
  762. else
  763. {
  764. /* next_opt will just iterate over the range. */
  765. dp->stack[sp].lo = INT_MAX;
  766. dp->stack[sp].hi = INT_MIN; /* Prevent range chop */
  767. }
  768. dp->stack[sp].opt = opt;
  769. dp->stack[sp].entry = entry;
  770. dp->stack[sp].best_val = dp->value[opt] = options[opt].values[entry].value;
  771. set_opt_string(dp, sp);
  772. /* This works for the search case too; if the range has only one entry 'end'
  773. * will be marked here.
  774. */
  775. if (opt_list_end(dp, opt, entry))
  776. {
  777. dp->stack[sp].end = 1;
  778. /* Skip the warning if pngcp did this itself. See the code in
  779. * set_windowBits_hi.
  780. */
  781. if (opt != dp->min_windowBits)
  782. display_log(dp, APP_WARNING, "%s: only testing one value",
  783. options[opt].name);
  784. }
  785. else
  786. {
  787. dp->stack[sp].end = 0;
  788. dp->nsp = dp->tsp;
  789. }
  790. /* Do a lazy cache of the text chunks for libpng 1.6 and earlier; this is
  791. * because they can only be written once(!) so if we are going to re-use the
  792. * png_info we need a copy.
  793. */
  794. text_stash(dp);
  795. }
  796. static void
  797. next_opt(struct display *dp, unsigned int sp)
  798. /* Return the next value for this option. When called 'sp' is expected to be
  799. * the topmost stack entry - only the topmost entry changes each time round -
  800. * and there must be a valid entry to return. next_opt will set dp->nsp to
  801. * sp+1 if more entries are available, otherwise it will not change it and
  802. * set dp->stack[s].end to true.
  803. */
  804. {
  805. int search = 0;
  806. png_byte entry, opt;
  807. const char *entry_name;
  808. /* dp->stack[sp] must be the top stack entry and it must be active: */
  809. assert(sp+1U == dp->tsp && !dp->stack[sp].end);
  810. opt = dp->stack[sp].opt;
  811. entry = dp->stack[sp].entry;
  812. assert(entry+1U < options[opt].value_count);
  813. entry_name = options[opt].values[entry].name;
  814. assert(entry_name != NULL);
  815. /* For ranges increment the value but don't change the entry, for all other
  816. * cases move to the next entry and load its value:
  817. */
  818. if (entry_name == range_lo) /* a range */
  819. {
  820. /* A range can be iterated over or searched. The default iteration option
  821. * is indicated by hi < lo on the stack, otherwise the range being search
  822. * is [lo..hi] (inclusive).
  823. */
  824. if (dp->stack[sp].lo > dp->stack[sp].hi)
  825. dp->value[opt]++;
  826. else
  827. {
  828. /* This is the best size found for this option value: */
  829. png_alloc_size_t best_size = dp->stack[sp].best_size;
  830. int lo = dp->stack[sp].lo;
  831. int hi = dp->stack[sp].hi;
  832. int val = dp->value[opt];
  833. search = 1; /* end is determined here */
  834. assert(best_size < MAX_SIZE);
  835. if (val == lo)
  836. {
  837. /* Finding the best for the low end of the range: */
  838. dp->stack[sp].lo_size = best_size;
  839. assert(hi > val);
  840. if (hi == val+1) /* only 2 entries */
  841. dp->stack[sp].end = 1;
  842. val = hi;
  843. }
  844. else if (val == hi)
  845. {
  846. dp->stack[sp].hi_size = best_size;
  847. assert(val > lo+1); /* else 'end' set above */
  848. if (val == lo+2) /* only three entries to test */
  849. dp->stack[sp].end = 1;
  850. val = (lo + val)/2;
  851. }
  852. else
  853. {
  854. png_alloc_size_t lo_size = dp->stack[sp].lo_size;
  855. png_alloc_size_t hi_size = dp->stack[sp].hi_size;
  856. /* lo and hi should have been tested. */
  857. assert(lo_size < MAX_SIZE && hi_size < MAX_SIZE);
  858. /* These cases arise with the 'probe' handling below when there is a
  859. * dip or peak in the size curve.
  860. */
  861. if (val < lo) /* probing a new lo */
  862. {
  863. /* Swap lo and val: */
  864. dp->stack[sp].lo = val;
  865. dp->stack[sp].lo_size = best_size;
  866. val = lo;
  867. best_size = lo_size;
  868. lo = dp->stack[sp].lo;
  869. lo_size = dp->stack[sp].lo_size;
  870. }
  871. else if (val > hi) /* probing a new hi */
  872. {
  873. /* Swap hi and val: */
  874. dp->stack[sp].hi = val;
  875. dp->stack[sp].hi_size = best_size;
  876. val = hi;
  877. best_size = hi_size;
  878. hi = dp->stack[sp].hi;
  879. hi_size = dp->stack[sp].hi_size;
  880. }
  881. /* The following should be true or something got messed up above. */
  882. assert(lo < val && val < hi);
  883. /* If there are only four entries (lo, val, hi plus one more) just
  884. * test the remaining entry.
  885. */
  886. if (hi == lo+3)
  887. {
  888. /* Because of the 'probe' code val can either be lo+1 or hi-1; we
  889. * need to test the other.
  890. */
  891. val = lo + ((val == lo+1) ? 2 : 1);
  892. assert(lo < val && val < hi);
  893. dp->stack[sp].end = 1;
  894. }
  895. else
  896. {
  897. /* There are at least 2 entries still untested between lo and hi,
  898. * i.e. hi >= lo+4. 'val' is the midpoint +/- 0.5
  899. *
  900. * Separate out the four easy cases when lo..val..hi are
  901. * monotonically decreased or (more weird) increasing:
  902. */
  903. assert(hi > lo+3);
  904. if (lo_size <= best_size && best_size <= hi_size)
  905. {
  906. /* Select the low range; testing this first favours the low
  907. * range over the high range when everything comes out equal.
  908. * Because of the probing 'val' may be lo+1. In that case end
  909. * the search and set 'val' to lo+2.
  910. */
  911. if (val == lo+1)
  912. {
  913. ++val;
  914. dp->stack[sp].end = 1;
  915. }
  916. else
  917. {
  918. dp->stack[sp].hi = hi = val;
  919. dp->stack[sp].hi_size = best_size;
  920. val = (lo + val) / 2;
  921. }
  922. }
  923. else if (lo_size >= best_size && best_size >= hi_size)
  924. {
  925. /* Monotonically decreasing size; this is the expected case.
  926. * Select the high end of the range. As above, val may be
  927. * hi-1.
  928. */
  929. if (val == hi-1)
  930. {
  931. --val;
  932. dp->stack[sp].end = 1;
  933. }
  934. else
  935. {
  936. dp->stack[sp].lo = lo = val;
  937. dp->stack[sp].lo_size = best_size;
  938. val = (val + hi) / 2;
  939. }
  940. }
  941. /* If both those tests failed 'best_size' is either greater than
  942. * or less than both lo_size and hi_size. There is a peak or dip
  943. * in the curve of sizes from lo to hi and val is on the peak or
  944. * dip.
  945. *
  946. * Because the ranges being searched as so small (level is 1..9,
  947. * windowBits 8..15, memLevel 1..9) there will only be at most
  948. * three untested values between lo..val and val..hi, so solve
  949. * the problem by probing down from hi or up from lo, whichever
  950. * is the higher.
  951. *
  952. * This is the place where 'val' is set to outside the range
  953. * lo..hi, described as 'probing', though maybe 'narrowing' would
  954. * be more accurate.
  955. */
  956. else if (lo_size <= hi_size) /* down from hi */
  957. {
  958. dp->stack[sp].hi = val;
  959. dp->stack[sp].hi_size = best_size;
  960. val = --hi;
  961. }
  962. else /* up from low */
  963. {
  964. dp->stack[sp].lo = val;
  965. dp->stack[sp].lo_size = best_size;
  966. val = ++lo;
  967. }
  968. /* lo and hi are still the true range limits, check for the end
  969. * condition.
  970. */
  971. assert(hi > lo+1);
  972. if (hi <= lo+2)
  973. dp->stack[sp].end = 1;
  974. }
  975. }
  976. assert(val != dp->stack[sp].best_val); /* should be a new value */
  977. dp->value[opt] = val;
  978. dp->stack[sp].best_size = MAX_SIZE;
  979. }
  980. }
  981. else
  982. {
  983. /* Increment 'entry' */
  984. dp->value[opt] = options[opt].values[++entry].value;
  985. dp->stack[sp].entry = entry;
  986. }
  987. set_opt_string(dp, sp);
  988. if (!search && opt_list_end(dp, opt, entry)) /* end of list */
  989. dp->stack[sp].end = 1;
  990. else if (!dp->stack[sp].end) /* still active after all these tests */
  991. dp->nsp = dp->tsp;
  992. }
  993. static int
  994. compare_option(const struct display *dp, unsigned int sp)
  995. {
  996. int opt = dp->stack[sp].opt;
  997. /* If the best so far is numerically less than the current value the
  998. * current set of options is invariably worse.
  999. */
  1000. if (dp->stack[sp].best_val < dp->value[opt])
  1001. return -1;
  1002. /* Lists of options are searched out of numerical order (currently only
  1003. * strategy), so only return +1 here when a range is being searched.
  1004. */
  1005. else if (dp->stack[sp].best_val > dp->value[opt])
  1006. {
  1007. if (dp->stack[sp].lo <= dp->stack[sp].hi /*searching*/)
  1008. return 1;
  1009. else
  1010. return -1;
  1011. }
  1012. else
  1013. return 0; /* match; current value is the best one */
  1014. }
  1015. static int
  1016. advance_opt(struct display *dp, png_byte opt, int search)
  1017. {
  1018. unsigned int sp = dp->csp++; /* my stack entry */
  1019. assert(sp >= dp->nsp); /* nsp starts off zero */
  1020. /* If the entry was active in the previous run dp->stack[sp] is already
  1021. * set up and dp->tsp will be greater than sp, otherwise a new entry
  1022. * needs to be created.
  1023. *
  1024. * dp->nsp is handled this way:
  1025. *
  1026. * 1) When an option is pushed onto the stack dp->nsp and dp->tsp are
  1027. * both set (by push_opt) to the next stack entry *unless* there is
  1028. * only one entry in the new list, in which case dp->stack[sp].end
  1029. * is set.
  1030. *
  1031. * 2) For the top stack entry next_opt is called. The entry must be
  1032. * active (dp->stack[sp].end is not set) and either 'nsp' or 'end'
  1033. * will be updated as appropriate.
  1034. *
  1035. * 3) For lower stack entries nsp is set unless the stack entry is
  1036. * already at the end. This means that when all the higher entries
  1037. * are popped this entry will be too.
  1038. */
  1039. if (sp >= dp->tsp)
  1040. {
  1041. push_opt(dp, sp, opt, search); /* This sets tsp to sp+1 */
  1042. return 1; /* initialized */
  1043. }
  1044. else
  1045. {
  1046. int ret = 0; /* unchanged */
  1047. /* An option that is already on the stack; update best_size and best_val
  1048. * if appropriate. On the first run there are no previous values and
  1049. * dp->write_size will be MAX_SIZE, however on the first run dp->tsp
  1050. * starts off as 0.
  1051. */
  1052. assert(dp->write_size > 0U && dp->write_size < MAX_SIZE);
  1053. if (dp->stack[sp].best_size > dp->write_size ||
  1054. (dp->stack[sp].best_size == dp->write_size &&
  1055. compare_option(dp, sp) > 0))
  1056. {
  1057. dp->stack[sp].best_size = dp->write_size;
  1058. dp->stack[sp].best_val = dp->value[opt];
  1059. }
  1060. if (sp+1U >= dp->tsp)
  1061. {
  1062. next_opt(dp, sp);
  1063. ret = 1; /* advanced */
  1064. }
  1065. else if (!dp->stack[sp].end) /* Active, not at top of stack */
  1066. dp->nsp = sp+1U;
  1067. return ret; /* advanced || unchanged */
  1068. }
  1069. }
  1070. static int
  1071. getallopts_(struct display *dp, png_byte opt, int *value, int record)
  1072. /* Like getop but iterate over all the values if the option was set to "all".
  1073. */
  1074. {
  1075. if (dp->entry[opt]) /* option was set on command line */
  1076. {
  1077. /* Simple, single value, entries don't have a stack frame and have a fixed
  1078. * value (it doesn't change once set on the command line). Otherwise the
  1079. * value (entry) selected from the command line is 'all':
  1080. */
  1081. const char *entry_name = options[opt].values[dp->entry[opt]-1].name;
  1082. if (entry_name == all)
  1083. (void)advance_opt(dp, opt, 0/*do not search; iterate*/);
  1084. else if (record)
  1085. record_opt(dp, opt, entry_name);
  1086. *value = dp->value[opt];
  1087. return 1; /* set */
  1088. }
  1089. else
  1090. return 0; /* not set */
  1091. }
  1092. static int
  1093. getallopts(struct display *dp, const char *opt_str, int *value)
  1094. {
  1095. return getallopts_(dp, option_index(dp, opt_str, strlen(opt_str)), value, 0);
  1096. }
  1097. static int
  1098. getsearchopts(struct display *dp, const char *opt_str, int *value)
  1099. /* As above except that if the option was not set try a search */
  1100. {
  1101. png_byte istrat;
  1102. png_byte opt = option_index(dp, opt_str, strlen(opt_str));
  1103. int record = options[opt].search;
  1104. const char *entry_name;
  1105. /* If it was set on the command line honour the setting, including 'all'
  1106. * which will override the built in search:
  1107. */
  1108. if (getallopts_(dp, opt, value, record))
  1109. return 1;
  1110. else if (!record) /* not a search option */
  1111. return 0; /* unset and not searched */
  1112. /* Otherwise decide what to do here. */
  1113. istrat = OPTIND(dp, strategy);
  1114. entry_name = range_lo; /* record the value, not the name */
  1115. if (opt == istrat) /* search all strategies */
  1116. (void)advance_opt(dp, opt, 0/*iterate*/), record=0;
  1117. else if (opt == OPTIND(dp, level))
  1118. {
  1119. /* Both RLE and HUFFMAN don't benefit from level increases */
  1120. if (dp->value[istrat] == Z_RLE || dp->value[istrat] == Z_HUFFMAN_ONLY)
  1121. dp->value[opt] = 1;
  1122. else /* fixed, filtered or default */
  1123. (void)advance_opt(dp, opt, 1/*search*/), record=0;
  1124. }
  1125. else if (opt == OPTIND(dp, windowBits))
  1126. {
  1127. /* Changing windowBits for strategies that do not search the window is
  1128. * pointless. Huffman-only does not search, RLE only searches backwards
  1129. * one byte, so given that the maximum string length is 258, a windowBits
  1130. * of 9 is always sufficient.
  1131. */
  1132. if (dp->value[istrat] == Z_HUFFMAN_ONLY)
  1133. dp->value[opt] = 8;
  1134. else if (dp->value[istrat] == Z_RLE)
  1135. dp->value[opt] = 9;
  1136. else /* fixed, filtered or default */
  1137. (void)advance_opt(dp, opt, 1/*search*/), record=0;
  1138. }
  1139. else if (opt == OPTIND(dp, memLevel))
  1140. {
  1141. # if 0
  1142. (void)advance_opt(dp, opt, 0/*all*/), record=0;
  1143. # else
  1144. dp->value[opt] = MAX_MEM_LEVEL;
  1145. # endif
  1146. }
  1147. else /* something else */
  1148. assert(0=="reached");
  1149. if (record)
  1150. record_opt(dp, opt, entry_name);
  1151. /* One of the above searched options: */
  1152. *value = dp->value[opt];
  1153. return 1;
  1154. }
  1155. static int
  1156. find_val(struct display *dp, png_byte opt, const char *str, size_t len)
  1157. /* Like option_index but sets (index+i) of the entry in options[opt] that
  1158. * matches str[0..len-1] into dp->entry[opt] as well as returning the actual
  1159. * value.
  1160. */
  1161. {
  1162. int rlo = INT_MAX, rhi = INT_MIN;
  1163. png_byte j, irange = 0;
  1164. for (j=1U; j<=options[opt].value_count; ++j)
  1165. {
  1166. if (strncmp(options[opt].values[j-1U].name, str, len) == 0 &&
  1167. options[opt].values[j-1U].name[len] == 0)
  1168. {
  1169. dp->entry[opt] = j;
  1170. return options[opt].values[j-1U].value;
  1171. }
  1172. else if (options[opt].values[j-1U].name == range_lo)
  1173. rlo = options[opt].values[j-1U].value, irange = j;
  1174. else if (options[opt].values[j-1U].name == range_hi)
  1175. rhi = options[opt].values[j-1U].value;
  1176. }
  1177. /* No match on the name, but there may be a range. */
  1178. if (irange > 0)
  1179. {
  1180. char *ep = NULL;
  1181. long l = strtol(str, &ep, 0);
  1182. if (ep == str+len && l >= rlo && l <= rhi)
  1183. {
  1184. dp->entry[opt] = irange; /* range_lo */
  1185. return (int)/*SAFE*/l;
  1186. }
  1187. }
  1188. display_log(dp, dp->errset ? INTERNAL_ERROR : USER_ERROR,
  1189. "%s: unknown value setting '%.*s'", options[opt].name,
  1190. (int)/*SAFE*/len, str);
  1191. abort(); /* NOT REACHED */
  1192. }
  1193. static int
  1194. opt_check(struct display *dp, const char *arg)
  1195. {
  1196. assert(dp->errset == 0);
  1197. if (arg != NULL && arg[0] == '-' && arg[1] == '-')
  1198. {
  1199. int i = 0, negate = (strncmp(arg+2, "no-", 3) == 0), val;
  1200. png_byte j;
  1201. if (negate)
  1202. arg += 5; /* --no- */
  1203. else
  1204. arg += 2; /* -- */
  1205. /* Find the length (expect arg\0 or arg=) */
  1206. while (arg[i] != 0 && arg[i] != '=') ++i;
  1207. /* So arg[0..i-1] is the argument name, this does not return if this isn't
  1208. * a valid option name.
  1209. */
  1210. j = option_index(dp, arg, i);
  1211. /* It matcheth an option; check the remainder. */
  1212. if (arg[i] == 0) /* no specified value, use the default */
  1213. {
  1214. val = options[j].values[negate].value;
  1215. dp->entry[j] = (png_byte)/*SAFE*/(negate + 1U);
  1216. }
  1217. else
  1218. {
  1219. const char *list = arg + (i+1);
  1220. /* Expect a single value here unless this is a list, in which case
  1221. * multiple values are combined.
  1222. */
  1223. if (options[j].opt != LIST)
  1224. {
  1225. /* find_val sets 'dp->entry[j]' to a non-zero value: */
  1226. val = find_val(dp, j, list, strlen(list));
  1227. if (negate)
  1228. {
  1229. if (options[j].opt < OPTION)
  1230. val = !val;
  1231. else
  1232. {
  1233. display_log(dp, USER_ERROR,
  1234. "%.*s: option=arg cannot be negated", i, arg);
  1235. abort(); /* NOT REACHED */
  1236. }
  1237. }
  1238. }
  1239. else /* multiple options separated by ',' characters */
  1240. {
  1241. /* --no-option negates list values from the default, which should
  1242. * therefore be 'all'. Notice that if the option list is empty in
  1243. * this case nothing will be removed and therefore --no-option= is
  1244. * the same as --option.
  1245. */
  1246. if (negate)
  1247. val = options[j].values[0].value;
  1248. else
  1249. val = 0;
  1250. while (*list != 0) /* allows option= which sets 0 */
  1251. {
  1252. /* A value is terminated by the end of the list or a ','
  1253. * character.
  1254. */
  1255. int v, iv;
  1256. iv = 0; /* an index into 'list' */
  1257. while (list[++iv] != 0 && list[iv] != ',') {}
  1258. v = find_val(dp, j, list, iv);
  1259. if (negate)
  1260. val &= ~v;
  1261. else
  1262. val |= v;
  1263. list += iv;
  1264. if (*list != 0)
  1265. ++list; /* skip the ',' */
  1266. }
  1267. }
  1268. }
  1269. /* 'val' is the new value, store it for use later and debugging: */
  1270. dp->value[j] = val;
  1271. if (options[j].opt < LEVEL_MASK)
  1272. {
  1273. /* The handling for error levels is to set the level. */
  1274. if (val) /* Set this level */
  1275. dp->options = (dp->options & ~LEVEL_MASK) | options[j].opt;
  1276. else
  1277. display_log(dp, USER_ERROR,
  1278. "%.*s: messages cannot be turned off individually; set a message level",
  1279. i, arg);
  1280. }
  1281. else if (options[j].opt < OPTION)
  1282. {
  1283. if (val)
  1284. dp->options |= options[j].opt;
  1285. else
  1286. dp->options &= ~options[j].opt;
  1287. }
  1288. return 1; /* this is an option */
  1289. }
  1290. else
  1291. return 0; /* not an option */
  1292. }
  1293. #ifdef PNG_PNGCP_TIMING_SUPPORTED
  1294. static void
  1295. set_timer(struct display *dp, struct timespec *timer)
  1296. {
  1297. /* Do the timing using clock_gettime and the per-process timer. */
  1298. if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, timer))
  1299. {
  1300. display_log(dp, APP_ERROR,
  1301. "CLOCK_PROCESS_CPUTIME_ID: %s: timing disabled\n", strerror(errno));
  1302. dp->value[OPTIND(dp,time)] = 0; /* i.e. off */
  1303. }
  1304. }
  1305. static void
  1306. start_timer(struct display *dp, int what)
  1307. {
  1308. if ((dp->value[OPTIND(dp,time)] & what) != 0)
  1309. set_timer(dp, what == PNGCP_TIME_READ ? &dp->read_time : &dp->write_time);
  1310. }
  1311. static void
  1312. end_timer(struct display *dp, int what)
  1313. {
  1314. if ((dp->value[OPTIND(dp,time)] & what) != 0)
  1315. {
  1316. struct timespec t, tmp;
  1317. set_timer(dp, &t);
  1318. if (what == PNGCP_TIME_READ)
  1319. tmp = dp->read_time;
  1320. else
  1321. tmp = dp->write_time;
  1322. t.tv_sec -= tmp.tv_sec;
  1323. t.tv_nsec -= tmp.tv_nsec;
  1324. if (t.tv_nsec < 0)
  1325. {
  1326. --(t.tv_sec);
  1327. t.tv_nsec += 1000000000L;
  1328. }
  1329. if (what == PNGCP_TIME_READ)
  1330. dp->read_time = t, tmp = dp->read_time_total;
  1331. else
  1332. dp->write_time = t, tmp = dp->write_time_total;
  1333. tmp.tv_sec += t.tv_sec;
  1334. tmp.tv_nsec += t.tv_nsec;
  1335. if (tmp.tv_nsec >= 1000000000L)
  1336. {
  1337. ++(tmp.tv_sec);
  1338. tmp.tv_nsec -= 1000000000L;
  1339. }
  1340. if (what == PNGCP_TIME_READ)
  1341. dp->read_time_total = tmp;
  1342. else
  1343. dp->write_time_total = tmp;
  1344. }
  1345. }
  1346. static void
  1347. print_time(const char *what, struct timespec t)
  1348. {
  1349. printf("%s %.2lu.%.9ld", what, (unsigned long)t.tv_sec, t.tv_nsec);
  1350. }
  1351. #else /* !PNGCP_TIMING */
  1352. #define start_timer(dp, what) ((void)0)
  1353. #define end_timer(dp, what) ((void)0)
  1354. #endif /* !PNGCP_TIMING */
  1355. /* The following is used in main to verify that the final argument is a
  1356. * directory:
  1357. */
  1358. static int
  1359. checkdir(const char *pathname)
  1360. {
  1361. struct stat buf;
  1362. return stat(pathname, &buf) == 0 && S_ISDIR(buf.st_mode);
  1363. }
  1364. /* Work out whether a path is valid (if not a display_log occurs), a directory
  1365. * (1 is returned) or a file *or* non-existent (0 is returned).
  1366. *
  1367. * Used for a write path.
  1368. */
  1369. static int
  1370. isdir(struct display *dp, const char *pathname)
  1371. {
  1372. if (pathname == NULL)
  1373. return 0; /* stdout */
  1374. else if (pathname[0] == 0)
  1375. return 1; /* empty string */
  1376. else
  1377. {
  1378. struct stat buf;
  1379. int ret = stat(pathname, &buf);
  1380. if (ret == 0) /* the entry exists */
  1381. {
  1382. if (S_ISDIR(buf.st_mode))
  1383. return 1;
  1384. /* Else expect an object that exists and can be written: */
  1385. if (access(pathname, W_OK) != 0)
  1386. display_log(dp, USER_ERROR, "%s: cannot be written (%s)", pathname,
  1387. strerror(errno));
  1388. return 0; /* file (exists, can be written) */
  1389. }
  1390. else /* an error */
  1391. {
  1392. /* Non-existence is fine, other errors are not: */
  1393. if (errno != ENOENT)
  1394. display_log(dp, USER_ERROR, "%s: invalid output name (%s)",
  1395. pathname, strerror(errno));
  1396. return 0; /* file (does not exist) */
  1397. }
  1398. }
  1399. }
  1400. static void
  1401. makename(struct display *dp, const char *dir, const char *infile)
  1402. {
  1403. /* Make a name for an output file (and check it). */
  1404. dp->namebuf[0] = 0;
  1405. if (dir == NULL || infile == NULL)
  1406. display_log(dp, INTERNAL_ERROR, "NULL name to makename");
  1407. else
  1408. {
  1409. size_t dsize = strlen(dir);
  1410. if (dsize <= (sizeof dp->namebuf)-2) /* Allow for name + '/' + '\0' */
  1411. {
  1412. size_t isize = strlen(infile);
  1413. size_t istart = isize-1;
  1414. /* This should fail before here: */
  1415. if (infile[istart] == '/')
  1416. display_log(dp, INTERNAL_ERROR, "infile with trailing /");
  1417. memcpy(dp->namebuf, dir, dsize);
  1418. if (dsize > 0 && dp->namebuf[dsize-1] != '/')
  1419. dp->namebuf[dsize++] = '/';
  1420. /* Find the rightmost non-/ character: */
  1421. while (istart > 0 && infile[istart-1] != '/')
  1422. --istart;
  1423. isize -= istart;
  1424. infile += istart;
  1425. if (dsize+isize < (sizeof dp->namebuf)) /* dsize + infile + '\0' */
  1426. {
  1427. memcpy(dp->namebuf+dsize, infile, isize+1);
  1428. if (isdir(dp, dp->namebuf))
  1429. display_log(dp, USER_ERROR, "%s: output file is a directory",
  1430. dp->namebuf);
  1431. }
  1432. else
  1433. {
  1434. dp->namebuf[dsize] = 0; /* allowed for: -2 at start */
  1435. display_log(dp, USER_ERROR, "%s%s: output file name too long",
  1436. dp->namebuf, infile);
  1437. }
  1438. }
  1439. else
  1440. display_log(dp, USER_ERROR, "%s: output directory name too long", dir);
  1441. }
  1442. }
  1443. /* error handler callbacks for libpng */
  1444. static void PNGCBAPI
  1445. display_warning(png_structp pp, png_const_charp warning)
  1446. {
  1447. struct display *dp = get_dp(pp);
  1448. /* This is used to prevent repeated warnings while searching */
  1449. if (!dp->no_warnings)
  1450. display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning);
  1451. }
  1452. static void PNGCBAPI
  1453. display_error(png_structp pp, png_const_charp error)
  1454. {
  1455. struct display *dp = get_dp(pp);
  1456. display_log(dp, LIBPNG_ERROR, "%s", error);
  1457. }
  1458. static void
  1459. display_start_read(struct display *dp, const char *filename)
  1460. {
  1461. if (filename != NULL)
  1462. {
  1463. dp->filename = filename;
  1464. dp->fp = fopen(filename, "rb");
  1465. }
  1466. else
  1467. {
  1468. dp->filename = "<stdin>";
  1469. dp->fp = stdin;
  1470. }
  1471. dp->w = dp->h = 0U;
  1472. dp->bpp = 0U;
  1473. dp->size = 0U;
  1474. dp->read_size = 0U;
  1475. if (dp->fp == NULL)
  1476. display_log(dp, USER_ERROR, "file open failed (%s)", strerror(errno));
  1477. }
  1478. static void PNGCBAPI
  1479. read_function(png_structp pp, png_bytep data, size_t size)
  1480. {
  1481. struct display *dp = get_dp(pp);
  1482. if (size == 0U || fread(data, size, 1U, dp->fp) == 1U)
  1483. dp->read_size += size;
  1484. else
  1485. {
  1486. if (feof(dp->fp))
  1487. display_log(dp, LIBPNG_ERROR, "PNG file truncated");
  1488. else
  1489. display_log(dp, LIBPNG_ERROR, "PNG file read failed (%s)",
  1490. strerror(errno));
  1491. }
  1492. }
  1493. static void
  1494. read_png(struct display *dp, const char *filename)
  1495. {
  1496. display_clean_read(dp); /* safety */
  1497. display_start_read(dp, filename);
  1498. dp->read_pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
  1499. display_error, display_warning);
  1500. if (dp->read_pp == NULL)
  1501. display_log(dp, LIBPNG_ERROR, "failed to create read struct");
  1502. # ifdef PNG_BENIGN_ERRORS_SUPPORTED
  1503. png_set_benign_errors(dp->read_pp, 1/*allowed*/);
  1504. # endif /* BENIGN_ERRORS */
  1505. # ifdef FIX_INDEX
  1506. if ((dp->options & FIX_INDEX) != 0)
  1507. png_set_check_for_invalid_index(dp->read_pp, 1/*on, no warning*/);
  1508. # ifdef IGNORE_INDEX
  1509. else
  1510. # endif /* IGNORE_INDEX */
  1511. # endif /* FIX_INDEX */
  1512. # ifdef IGNORE_INDEX
  1513. if ((dp->options & IGNORE_INDEX) != 0) /* DANGEROUS */
  1514. png_set_check_for_invalid_index(dp->read_pp, -1/*off completely*/);
  1515. # endif /* IGNORE_INDEX */
  1516. /* The png_read_png API requires us to make the info struct, but it does the
  1517. * call to png_read_info.
  1518. */
  1519. dp->ip = png_create_info_struct(dp->read_pp);
  1520. if (dp->ip == NULL)
  1521. png_error(dp->read_pp, "failed to create info struct");
  1522. /* Set the IO handling */
  1523. png_set_read_fn(dp->read_pp, dp, read_function);
  1524. # ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  1525. png_set_keep_unknown_chunks(dp->read_pp, PNG_HANDLE_CHUNK_ALWAYS, NULL,
  1526. 0);
  1527. # endif /* HANDLE_AS_UNKNOWN */
  1528. # ifdef PNG_SET_USER_LIMITS_SUPPORTED
  1529. /* Remove the user limits, if any */
  1530. png_set_user_limits(dp->read_pp, 0x7fffffff, 0x7fffffff);
  1531. # endif /* SET_USER_LIMITS */
  1532. /* Now read the PNG. */
  1533. start_timer(dp, PNGCP_TIME_READ);
  1534. png_read_png(dp->read_pp, dp->ip, 0U/*transforms*/, NULL/*params*/);
  1535. end_timer(dp, PNGCP_TIME_READ);
  1536. dp->w = png_get_image_width(dp->read_pp, dp->ip);
  1537. dp->h = png_get_image_height(dp->read_pp, dp->ip);
  1538. dp->ct = png_get_color_type(dp->read_pp, dp->ip);
  1539. dp->bpp = png_get_bit_depth(dp->read_pp, dp->ip) *
  1540. png_get_channels(dp->read_pp, dp->ip);
  1541. {
  1542. /* png_get_rowbytes should never return 0 because the value is set by the
  1543. * first call to png_set_IHDR, which should have happened by now, but just
  1544. * in case:
  1545. */
  1546. png_alloc_size_t rb = png_get_rowbytes(dp->read_pp, dp->ip);
  1547. if (rb == 0)
  1548. png_error(dp->read_pp, "invalid row byte count from libpng");
  1549. /* The size calc can overflow. */
  1550. if ((MAX_SIZE-dp->h)/rb < dp->h)
  1551. png_error(dp->read_pp, "image too large");
  1552. dp->size = rb * dp->h + dp->h/*filter byte*/;
  1553. }
  1554. #ifdef FIX_INDEX
  1555. if (dp->ct == PNG_COLOR_TYPE_PALETTE && (dp->options & FIX_INDEX) != 0)
  1556. {
  1557. int max = png_get_palette_max(dp->read_pp, dp->ip);
  1558. png_colorp palette = NULL;
  1559. int num = -1;
  1560. if (png_get_PLTE(dp->read_pp, dp->ip, &palette, &num) != PNG_INFO_PLTE
  1561. || max < 0 || num <= 0 || palette == NULL)
  1562. display_log(dp, LIBPNG_ERROR, "invalid png_get_PLTE result");
  1563. if (max >= num)
  1564. {
  1565. /* 'Fix' the palette. */
  1566. int i;
  1567. png_color newpal[256];
  1568. for (i=0; i<num; ++i)
  1569. newpal[i] = palette[i];
  1570. /* Fill in any remainder with a warning color: */
  1571. for (; i<=max; ++i)
  1572. {
  1573. newpal[i].red = 0xbe;
  1574. newpal[i].green = 0xad;
  1575. newpal[i].blue = 0xed;
  1576. }
  1577. png_set_PLTE(dp->read_pp, dp->ip, newpal, i);
  1578. }
  1579. }
  1580. #endif /* FIX_INDEX */
  1581. display_clean_read(dp);
  1582. dp->operation = "none";
  1583. }
  1584. static void
  1585. display_start_write(struct display *dp, const char *filename)
  1586. {
  1587. assert(dp->fp == NULL);
  1588. if ((dp->options & NOWRITE) != 0)
  1589. dp->output_file = "<no write>";
  1590. else
  1591. {
  1592. if (filename != NULL)
  1593. {
  1594. dp->output_file = filename;
  1595. dp->fp = fopen(filename, "wb");
  1596. }
  1597. else
  1598. {
  1599. dp->output_file = "<stdout>";
  1600. dp->fp = stdout;
  1601. }
  1602. if (dp->fp == NULL)
  1603. display_log(dp, USER_ERROR, "%s: file open failed (%s)",
  1604. dp->output_file, strerror(errno));
  1605. }
  1606. }
  1607. static void PNGCBAPI
  1608. write_function(png_structp pp, png_bytep data, size_t size)
  1609. {
  1610. struct display *dp = get_dp(pp);
  1611. /* The write fail is classed as a USER_ERROR, so --quiet does not turn it
  1612. * off, this seems more likely to be correct.
  1613. */
  1614. if (dp->fp == NULL || fwrite(data, size, 1U, dp->fp) == 1U)
  1615. {
  1616. dp->write_size += size;
  1617. if (dp->write_size < size || dp->write_size == MAX_SIZE)
  1618. png_error(pp, "IDAT size overflow");
  1619. }
  1620. else
  1621. display_log(dp, USER_ERROR, "%s: PNG file write failed (%s)",
  1622. dp->output_file, strerror(errno));
  1623. }
  1624. /* Compression option, 'method' is never set: there is no choice.
  1625. *
  1626. * IMPORTANT: the order of the entries in this macro determines the preference
  1627. * order when two different combos of two of these options produce an IDAT of
  1628. * the same size. The logic here is to put the things that affect the decoding
  1629. * of the PNG image ahead of those that are relevant only to the encoding.
  1630. */
  1631. #define SET_COMPRESSION\
  1632. SET(strategy, strategy);\
  1633. SET(windowBits, window_bits);\
  1634. SET(level, level);\
  1635. SET(memLevel, mem_level);
  1636. #ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
  1637. static void
  1638. search_compression(struct display *dp)
  1639. {
  1640. /* Like set_compression below but use a more restricted search than 'all' */
  1641. int val;
  1642. # define SET(name, func) if (getsearchopts(dp, #name, &val))\
  1643. png_set_compression_ ## func(dp->write_pp, val);
  1644. SET_COMPRESSION
  1645. # undef SET
  1646. }
  1647. static void
  1648. set_compression(struct display *dp)
  1649. {
  1650. int val;
  1651. # define SET(name, func) if (getallopts(dp, #name, &val))\
  1652. png_set_compression_ ## func(dp->write_pp, val);
  1653. SET_COMPRESSION
  1654. # undef SET
  1655. }
  1656. #ifdef PNG_SW_COMPRESS_level /* 1.7.0+ */
  1657. static void
  1658. set_ICC_profile_compression(struct display *dp)
  1659. {
  1660. int val;
  1661. # define SET(name, func) if (getallopts(dp, "ICC-profile-" #name, &val))\
  1662. png_set_ICC_profile_compression_ ## func(dp->write_pp, val);
  1663. SET_COMPRESSION
  1664. # undef SET
  1665. }
  1666. #else
  1667. # define set_ICC_profile_compression(dp) ((void)0)
  1668. #endif
  1669. #else
  1670. # define search_compression(dp) ((void)0)
  1671. # define set_compression(dp) ((void)0)
  1672. # define set_ICC_profile_compression(dp) ((void)0)
  1673. #endif /* WRITE_CUSTOMIZE_COMPRESSION */
  1674. #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
  1675. static void
  1676. set_text_compression(struct display *dp)
  1677. {
  1678. int val;
  1679. # define SET(name, func) if (getallopts(dp, "text-" #name, &val))\
  1680. png_set_text_compression_ ## func(dp->write_pp, val);
  1681. SET_COMPRESSION
  1682. # undef SET
  1683. }
  1684. #else
  1685. # define set_text_compression(dp) ((void)0)
  1686. #endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
  1687. static void
  1688. write_png(struct display *dp, const char *destname)
  1689. {
  1690. display_clean_write(dp); /* safety */
  1691. display_start_write(dp, destname);
  1692. dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
  1693. display_error, display_warning);
  1694. if (dp->write_pp == NULL)
  1695. display_log(dp, LIBPNG_ERROR, "failed to create write png_struct");
  1696. # ifdef PNG_BENIGN_ERRORS_SUPPORTED
  1697. png_set_benign_errors(dp->write_pp, 1/*allowed*/);
  1698. # endif /* BENIGN_ERRORS */
  1699. png_set_write_fn(dp->write_pp, dp, write_function, NULL/*flush*/);
  1700. #ifdef IGNORE_INDEX
  1701. if ((dp->options & IGNORE_INDEX) != 0) /* DANGEROUS */
  1702. png_set_check_for_invalid_index(dp->write_pp, -1/*off completely*/);
  1703. #endif /* IGNORE_INDEX */
  1704. /* Restore the text chunks when using libpng 1.6 or less; this is a macro
  1705. * which expands to nothing in 1.7+ In earlier versions it tests
  1706. * dp->text_stashed, which is only set (below) *after* the first write.
  1707. */
  1708. text_restore(dp);
  1709. # ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
  1710. png_set_keep_unknown_chunks(dp->write_pp, PNG_HANDLE_CHUNK_ALWAYS, NULL,
  1711. 0);
  1712. # endif /* HANDLE_AS_UNKNOWN */
  1713. # ifdef PNG_SET_USER_LIMITS_SUPPORTED
  1714. /* Remove the user limits, if any */
  1715. png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);
  1716. # endif
  1717. /* OPTION HANDLING */
  1718. /* compression outputs, IDAT and zTXt/iTXt: */
  1719. dp->tsp = dp->nsp;
  1720. dp->nsp = dp->csp = 0;
  1721. # ifdef PNG_SW_COMPRESS_png_level
  1722. {
  1723. int val;
  1724. /* This sets everything, but then the following options just override
  1725. * the specific settings for ICC profiles and text.
  1726. */
  1727. if (getallopts(dp, "compression", &val))
  1728. png_set_compression(dp->write_pp, val);
  1729. if (getallopts(dp, "ICC-profile-compression", &val))
  1730. png_set_ICC_profile_compression(dp->write_pp, val);
  1731. if (getallopts(dp, "text-compression", &val))
  1732. png_set_text_compression(dp->write_pp, val);
  1733. }
  1734. # endif /* png_level support */
  1735. if (dp->options & SEARCH)
  1736. search_compression(dp);
  1737. else
  1738. set_compression(dp);
  1739. set_ICC_profile_compression(dp);
  1740. set_text_compression(dp);
  1741. {
  1742. int val;
  1743. /* The permitted range is 1..0x7FFFFFFF, so the cast is safe */
  1744. if (get_option(dp, "IDAT-size", &val))
  1745. png_set_IDAT_size(dp->write_pp, val);
  1746. }
  1747. /* filter handling */
  1748. # ifdef PNG_WRITE_FILTER_SUPPORTED
  1749. {
  1750. int val;
  1751. if (get_option(dp, "filter", &val))
  1752. png_set_filter(dp->write_pp, PNG_FILTER_TYPE_BASE, val);
  1753. }
  1754. # endif /* WRITE_FILTER */
  1755. /* This just uses the 'read' info_struct directly, it contains the image. */
  1756. dp->write_size = 0U;
  1757. start_timer(dp, PNGCP_TIME_WRITE);
  1758. png_write_png(dp->write_pp, dp->ip, 0U/*transforms*/, NULL/*params*/);
  1759. end_timer(dp, PNGCP_TIME_WRITE);
  1760. /* Make sure the file was written ok: */
  1761. if (dp->fp != NULL)
  1762. {
  1763. FILE *fp = dp->fp;
  1764. dp->fp = NULL;
  1765. if (fclose(fp))
  1766. display_log(dp, APP_ERROR, "%s: write failed (%s)",
  1767. destname == NULL ? "stdout" : destname, strerror(errno));
  1768. }
  1769. /* Clean it on the way out - if control returns to the caller then the
  1770. * written_file contains the required data.
  1771. */
  1772. display_clean_write(dp);
  1773. dp->operation = "none";
  1774. }
  1775. static void
  1776. set_windowBits_hi(struct display *dp)
  1777. {
  1778. /* windowBits is in the range 8..15 but zlib maps '8' to '9' so it is only
  1779. * worth using if the data size is 256 byte or less.
  1780. */
  1781. int wb = MAX_WBITS; /* for large images */
  1782. int i = VLSIZE(windowBits_IDAT);
  1783. while (wb > 8 && dp->size <= 1U<<(wb-1)) --wb;
  1784. while (--i >= 0) if (VLNAME(windowBits_IDAT)[i].name == range_hi) break;
  1785. assert(i > 1); /* vl_windowBits_IDAT always has a RANGE() */
  1786. VLNAME(windowBits_IDAT)[i].value = wb;
  1787. assert(VLNAME(windowBits_IDAT)[--i].name == range_lo);
  1788. VLNAME(windowBits_IDAT)[i].value = wb > 8 ? 9 : 8;
  1789. /* If wb == 8 then any search has been restricted to just one windowBits
  1790. * entry. Record that here to avoid producing a spurious app-level warning
  1791. * above.
  1792. */
  1793. if (wb == 8)
  1794. dp->min_windowBits = OPTIND(dp, windowBits);
  1795. }
  1796. static int
  1797. better_options(const struct display *dp)
  1798. {
  1799. /* Are these options better than the best found so far? Normally the
  1800. * options are tested in preference order, best first, however when doing a
  1801. * search operation on a range the range values are tested out of order. In
  1802. * that case preferable options will get tested later.
  1803. *
  1804. * This function looks through the stack from the bottom up looking for an
  1805. * option that does not match the current best value. When it finds one it
  1806. * checks to see if it is more or less desirable and returns true or false
  1807. * as appropriate.
  1808. *
  1809. * Notice that this means that the order options are pushed onto the stack
  1810. * conveys a priority; lower/earlier options are more important than later
  1811. * ones.
  1812. */
  1813. unsigned int sp;
  1814. for (sp=0; sp<dp->csp; ++sp)
  1815. {
  1816. int c = compare_option(dp, sp);
  1817. if (c < 0)
  1818. return 0; /* worse */
  1819. else if (c > 0)
  1820. return 1; /* better */
  1821. }
  1822. assert(0 && "unreached");
  1823. }
  1824. static void
  1825. print_search_results(struct display *dp)
  1826. {
  1827. assert(dp->filename != NULL);
  1828. printf("%s [%ld x %ld %d bpp %s, %lu bytes] %lu -> %lu with '%s'\n",
  1829. dp->filename, (unsigned long)dp->w, (unsigned long)dp->h, dp->bpp,
  1830. cts(dp->ct), (unsigned long)dp->size, (unsigned long)dp->read_size,
  1831. (unsigned long)dp->best_size, dp->best);
  1832. fflush(stdout);
  1833. }
  1834. static void
  1835. log_search(struct display *dp, unsigned int log_depth)
  1836. {
  1837. /* Log, and reset, the search so far: */
  1838. if (dp->nsp/*next entry to change*/ <= log_depth)
  1839. {
  1840. print_search_results(dp);
  1841. /* Start again with this entry: */
  1842. dp->best_size = MAX_SIZE;
  1843. }
  1844. }
  1845. static void
  1846. cp_one_file(struct display *dp, const char *filename, const char *destname)
  1847. {
  1848. unsigned int log_depth;
  1849. dp->filename = filename;
  1850. dp->operation = "read";
  1851. dp->no_warnings = 0;
  1852. /* Read it then write it: */
  1853. if (filename != NULL && access(filename, R_OK) != 0)
  1854. display_log(dp, USER_ERROR, "%s: invalid file name (%s)",
  1855. filename, strerror(errno));
  1856. read_png(dp, filename);
  1857. /* But 'destname' may be a directory. */
  1858. dp->operation = "write";
  1859. /* Limit the upper end of the windowBits range for this file */
  1860. set_windowBits_hi(dp);
  1861. /* For logging, depth to log: */
  1862. {
  1863. int val;
  1864. if (get_option(dp, "log-depth", &val) && val >= 0)
  1865. log_depth = (unsigned int)/*SAFE*/val;
  1866. else
  1867. log_depth = 0U;
  1868. }
  1869. if (destname != NULL) /* else stdout */
  1870. {
  1871. if (isdir(dp, destname))
  1872. {
  1873. makename(dp, destname, filename);
  1874. destname = dp->namebuf;
  1875. }
  1876. else if (access(destname, W_OK) != 0 && errno != ENOENT)
  1877. display_log(dp, USER_ERROR, "%s: invalid output name (%s)", destname,
  1878. strerror(errno));
  1879. }
  1880. dp->nsp = 0;
  1881. dp->curr[0] = 0; /* acts as a flag for the caller */
  1882. dp->opt_string_start = 0;
  1883. dp->best[0] = 0; /* safety */
  1884. dp->best_size = MAX_SIZE;
  1885. write_png(dp, destname);
  1886. /* Initialize the 'best' fields: */
  1887. strcpy(dp->best, dp->curr);
  1888. dp->best_size = dp->write_size;
  1889. if (dp->nsp > 0) /* iterating over lists */
  1890. {
  1891. char *tmpname, tmpbuf[(sizeof dp->namebuf) + 4];
  1892. assert(dp->curr[0] == ' ' && dp->tsp > 0);
  1893. /* Cancel warnings on subsequent writes */
  1894. log_search(dp, log_depth);
  1895. dp->no_warnings = 1;
  1896. /* Make a temporary name for the subsequent tests: */
  1897. if (destname != NULL)
  1898. {
  1899. strcpy(tmpbuf, destname);
  1900. strcat(tmpbuf, ".tmp"); /* space for .tmp allocated above */
  1901. tmpname = tmpbuf;
  1902. }
  1903. else
  1904. tmpname = NULL; /* stdout */
  1905. /* Loop to find the best option. */
  1906. do
  1907. {
  1908. write_png(dp, tmpname);
  1909. /* And compare the sizes (the write function makes sure write_size
  1910. * doesn't overflow.)
  1911. */
  1912. assert(dp->csp > 0);
  1913. if (dp->write_size < dp->best_size ||
  1914. (dp->write_size == dp->best_size && better_options(dp)))
  1915. {
  1916. if (destname != NULL && rename(tmpname, destname) != 0)
  1917. display_log(dp, APP_ERROR, "rename %s %s failed (%s)", tmpname,
  1918. destname, strerror(errno));
  1919. strcpy(dp->best, dp->curr);
  1920. dp->best_size = dp->write_size;
  1921. }
  1922. else if (tmpname != NULL && unlink(tmpname) != 0)
  1923. display_log(dp, APP_WARNING, "unlink %s failed (%s)", tmpname,
  1924. strerror(errno));
  1925. log_search(dp, log_depth);
  1926. }
  1927. while (dp->nsp > 0);
  1928. /* Do this for the 'sizes' option so that it reports the correct size. */
  1929. dp->write_size = dp->best_size;
  1930. }
  1931. }
  1932. static int
  1933. cppng(struct display *dp, const char *file, const char *gv dest)
  1934. /* Exists solely to isolate the setjmp clobbers which some versions of GCC
  1935. * erroneously generate.
  1936. */
  1937. {
  1938. int ret = setjmp(dp->error_return);
  1939. if (ret == 0)
  1940. {
  1941. dp->errset = 1;
  1942. cp_one_file(dp, file, dest);
  1943. dp->errset = 0;
  1944. return 0;
  1945. }
  1946. else
  1947. {
  1948. dp->errset = 0;
  1949. if (ret < ERRORS) /* shouldn't longjmp on warnings */
  1950. display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);
  1951. return ret;
  1952. }
  1953. }
  1954. int
  1955. main(int argc, char **argv)
  1956. {
  1957. /* For each file on the command line test it with a range of transforms */
  1958. int option_end;
  1959. struct display d;
  1960. display_init(&d);
  1961. d.operation = "options";
  1962. for (option_end = 1;
  1963. option_end < argc && opt_check(&d, argv[option_end]);
  1964. ++option_end)
  1965. {
  1966. }
  1967. /* Do a quick check on the directory target case; when there are more than
  1968. * two arguments the last one must be a directory.
  1969. */
  1970. if (!(d.options & NOWRITE) && option_end+2 < argc && !checkdir(argv[argc-1]))
  1971. {
  1972. fprintf(stderr,
  1973. "pngcp: %s: directory required with more than two arguments\n",
  1974. argv[argc-1]);
  1975. return 99;
  1976. }
  1977. {
  1978. int errors = 0;
  1979. int i = option_end;
  1980. /* Do this at least once; if there are no arguments stdin/stdout are used.
  1981. */
  1982. d.operation = "files";
  1983. do
  1984. {
  1985. const char *infile = NULL;
  1986. const char *outfile = NULL;
  1987. int ret;
  1988. if (i < argc)
  1989. {
  1990. infile = argv[i++];
  1991. if (!(d.options & NOWRITE) && i < argc)
  1992. outfile = argv[argc-1];
  1993. }
  1994. ret = cppng(&d, infile, outfile);
  1995. if (ret)
  1996. {
  1997. if (ret > QUIET) /* abort on user or internal error */
  1998. return 99;
  1999. /* An error: the output is meaningless */
  2000. }
  2001. else if (d.best[0] != 0)
  2002. {
  2003. /* This result may already have been output, in which case best_size
  2004. * has been reset.
  2005. */
  2006. if (d.best_size < MAX_SIZE)
  2007. print_search_results(&d);
  2008. }
  2009. else if (d.options & SIZES)
  2010. {
  2011. printf("%s [%ld x %ld %d bpp %s, %lu bytes] %lu -> %lu [0x%lx]\n",
  2012. infile, (unsigned long)d.w, (unsigned long)d.h, d.bpp,
  2013. cts(d.ct), (unsigned long)d.size, (unsigned long)d.read_size,
  2014. (unsigned long)d.write_size, (unsigned long)d.results);
  2015. fflush(stdout);
  2016. }
  2017. /* Here on any return, including failures, except user/internal issues
  2018. */
  2019. {
  2020. int pass = (d.options & STRICT) ?
  2021. RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);
  2022. if (!pass)
  2023. ++errors;
  2024. if (d.options & LOG)
  2025. {
  2026. int j;
  2027. printf("%s: pngcp", pass ? "PASS" : "FAIL");
  2028. for (j=1; j<option_end; ++j)
  2029. printf(" %s", argv[j]);
  2030. if (infile != NULL)
  2031. printf(" %s", infile);
  2032. # ifdef PNG_PNGCP_TIMING_SUPPORTED
  2033. /* When logging output the files for each file, if enabled. */
  2034. if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_READ) != 0)
  2035. print_time(" read", d.read_time);
  2036. if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_WRITE) != 0)
  2037. print_time(" write", d.write_time);
  2038. # endif /* PNGCP_TIMING */
  2039. printf("\n");
  2040. fflush(stdout);
  2041. }
  2042. }
  2043. display_clean(&d);
  2044. }
  2045. while (i+!(d.options & NOWRITE) < argc);
  2046. /* I.e. for write cases after the first time through the loop require
  2047. * there to be at least two arguments left and for the last one to be a
  2048. * directory (this was checked above).
  2049. */
  2050. /* Release allocated memory */
  2051. display_destroy(&d);
  2052. # ifdef PNG_PNGCP_TIMING_SUPPORTED
  2053. {
  2054. int output = 0;
  2055. if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_READ) != 0)
  2056. print_time("read", d.read_time_total), output = 1;
  2057. if ((d.value[OPTIND(&d,time)] & PNGCP_TIME_WRITE) != 0)
  2058. {
  2059. if (output) putchar(' ');
  2060. print_time("write", d.write_time_total);
  2061. output = 1;
  2062. }
  2063. if (output) putchar('\n');
  2064. }
  2065. # endif /* PNGCP_TIMING */
  2066. return errors != 0;
  2067. }
  2068. }
  2069. #else /* !READ_PNG || !WRITE_PNG */
  2070. int
  2071. main(void)
  2072. {
  2073. fprintf(stderr, "pngcp: no support for png_read/write_image\n");
  2074. return 77;
  2075. }
  2076. #endif /* !READ_PNG || !WRITE_PNG */