pngtest.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821
  1. /* pngtest.c - a simple test program to test libpng
  2. *
  3. * Last changed in libpng 1.5.6 [November 3, 2011]
  4. * Copyright (c) 1998-2011 Glenn Randers-Pehrson
  5. * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  6. * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  7. *
  8. * This code is released under the libpng license.
  9. * For conditions of distribution and use, see the disclaimer
  10. * and license in png.h
  11. *
  12. * This program reads in a PNG image, writes it out again, and then
  13. * compares the two files. If the files are identical, this shows that
  14. * the basic chunk handling, filtering, and (de)compression code is working
  15. * properly. It does not currently test all of the transforms, although
  16. * it probably should.
  17. *
  18. * The program will report "FAIL" in certain legitimate cases:
  19. * 1) when the compression level or filter selection method is changed.
  20. * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
  21. * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
  22. * exist in the input file.
  23. * 4) others not listed here...
  24. * In these cases, it is best to check with another tool such as "pngcheck"
  25. * to see what the differences between the two files are.
  26. *
  27. * If a filename is given on the command-line, then this file is used
  28. * for the input, rather than the default "pngtest.png". This allows
  29. * testing a wide variety of files easily. You can also test a number
  30. * of files at once by typing "pngtest -m file1.png file2.png ..."
  31. */
  32. #define _POSIX_SOURCE 1
  33. #include "zlib.h"
  34. #include "png.h"
  35. /* Copied from pngpriv.h but only used in error messages below. */
  36. #ifndef PNG_ZBUF_SIZE
  37. # define PNG_ZBUF_SIZE 8192
  38. #endif
  39. # include <stdio.h>
  40. # include <stdlib.h>
  41. # include <string.h>
  42. # define FCLOSE(file) fclose(file)
  43. #ifndef PNG_STDIO_SUPPORTED
  44. typedef FILE * png_FILE_p;
  45. #endif
  46. /* Makes pngtest verbose so we can find problems. */
  47. #ifndef PNG_DEBUG
  48. # define PNG_DEBUG 0
  49. #endif
  50. #if PNG_DEBUG > 1
  51. # define pngtest_debug(m) ((void)fprintf(stderr, m "\n"))
  52. # define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1))
  53. # define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2))
  54. #else
  55. # define pngtest_debug(m) ((void)0)
  56. # define pngtest_debug1(m,p1) ((void)0)
  57. # define pngtest_debug2(m,p1,p2) ((void)0)
  58. #endif
  59. #if !PNG_DEBUG
  60. # define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */
  61. #endif
  62. /* The code uses memcmp and memcpy on large objects (typically row pointers) so
  63. * it is necessary to do soemthing special on certain architectures, note that
  64. * the actual support for this was effectively removed in 1.4, so only the
  65. * memory remains in this program:
  66. */
  67. #define CVT_PTR(ptr) (ptr)
  68. #define CVT_PTR_NOCHECK(ptr) (ptr)
  69. #define png_memcmp memcmp
  70. #define png_memcpy memcpy
  71. #define png_memset memset
  72. /* Turn on CPU timing
  73. #define PNGTEST_TIMING
  74. */
  75. #ifndef PNG_FLOATING_POINT_SUPPORTED
  76. #undef PNGTEST_TIMING
  77. #endif
  78. #ifdef PNGTEST_TIMING
  79. static float t_start, t_stop, t_decode, t_encode, t_misc;
  80. #include <time.h>
  81. #endif
  82. #ifdef PNG_TIME_RFC1123_SUPPORTED
  83. #define PNG_tIME_STRING_LENGTH 29
  84. static int tIME_chunk_present = 0;
  85. static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
  86. #endif
  87. static int verbose = 0;
  88. static int strict = 0;
  89. int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
  90. #ifdef __TURBOC__
  91. #include <mem.h>
  92. #endif
  93. /* Defined so I can write to a file on gui/windowing platforms */
  94. /* #define STDERR stderr */
  95. #define STDERR stdout /* For DOS */
  96. /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
  97. #ifndef png_jmpbuf
  98. # define png_jmpbuf(png_ptr) png_ptr->jmpbuf
  99. #endif
  100. /* Example of using row callbacks to make a simple progress meter */
  101. static int status_pass = 1;
  102. static int status_dots_requested = 0;
  103. static int status_dots = 1;
  104. void PNGCBAPI
  105. read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
  106. void PNGCBAPI
  107. read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
  108. {
  109. if (png_ptr == NULL || row_number > PNG_UINT_31_MAX)
  110. return;
  111. if (status_pass != pass)
  112. {
  113. fprintf(stdout, "\n Pass %d: ", pass);
  114. status_pass = pass;
  115. status_dots = 31;
  116. }
  117. status_dots--;
  118. if (status_dots == 0)
  119. {
  120. fprintf(stdout, "\n ");
  121. status_dots=30;
  122. }
  123. fprintf(stdout, "r");
  124. }
  125. void PNGCBAPI
  126. write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
  127. void PNGCBAPI
  128. write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
  129. {
  130. if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7)
  131. return;
  132. fprintf(stdout, "w");
  133. }
  134. #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
  135. /* Example of using user transform callback (we don't transform anything,
  136. * but merely examine the row filters. We set this to 256 rather than
  137. * 5 in case illegal filter values are present.)
  138. */
  139. static png_uint_32 filters_used[256];
  140. void PNGCBAPI
  141. count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
  142. void PNGCBAPI
  143. count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
  144. {
  145. if (png_ptr != NULL && row_info != NULL)
  146. ++filters_used[*(data - 1)];
  147. }
  148. #endif
  149. #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
  150. /* Example of using user transform callback (we don't transform anything,
  151. * but merely count the zero samples)
  152. */
  153. static png_uint_32 zero_samples;
  154. void PNGCBAPI
  155. count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
  156. void PNGCBAPI
  157. count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
  158. {
  159. png_bytep dp = data;
  160. if (png_ptr == NULL)
  161. return;
  162. /* Contents of row_info:
  163. * png_uint_32 width width of row
  164. * png_uint_32 rowbytes number of bytes in row
  165. * png_byte color_type color type of pixels
  166. * png_byte bit_depth bit depth of samples
  167. * png_byte channels number of channels (1-4)
  168. * png_byte pixel_depth bits per pixel (depth*channels)
  169. */
  170. /* Counts the number of zero samples (or zero pixels if color_type is 3 */
  171. if (row_info->color_type == 0 || row_info->color_type == 3)
  172. {
  173. int pos = 0;
  174. png_uint_32 n, nstop;
  175. for (n = 0, nstop=row_info->width; n<nstop; n++)
  176. {
  177. if (row_info->bit_depth == 1)
  178. {
  179. if (((*dp << pos++ ) & 0x80) == 0)
  180. zero_samples++;
  181. if (pos == 8)
  182. {
  183. pos = 0;
  184. dp++;
  185. }
  186. }
  187. if (row_info->bit_depth == 2)
  188. {
  189. if (((*dp << (pos+=2)) & 0xc0) == 0)
  190. zero_samples++;
  191. if (pos == 8)
  192. {
  193. pos = 0;
  194. dp++;
  195. }
  196. }
  197. if (row_info->bit_depth == 4)
  198. {
  199. if (((*dp << (pos+=4)) & 0xf0) == 0)
  200. zero_samples++;
  201. if (pos == 8)
  202. {
  203. pos = 0;
  204. dp++;
  205. }
  206. }
  207. if (row_info->bit_depth == 8)
  208. if (*dp++ == 0)
  209. zero_samples++;
  210. if (row_info->bit_depth == 16)
  211. {
  212. if ((*dp | *(dp+1)) == 0)
  213. zero_samples++;
  214. dp+=2;
  215. }
  216. }
  217. }
  218. else /* Other color types */
  219. {
  220. png_uint_32 n, nstop;
  221. int channel;
  222. int color_channels = row_info->channels;
  223. if (row_info->color_type > 3)color_channels--;
  224. for (n = 0, nstop=row_info->width; n<nstop; n++)
  225. {
  226. for (channel = 0; channel < color_channels; channel++)
  227. {
  228. if (row_info->bit_depth == 8)
  229. if (*dp++ == 0)
  230. zero_samples++;
  231. if (row_info->bit_depth == 16)
  232. {
  233. if ((*dp | *(dp+1)) == 0)
  234. zero_samples++;
  235. dp+=2;
  236. }
  237. }
  238. if (row_info->color_type > 3)
  239. {
  240. dp++;
  241. if (row_info->bit_depth == 16)
  242. dp++;
  243. }
  244. }
  245. }
  246. }
  247. #endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
  248. static int wrote_question = 0;
  249. #ifndef PNG_STDIO_SUPPORTED
  250. /* START of code to validate stdio-free compilation */
  251. /* These copies of the default read/write functions come from pngrio.c and
  252. * pngwio.c. They allow "don't include stdio" testing of the library.
  253. * This is the function that does the actual reading of data. If you are
  254. * not reading from a standard C stream, you should create a replacement
  255. * read_data function and use it at run time with png_set_read_fn(), rather
  256. * than changing the library.
  257. */
  258. #ifdef PNG_IO_STATE_SUPPORTED
  259. void
  260. pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
  261. png_uint_32 io_op);
  262. void
  263. pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
  264. png_uint_32 io_op)
  265. {
  266. png_uint_32 io_state = png_get_io_state(png_ptr);
  267. int err = 0;
  268. /* Check if the current operation (reading / writing) is as expected. */
  269. if ((io_state & PNG_IO_MASK_OP) != io_op)
  270. png_error(png_ptr, "Incorrect operation in I/O state");
  271. /* Check if the buffer size specific to the current location
  272. * (file signature / header / data / crc) is as expected.
  273. */
  274. switch (io_state & PNG_IO_MASK_LOC)
  275. {
  276. case PNG_IO_SIGNATURE:
  277. if (data_length > 8)
  278. err = 1;
  279. break;
  280. case PNG_IO_CHUNK_HDR:
  281. if (data_length != 8)
  282. err = 1;
  283. break;
  284. case PNG_IO_CHUNK_DATA:
  285. break; /* no restrictions here */
  286. case PNG_IO_CHUNK_CRC:
  287. if (data_length != 4)
  288. err = 1;
  289. break;
  290. default:
  291. err = 1; /* uninitialized */
  292. }
  293. if (err)
  294. png_error(png_ptr, "Bad I/O state or buffer size");
  295. }
  296. #endif
  297. #ifndef USE_FAR_KEYWORD
  298. static void PNGCBAPI
  299. pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  300. {
  301. png_size_t check = 0;
  302. png_voidp io_ptr;
  303. /* fread() returns 0 on error, so it is OK to store this in a png_size_t
  304. * instead of an int, which is what fread() actually returns.
  305. */
  306. io_ptr = png_get_io_ptr(png_ptr);
  307. if (io_ptr != NULL)
  308. {
  309. check = fread(data, 1, length, (png_FILE_p)io_ptr);
  310. }
  311. if (check != length)
  312. {
  313. png_error(png_ptr, "Read Error");
  314. }
  315. #ifdef PNG_IO_STATE_SUPPORTED
  316. pngtest_check_io_state(png_ptr, length, PNG_IO_READING);
  317. #endif
  318. }
  319. #else
  320. /* This is the model-independent version. Since the standard I/O library
  321. can't handle far buffers in the medium and small models, we have to copy
  322. the data.
  323. */
  324. #define NEAR_BUF_SIZE 1024
  325. #define MIN(a,b) (a <= b ? a : b)
  326. static void PNGCBAPI
  327. pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  328. {
  329. png_size_t check;
  330. png_byte *n_data;
  331. png_FILE_p io_ptr;
  332. /* Check if data really is near. If so, use usual code. */
  333. n_data = (png_byte *)CVT_PTR_NOCHECK(data);
  334. io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr));
  335. if ((png_bytep)n_data == data)
  336. {
  337. check = fread(n_data, 1, length, io_ptr);
  338. }
  339. else
  340. {
  341. png_byte buf[NEAR_BUF_SIZE];
  342. png_size_t read, remaining, err;
  343. check = 0;
  344. remaining = length;
  345. do
  346. {
  347. read = MIN(NEAR_BUF_SIZE, remaining);
  348. err = fread(buf, 1, 1, io_ptr);
  349. png_memcpy(data, buf, read); /* Copy far buffer to near buffer */
  350. if (err != read)
  351. break;
  352. else
  353. check += err;
  354. data += read;
  355. remaining -= read;
  356. }
  357. while (remaining != 0);
  358. }
  359. if (check != length)
  360. png_error(png_ptr, "Read Error");
  361. #ifdef PNG_IO_STATE_SUPPORTED
  362. pngtest_check_io_state(png_ptr, length, PNG_IO_READING);
  363. #endif
  364. }
  365. #endif /* USE_FAR_KEYWORD */
  366. #ifdef PNG_WRITE_FLUSH_SUPPORTED
  367. static void PNGCBAPI
  368. pngtest_flush(png_structp png_ptr)
  369. {
  370. /* Do nothing; fflush() is said to be just a waste of energy. */
  371. PNG_UNUSED(png_ptr) /* Stifle compiler warning */
  372. }
  373. #endif
  374. /* This is the function that does the actual writing of data. If you are
  375. * not writing to a standard C stream, you should create a replacement
  376. * write_data function and use it at run time with png_set_write_fn(), rather
  377. * than changing the library.
  378. */
  379. #ifndef USE_FAR_KEYWORD
  380. static void PNGCBAPI
  381. pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  382. {
  383. png_size_t check;
  384. check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr));
  385. if (check != length)
  386. {
  387. png_error(png_ptr, "Write Error");
  388. }
  389. #ifdef PNG_IO_STATE_SUPPORTED
  390. pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
  391. #endif
  392. }
  393. #else
  394. /* This is the model-independent version. Since the standard I/O library
  395. can't handle far buffers in the medium and small models, we have to copy
  396. the data.
  397. */
  398. #define NEAR_BUF_SIZE 1024
  399. #define MIN(a,b) (a <= b ? a : b)
  400. static void PNGCBAPI
  401. pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  402. {
  403. png_size_t check;
  404. png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
  405. png_FILE_p io_ptr;
  406. /* Check if data really is near. If so, use usual code. */
  407. near_data = (png_byte *)CVT_PTR_NOCHECK(data);
  408. io_ptr = (png_FILE_p)CVT_PTR(png_get_io_ptr(png_ptr));
  409. if ((png_bytep)near_data == data)
  410. {
  411. check = fwrite(near_data, 1, length, io_ptr);
  412. }
  413. else
  414. {
  415. png_byte buf[NEAR_BUF_SIZE];
  416. png_size_t written, remaining, err;
  417. check = 0;
  418. remaining = length;
  419. do
  420. {
  421. written = MIN(NEAR_BUF_SIZE, remaining);
  422. png_memcpy(buf, data, written); /* Copy far buffer to near buffer */
  423. err = fwrite(buf, 1, written, io_ptr);
  424. if (err != written)
  425. break;
  426. else
  427. check += err;
  428. data += written;
  429. remaining -= written;
  430. }
  431. while (remaining != 0);
  432. }
  433. if (check != length)
  434. {
  435. png_error(png_ptr, "Write Error");
  436. }
  437. #ifdef PNG_IO_STATE_SUPPORTED
  438. pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
  439. #endif
  440. }
  441. #endif /* USE_FAR_KEYWORD */
  442. /* This function is called when there is a warning, but the library thinks
  443. * it can continue anyway. Replacement functions don't have to do anything
  444. * here if you don't want to. In the default configuration, png_ptr is
  445. * not used, but it is passed in case it may be useful.
  446. */
  447. static void PNGCBAPI
  448. pngtest_warning(png_structp png_ptr, png_const_charp message)
  449. {
  450. PNG_CONST char *name = "UNKNOWN (ERROR!)";
  451. char *test;
  452. test = png_get_error_ptr(png_ptr);
  453. if (test == NULL)
  454. fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
  455. else
  456. fprintf(STDERR, "%s: libpng warning: %s\n", test, message);
  457. }
  458. /* This is the default error handling function. Note that replacements for
  459. * this function MUST NOT RETURN, or the program will likely crash. This
  460. * function is used by default, or if the program supplies NULL for the
  461. * error function pointer in png_set_error_fn().
  462. */
  463. static void PNGCBAPI
  464. pngtest_error(png_structp png_ptr, png_const_charp message)
  465. {
  466. pngtest_warning(png_ptr, message);
  467. /* We can return because png_error calls the default handler, which is
  468. * actually OK in this case.
  469. */
  470. }
  471. #endif /* !PNG_STDIO_SUPPORTED */
  472. /* END of code to validate stdio-free compilation */
  473. /* START of code to validate memory allocation and deallocation */
  474. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  475. /* Allocate memory. For reasonable files, size should never exceed
  476. * 64K. However, zlib may allocate more then 64K if you don't tell
  477. * it not to. See zconf.h and png.h for more information. zlib does
  478. * need to allocate exactly 64K, so whatever you call here must
  479. * have the ability to do that.
  480. *
  481. * This piece of code can be compiled to validate max 64K allocations
  482. * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
  483. */
  484. typedef struct memory_information
  485. {
  486. png_alloc_size_t size;
  487. png_voidp pointer;
  488. struct memory_information FAR *next;
  489. } memory_information;
  490. typedef memory_information FAR *memory_infop;
  491. static memory_infop pinformation = NULL;
  492. static int current_allocation = 0;
  493. static int maximum_allocation = 0;
  494. static int total_allocation = 0;
  495. static int num_allocations = 0;
  496. png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr,
  497. png_alloc_size_t size));
  498. void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
  499. png_voidp
  500. PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
  501. {
  502. /* png_malloc has already tested for NULL; png_create_struct calls
  503. * png_debug_malloc directly, with png_ptr == NULL which is OK
  504. */
  505. if (size == 0)
  506. return (NULL);
  507. /* This calls the library allocator twice, once to get the requested
  508. buffer and once to get a new free list entry. */
  509. {
  510. /* Disable malloc_fn and free_fn */
  511. memory_infop pinfo;
  512. png_set_mem_fn(png_ptr, NULL, NULL, NULL);
  513. pinfo = (memory_infop)png_malloc(png_ptr,
  514. png_sizeof(*pinfo));
  515. pinfo->size = size;
  516. current_allocation += size;
  517. total_allocation += size;
  518. num_allocations ++;
  519. if (current_allocation > maximum_allocation)
  520. maximum_allocation = current_allocation;
  521. pinfo->pointer = png_malloc(png_ptr, size);
  522. /* Restore malloc_fn and free_fn */
  523. png_set_mem_fn(png_ptr,
  524. NULL, png_debug_malloc, png_debug_free);
  525. if (size != 0 && pinfo->pointer == NULL)
  526. {
  527. current_allocation -= size;
  528. total_allocation -= size;
  529. png_error(png_ptr,
  530. "out of memory in pngtest->png_debug_malloc");
  531. }
  532. pinfo->next = pinformation;
  533. pinformation = pinfo;
  534. /* Make sure the caller isn't assuming zeroed memory. */
  535. png_memset(pinfo->pointer, 0xdd, pinfo->size);
  536. if (verbose)
  537. printf("png_malloc %lu bytes at %p\n", (unsigned long)size,
  538. pinfo->pointer);
  539. return (png_voidp)(pinfo->pointer);
  540. }
  541. }
  542. /* Free a pointer. It is removed from the list at the same time. */
  543. void PNGCBAPI
  544. png_debug_free(png_structp png_ptr, png_voidp ptr)
  545. {
  546. if (png_ptr == NULL)
  547. fprintf(STDERR, "NULL pointer to png_debug_free.\n");
  548. if (ptr == 0)
  549. {
  550. #if 0 /* This happens all the time. */
  551. fprintf(STDERR, "WARNING: freeing NULL pointer\n");
  552. #endif
  553. return;
  554. }
  555. /* Unlink the element from the list. */
  556. {
  557. memory_infop FAR *ppinfo = &pinformation;
  558. for (;;)
  559. {
  560. memory_infop pinfo = *ppinfo;
  561. if (pinfo->pointer == ptr)
  562. {
  563. *ppinfo = pinfo->next;
  564. current_allocation -= pinfo->size;
  565. if (current_allocation < 0)
  566. fprintf(STDERR, "Duplicate free of memory\n");
  567. /* We must free the list element too, but first kill
  568. the memory that is to be freed. */
  569. png_memset(ptr, 0x55, pinfo->size);
  570. png_free_default(png_ptr, pinfo);
  571. pinfo = NULL;
  572. break;
  573. }
  574. if (pinfo->next == NULL)
  575. {
  576. fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
  577. break;
  578. }
  579. ppinfo = &pinfo->next;
  580. }
  581. }
  582. /* Finally free the data. */
  583. if (verbose)
  584. printf("Freeing %p\n", ptr);
  585. png_free_default(png_ptr, ptr);
  586. ptr = NULL;
  587. }
  588. #endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */
  589. /* END of code to test memory allocation/deallocation */
  590. /* Demonstration of user chunk support of the sTER and vpAg chunks */
  591. #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
  592. /* (sTER is a public chunk not yet known by libpng. vpAg is a private
  593. chunk used in ImageMagick to store "virtual page" size). */
  594. static png_uint_32 user_chunk_data[4];
  595. /* 0: sTER mode + 1
  596. * 1: vpAg width
  597. * 2: vpAg height
  598. * 3: vpAg units
  599. */
  600. static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
  601. png_unknown_chunkp chunk)
  602. {
  603. png_uint_32
  604. *my_user_chunk_data;
  605. /* Return one of the following:
  606. * return (-n); chunk had an error
  607. * return (0); did not recognize
  608. * return (n); success
  609. *
  610. * The unknown chunk structure contains the chunk data:
  611. * png_byte name[5];
  612. * png_byte *data;
  613. * png_size_t size;
  614. *
  615. * Note that libpng has already taken care of the CRC handling.
  616. */
  617. if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */
  618. chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */
  619. {
  620. /* Found sTER chunk */
  621. if (chunk->size != 1)
  622. return (-1); /* Error return */
  623. if (chunk->data[0] != 0 && chunk->data[0] != 1)
  624. return (-1); /* Invalid mode */
  625. my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
  626. my_user_chunk_data[0]=chunk->data[0]+1;
  627. return (1);
  628. }
  629. if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */
  630. chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */
  631. return (0); /* Did not recognize */
  632. /* Found ImageMagick vpAg chunk */
  633. if (chunk->size != 9)
  634. return (-1); /* Error return */
  635. my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr);
  636. my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data);
  637. my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4);
  638. my_user_chunk_data[3]=(png_uint_32)chunk->data[8];
  639. return (1);
  640. }
  641. #endif
  642. /* END of code to demonstrate user chunk support */
  643. /* Test one file */
  644. int
  645. test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
  646. {
  647. static png_FILE_p fpin;
  648. static png_FILE_p fpout; /* "static" prevents setjmp corruption */
  649. png_structp read_ptr;
  650. png_infop read_info_ptr, end_info_ptr;
  651. #ifdef PNG_WRITE_SUPPORTED
  652. png_structp write_ptr;
  653. png_infop write_info_ptr;
  654. png_infop write_end_info_ptr;
  655. #else
  656. png_structp write_ptr = NULL;
  657. png_infop write_info_ptr = NULL;
  658. png_infop write_end_info_ptr = NULL;
  659. #endif
  660. png_bytep row_buf;
  661. png_uint_32 y;
  662. png_uint_32 width, height;
  663. int num_pass, pass;
  664. int bit_depth, color_type;
  665. #ifdef PNG_SETJMP_SUPPORTED
  666. #ifdef USE_FAR_KEYWORD
  667. jmp_buf tmp_jmpbuf;
  668. #endif
  669. #endif
  670. char inbuf[256], outbuf[256];
  671. row_buf = NULL;
  672. if ((fpin = fopen(inname, "rb")) == NULL)
  673. {
  674. fprintf(STDERR, "Could not find input file %s\n", inname);
  675. return (1);
  676. }
  677. if ((fpout = fopen(outname, "wb")) == NULL)
  678. {
  679. fprintf(STDERR, "Could not open output file %s\n", outname);
  680. FCLOSE(fpin);
  681. return (1);
  682. }
  683. pngtest_debug("Allocating read and write structures");
  684. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  685. read_ptr =
  686. png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
  687. NULL, NULL, NULL, png_debug_malloc, png_debug_free);
  688. #else
  689. read_ptr =
  690. png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  691. #endif
  692. #ifndef PNG_STDIO_SUPPORTED
  693. png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
  694. pngtest_warning);
  695. #endif
  696. #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
  697. user_chunk_data[0] = 0;
  698. user_chunk_data[1] = 0;
  699. user_chunk_data[2] = 0;
  700. user_chunk_data[3] = 0;
  701. png_set_read_user_chunk_fn(read_ptr, user_chunk_data,
  702. read_user_chunk_callback);
  703. #endif
  704. #ifdef PNG_WRITE_SUPPORTED
  705. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  706. write_ptr =
  707. png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
  708. NULL, NULL, NULL, png_debug_malloc, png_debug_free);
  709. #else
  710. write_ptr =
  711. png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  712. #endif
  713. #ifndef PNG_STDIO_SUPPORTED
  714. png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
  715. pngtest_warning);
  716. #endif
  717. #endif
  718. pngtest_debug("Allocating read_info, write_info and end_info structures");
  719. read_info_ptr = png_create_info_struct(read_ptr);
  720. end_info_ptr = png_create_info_struct(read_ptr);
  721. #ifdef PNG_WRITE_SUPPORTED
  722. write_info_ptr = png_create_info_struct(write_ptr);
  723. write_end_info_ptr = png_create_info_struct(write_ptr);
  724. #endif
  725. #ifdef PNG_SETJMP_SUPPORTED
  726. pngtest_debug("Setting jmpbuf for read struct");
  727. #ifdef USE_FAR_KEYWORD
  728. if (setjmp(tmp_jmpbuf))
  729. #else
  730. if (setjmp(png_jmpbuf(read_ptr)))
  731. #endif
  732. {
  733. fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
  734. png_free(read_ptr, row_buf);
  735. row_buf = NULL;
  736. png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
  737. #ifdef PNG_WRITE_SUPPORTED
  738. png_destroy_info_struct(write_ptr, &write_end_info_ptr);
  739. png_destroy_write_struct(&write_ptr, &write_info_ptr);
  740. #endif
  741. FCLOSE(fpin);
  742. FCLOSE(fpout);
  743. return (1);
  744. }
  745. #ifdef USE_FAR_KEYWORD
  746. png_memcpy(png_jmpbuf(read_ptr), tmp_jmpbuf, png_sizeof(jmp_buf));
  747. #endif
  748. #ifdef PNG_WRITE_SUPPORTED
  749. pngtest_debug("Setting jmpbuf for write struct");
  750. #ifdef USE_FAR_KEYWORD
  751. if (setjmp(tmp_jmpbuf))
  752. #else
  753. if (setjmp(png_jmpbuf(write_ptr)))
  754. #endif
  755. {
  756. fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
  757. png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
  758. png_destroy_info_struct(write_ptr, &write_end_info_ptr);
  759. #ifdef PNG_WRITE_SUPPORTED
  760. png_destroy_write_struct(&write_ptr, &write_info_ptr);
  761. #endif
  762. FCLOSE(fpin);
  763. FCLOSE(fpout);
  764. return (1);
  765. }
  766. #ifdef USE_FAR_KEYWORD
  767. png_memcpy(png_jmpbuf(write_ptr), tmp_jmpbuf, png_sizeof(jmp_buf));
  768. #endif
  769. #endif
  770. #endif
  771. pngtest_debug("Initializing input and output streams");
  772. #ifdef PNG_STDIO_SUPPORTED
  773. png_init_io(read_ptr, fpin);
  774. # ifdef PNG_WRITE_SUPPORTED
  775. png_init_io(write_ptr, fpout);
  776. # endif
  777. #else
  778. png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
  779. # ifdef PNG_WRITE_SUPPORTED
  780. png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
  781. # ifdef PNG_WRITE_FLUSH_SUPPORTED
  782. pngtest_flush);
  783. # else
  784. NULL);
  785. # endif
  786. # endif
  787. #endif
  788. #ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
  789. /* Normally one would use Z_DEFAULT_STRATEGY for text compression.
  790. * This is here just to make pngtest replicate the results from libpng
  791. * versions prior to 1.5.4, and to test this new API.
  792. */
  793. png_set_text_compression_strategy(write_ptr, Z_FILTERED);
  794. #endif
  795. if (status_dots_requested == 1)
  796. {
  797. #ifdef PNG_WRITE_SUPPORTED
  798. png_set_write_status_fn(write_ptr, write_row_callback);
  799. #endif
  800. png_set_read_status_fn(read_ptr, read_row_callback);
  801. }
  802. else
  803. {
  804. #ifdef PNG_WRITE_SUPPORTED
  805. png_set_write_status_fn(write_ptr, NULL);
  806. #endif
  807. png_set_read_status_fn(read_ptr, NULL);
  808. }
  809. #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
  810. {
  811. int i;
  812. for (i = 0; i<256; i++)
  813. filters_used[i] = 0;
  814. png_set_read_user_transform_fn(read_ptr, count_filters);
  815. }
  816. #endif
  817. #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
  818. zero_samples = 0;
  819. png_set_write_user_transform_fn(write_ptr, count_zero_samples);
  820. #endif
  821. #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  822. # ifndef PNG_HANDLE_CHUNK_ALWAYS
  823. # define PNG_HANDLE_CHUNK_ALWAYS 3
  824. # endif
  825. png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
  826. NULL, 0);
  827. #endif
  828. #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
  829. # ifndef PNG_HANDLE_CHUNK_IF_SAFE
  830. # define PNG_HANDLE_CHUNK_IF_SAFE 2
  831. # endif
  832. png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
  833. NULL, 0);
  834. #endif
  835. pngtest_debug("Reading info struct");
  836. png_read_info(read_ptr, read_info_ptr);
  837. pngtest_debug("Transferring info struct");
  838. {
  839. int interlace_type, compression_type, filter_type;
  840. if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
  841. &color_type, &interlace_type, &compression_type, &filter_type))
  842. {
  843. png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
  844. #ifdef PNG_WRITE_INTERLACING_SUPPORTED
  845. color_type, interlace_type, compression_type, filter_type);
  846. #else
  847. color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
  848. #endif
  849. }
  850. }
  851. #ifdef PNG_FIXED_POINT_SUPPORTED
  852. #ifdef PNG_cHRM_SUPPORTED
  853. {
  854. png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
  855. blue_y;
  856. if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
  857. &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y))
  858. {
  859. png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
  860. red_y, green_x, green_y, blue_x, blue_y);
  861. }
  862. }
  863. #endif
  864. #ifdef PNG_gAMA_SUPPORTED
  865. {
  866. png_fixed_point gamma;
  867. if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
  868. png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
  869. }
  870. #endif
  871. #else /* Use floating point versions */
  872. #ifdef PNG_FLOATING_POINT_SUPPORTED
  873. #ifdef PNG_cHRM_SUPPORTED
  874. {
  875. double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
  876. blue_y;
  877. if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
  878. &red_y, &green_x, &green_y, &blue_x, &blue_y))
  879. {
  880. png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
  881. red_y, green_x, green_y, blue_x, blue_y);
  882. }
  883. }
  884. #endif
  885. #ifdef PNG_gAMA_SUPPORTED
  886. {
  887. double gamma;
  888. if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
  889. png_set_gAMA(write_ptr, write_info_ptr, gamma);
  890. }
  891. #endif
  892. #endif /* Floating point */
  893. #endif /* Fixed point */
  894. #ifdef PNG_iCCP_SUPPORTED
  895. {
  896. png_charp name;
  897. png_bytep profile;
  898. png_uint_32 proflen;
  899. int compression_type;
  900. if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
  901. &profile, &proflen))
  902. {
  903. png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
  904. profile, proflen);
  905. }
  906. }
  907. #endif
  908. #ifdef PNG_sRGB_SUPPORTED
  909. {
  910. int intent;
  911. if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
  912. png_set_sRGB(write_ptr, write_info_ptr, intent);
  913. }
  914. #endif
  915. {
  916. png_colorp palette;
  917. int num_palette;
  918. if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
  919. png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
  920. }
  921. #ifdef PNG_bKGD_SUPPORTED
  922. {
  923. png_color_16p background;
  924. if (png_get_bKGD(read_ptr, read_info_ptr, &background))
  925. {
  926. png_set_bKGD(write_ptr, write_info_ptr, background);
  927. }
  928. }
  929. #endif
  930. #ifdef PNG_hIST_SUPPORTED
  931. {
  932. png_uint_16p hist;
  933. if (png_get_hIST(read_ptr, read_info_ptr, &hist))
  934. png_set_hIST(write_ptr, write_info_ptr, hist);
  935. }
  936. #endif
  937. #ifdef PNG_oFFs_SUPPORTED
  938. {
  939. png_int_32 offset_x, offset_y;
  940. int unit_type;
  941. if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
  942. &unit_type))
  943. {
  944. png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
  945. }
  946. }
  947. #endif
  948. #ifdef PNG_pCAL_SUPPORTED
  949. {
  950. png_charp purpose, units;
  951. png_charpp params;
  952. png_int_32 X0, X1;
  953. int type, nparams;
  954. if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
  955. &nparams, &units, &params))
  956. {
  957. png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
  958. nparams, units, params);
  959. }
  960. }
  961. #endif
  962. #ifdef PNG_pHYs_SUPPORTED
  963. {
  964. png_uint_32 res_x, res_y;
  965. int unit_type;
  966. if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
  967. png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
  968. }
  969. #endif
  970. #ifdef PNG_sBIT_SUPPORTED
  971. {
  972. png_color_8p sig_bit;
  973. if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
  974. png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
  975. }
  976. #endif
  977. #ifdef PNG_sCAL_SUPPORTED
  978. #ifdef PNG_FLOATING_POINT_SUPPORTED
  979. {
  980. int unit;
  981. double scal_width, scal_height;
  982. if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
  983. &scal_height))
  984. {
  985. png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
  986. }
  987. }
  988. #else
  989. #ifdef PNG_FIXED_POINT_SUPPORTED
  990. {
  991. int unit;
  992. png_charp scal_width, scal_height;
  993. if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
  994. &scal_height))
  995. {
  996. png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
  997. scal_height);
  998. }
  999. }
  1000. #endif
  1001. #endif
  1002. #endif
  1003. #ifdef PNG_TEXT_SUPPORTED
  1004. {
  1005. png_textp text_ptr;
  1006. int num_text;
  1007. if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
  1008. {
  1009. pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
  1010. if (verbose)
  1011. printf("\n Text compression=%d\n", text_ptr->compression);
  1012. png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
  1013. }
  1014. }
  1015. #endif
  1016. #ifdef PNG_tIME_SUPPORTED
  1017. {
  1018. png_timep mod_time;
  1019. if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
  1020. {
  1021. png_set_tIME(write_ptr, write_info_ptr, mod_time);
  1022. #ifdef PNG_TIME_RFC1123_SUPPORTED
  1023. /* We have to use png_memcpy instead of "=" because the string
  1024. * pointed to by png_convert_to_rfc1123() gets free'ed before
  1025. * we use it.
  1026. */
  1027. png_memcpy(tIME_string,
  1028. png_convert_to_rfc1123(read_ptr, mod_time),
  1029. png_sizeof(tIME_string));
  1030. tIME_string[png_sizeof(tIME_string) - 1] = '\0';
  1031. tIME_chunk_present++;
  1032. #endif /* PNG_TIME_RFC1123_SUPPORTED */
  1033. }
  1034. }
  1035. #endif
  1036. #ifdef PNG_tRNS_SUPPORTED
  1037. {
  1038. png_bytep trans_alpha;
  1039. int num_trans;
  1040. png_color_16p trans_color;
  1041. if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,
  1042. &trans_color))
  1043. {
  1044. int sample_max = (1 << bit_depth);
  1045. /* libpng doesn't reject a tRNS chunk with out-of-range samples */
  1046. if (!((color_type == PNG_COLOR_TYPE_GRAY &&
  1047. (int)trans_color->gray > sample_max) ||
  1048. (color_type == PNG_COLOR_TYPE_RGB &&
  1049. ((int)trans_color->red > sample_max ||
  1050. (int)trans_color->green > sample_max ||
  1051. (int)trans_color->blue > sample_max))))
  1052. png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans,
  1053. trans_color);
  1054. }
  1055. }
  1056. #endif
  1057. #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
  1058. {
  1059. png_unknown_chunkp unknowns;
  1060. int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
  1061. &unknowns);
  1062. if (num_unknowns)
  1063. {
  1064. int i;
  1065. png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
  1066. num_unknowns);
  1067. /* Copy the locations from the read_info_ptr. The automatically
  1068. * generated locations in write_info_ptr are wrong because we
  1069. * haven't written anything yet.
  1070. */
  1071. for (i = 0; i < num_unknowns; i++)
  1072. png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
  1073. unknowns[i].location);
  1074. }
  1075. }
  1076. #endif
  1077. #ifdef PNG_WRITE_SUPPORTED
  1078. pngtest_debug("Writing info struct");
  1079. /* If we wanted, we could write info in two steps:
  1080. * png_write_info_before_PLTE(write_ptr, write_info_ptr);
  1081. */
  1082. png_write_info(write_ptr, write_info_ptr);
  1083. #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
  1084. if (user_chunk_data[0] != 0)
  1085. {
  1086. png_byte png_sTER[5] = {115, 84, 69, 82, '\0'};
  1087. unsigned char
  1088. ster_chunk_data[1];
  1089. if (verbose)
  1090. fprintf(STDERR, "\n stereo mode = %lu\n",
  1091. (unsigned long)(user_chunk_data[0] - 1));
  1092. ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1);
  1093. png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1);
  1094. }
  1095. if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0)
  1096. {
  1097. png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'};
  1098. unsigned char
  1099. vpag_chunk_data[9];
  1100. if (verbose)
  1101. fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n",
  1102. (unsigned long)user_chunk_data[1],
  1103. (unsigned long)user_chunk_data[2],
  1104. (unsigned long)user_chunk_data[3]);
  1105. png_save_uint_32(vpag_chunk_data, user_chunk_data[1]);
  1106. png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]);
  1107. vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff);
  1108. png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9);
  1109. }
  1110. #endif
  1111. #endif
  1112. #ifdef SINGLE_ROWBUF_ALLOC
  1113. pngtest_debug("Allocating row buffer...");
  1114. row_buf = (png_bytep)png_malloc(read_ptr,
  1115. png_get_rowbytes(read_ptr, read_info_ptr));
  1116. pngtest_debug1("\t0x%08lx", (unsigned long)row_buf);
  1117. #endif /* SINGLE_ROWBUF_ALLOC */
  1118. pngtest_debug("Writing row data");
  1119. #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
  1120. defined(PNG_WRITE_INTERLACING_SUPPORTED)
  1121. num_pass = png_set_interlace_handling(read_ptr);
  1122. # ifdef PNG_WRITE_SUPPORTED
  1123. png_set_interlace_handling(write_ptr);
  1124. # endif
  1125. #else
  1126. num_pass = 1;
  1127. #endif
  1128. #ifdef PNGTEST_TIMING
  1129. t_stop = (float)clock();
  1130. t_misc += (t_stop - t_start);
  1131. t_start = t_stop;
  1132. #endif
  1133. for (pass = 0; pass < num_pass; pass++)
  1134. {
  1135. pngtest_debug1("Writing row data for pass %d", pass);
  1136. for (y = 0; y < height; y++)
  1137. {
  1138. #ifndef SINGLE_ROWBUF_ALLOC
  1139. pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
  1140. row_buf = (png_bytep)png_malloc(read_ptr,
  1141. png_get_rowbytes(read_ptr, read_info_ptr));
  1142. pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf,
  1143. png_get_rowbytes(read_ptr, read_info_ptr));
  1144. #endif /* !SINGLE_ROWBUF_ALLOC */
  1145. png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
  1146. #ifdef PNG_WRITE_SUPPORTED
  1147. #ifdef PNGTEST_TIMING
  1148. t_stop = (float)clock();
  1149. t_decode += (t_stop - t_start);
  1150. t_start = t_stop;
  1151. #endif
  1152. png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
  1153. #ifdef PNGTEST_TIMING
  1154. t_stop = (float)clock();
  1155. t_encode += (t_stop - t_start);
  1156. t_start = t_stop;
  1157. #endif
  1158. #endif /* PNG_WRITE_SUPPORTED */
  1159. #ifndef SINGLE_ROWBUF_ALLOC
  1160. pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
  1161. png_free(read_ptr, row_buf);
  1162. row_buf = NULL;
  1163. #endif /* !SINGLE_ROWBUF_ALLOC */
  1164. }
  1165. }
  1166. #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  1167. png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
  1168. #endif
  1169. #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
  1170. png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
  1171. #endif
  1172. pngtest_debug("Reading and writing end_info data");
  1173. png_read_end(read_ptr, end_info_ptr);
  1174. #ifdef PNG_TEXT_SUPPORTED
  1175. {
  1176. png_textp text_ptr;
  1177. int num_text;
  1178. if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
  1179. {
  1180. pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
  1181. png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
  1182. }
  1183. }
  1184. #endif
  1185. #ifdef PNG_tIME_SUPPORTED
  1186. {
  1187. png_timep mod_time;
  1188. if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
  1189. {
  1190. png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
  1191. #ifdef PNG_TIME_RFC1123_SUPPORTED
  1192. /* We have to use png_memcpy instead of "=" because the string
  1193. pointed to by png_convert_to_rfc1123() gets free'ed before
  1194. we use it */
  1195. png_memcpy(tIME_string,
  1196. png_convert_to_rfc1123(read_ptr, mod_time),
  1197. png_sizeof(tIME_string));
  1198. tIME_string[png_sizeof(tIME_string) - 1] = '\0';
  1199. tIME_chunk_present++;
  1200. #endif /* PNG_TIME_RFC1123_SUPPORTED */
  1201. }
  1202. }
  1203. #endif
  1204. #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
  1205. {
  1206. png_unknown_chunkp unknowns;
  1207. int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
  1208. &unknowns);
  1209. if (num_unknowns)
  1210. {
  1211. int i;
  1212. png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
  1213. num_unknowns);
  1214. /* Copy the locations from the read_info_ptr. The automatically
  1215. * generated locations in write_end_info_ptr are wrong because we
  1216. * haven't written the end_info yet.
  1217. */
  1218. for (i = 0; i < num_unknowns; i++)
  1219. png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
  1220. unknowns[i].location);
  1221. }
  1222. }
  1223. #endif
  1224. #ifdef PNG_WRITE_SUPPORTED
  1225. png_write_end(write_ptr, write_end_info_ptr);
  1226. #endif
  1227. #ifdef PNG_EASY_ACCESS_SUPPORTED
  1228. if (verbose)
  1229. {
  1230. png_uint_32 iwidth, iheight;
  1231. iwidth = png_get_image_width(write_ptr, write_info_ptr);
  1232. iheight = png_get_image_height(write_ptr, write_info_ptr);
  1233. fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
  1234. (unsigned long)iwidth, (unsigned long)iheight);
  1235. }
  1236. #endif
  1237. pngtest_debug("Destroying data structs");
  1238. #ifdef SINGLE_ROWBUF_ALLOC
  1239. pngtest_debug("destroying row_buf for read_ptr");
  1240. png_free(read_ptr, row_buf);
  1241. row_buf = NULL;
  1242. #endif /* SINGLE_ROWBUF_ALLOC */
  1243. pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr");
  1244. png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
  1245. #ifdef PNG_WRITE_SUPPORTED
  1246. pngtest_debug("destroying write_end_info_ptr");
  1247. png_destroy_info_struct(write_ptr, &write_end_info_ptr);
  1248. pngtest_debug("destroying write_ptr, write_info_ptr");
  1249. png_destroy_write_struct(&write_ptr, &write_info_ptr);
  1250. #endif
  1251. pngtest_debug("Destruction complete.");
  1252. FCLOSE(fpin);
  1253. FCLOSE(fpout);
  1254. pngtest_debug("Opening files for comparison");
  1255. if ((fpin = fopen(inname, "rb")) == NULL)
  1256. {
  1257. fprintf(STDERR, "Could not find file %s\n", inname);
  1258. return (1);
  1259. }
  1260. if ((fpout = fopen(outname, "rb")) == NULL)
  1261. {
  1262. fprintf(STDERR, "Could not find file %s\n", outname);
  1263. FCLOSE(fpin);
  1264. return (1);
  1265. }
  1266. for (;;)
  1267. {
  1268. png_size_t num_in, num_out;
  1269. num_in = fread(inbuf, 1, 1, fpin);
  1270. num_out = fread(outbuf, 1, 1, fpout);
  1271. if (num_in != num_out)
  1272. {
  1273. fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
  1274. inname, outname);
  1275. if (wrote_question == 0)
  1276. {
  1277. fprintf(STDERR,
  1278. " Was %s written with the same maximum IDAT chunk size (%d bytes),",
  1279. inname, PNG_ZBUF_SIZE);
  1280. fprintf(STDERR,
  1281. "\n filtering heuristic (libpng default), compression");
  1282. fprintf(STDERR,
  1283. " level (zlib default),\n and zlib version (%s)?\n\n",
  1284. ZLIB_VERSION);
  1285. wrote_question = 1;
  1286. }
  1287. FCLOSE(fpin);
  1288. FCLOSE(fpout);
  1289. if (strict != 0)
  1290. return (1);
  1291. else
  1292. return (0);
  1293. }
  1294. if (!num_in)
  1295. break;
  1296. if (png_memcmp(inbuf, outbuf, num_in))
  1297. {
  1298. fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
  1299. if (wrote_question == 0)
  1300. {
  1301. fprintf(STDERR,
  1302. " Was %s written with the same maximum IDAT chunk size (%d bytes),",
  1303. inname, PNG_ZBUF_SIZE);
  1304. fprintf(STDERR,
  1305. "\n filtering heuristic (libpng default), compression");
  1306. fprintf(STDERR,
  1307. " level (zlib default),\n and zlib version (%s)?\n\n",
  1308. ZLIB_VERSION);
  1309. wrote_question = 1;
  1310. }
  1311. FCLOSE(fpin);
  1312. FCLOSE(fpout);
  1313. if (strict != 0)
  1314. return (1);
  1315. else
  1316. return (0);
  1317. }
  1318. }
  1319. FCLOSE(fpin);
  1320. FCLOSE(fpout);
  1321. return (0);
  1322. }
  1323. /* Input and output filenames */
  1324. #ifdef RISCOS
  1325. static PNG_CONST char *inname = "pngtest/png";
  1326. static PNG_CONST char *outname = "pngout/png";
  1327. #else
  1328. static PNG_CONST char *inname = "pngtest.png";
  1329. static PNG_CONST char *outname = "pngout.png";
  1330. #endif
  1331. int
  1332. main(int argc, char *argv[])
  1333. {
  1334. int multiple = 0;
  1335. int ierror = 0;
  1336. fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
  1337. fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
  1338. fprintf(STDERR, "%s", png_get_copyright(NULL));
  1339. /* Show the version of libpng used in building the library */
  1340. fprintf(STDERR, " library (%lu):%s",
  1341. (unsigned long)png_access_version_number(),
  1342. png_get_header_version(NULL));
  1343. /* Show the version of libpng used in building the application */
  1344. fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
  1345. PNG_HEADER_VERSION_STRING);
  1346. /* Do some consistency checking on the memory allocation settings, I'm
  1347. * not sure this matters, but it is nice to know, the first of these
  1348. * tests should be impossible because of the way the macros are set
  1349. * in pngconf.h
  1350. */
  1351. #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
  1352. fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
  1353. #endif
  1354. /* I think the following can happen. */
  1355. #if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
  1356. fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
  1357. #endif
  1358. if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
  1359. {
  1360. fprintf(STDERR,
  1361. "Warning: versions are different between png.h and png.c\n");
  1362. fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
  1363. fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
  1364. ++ierror;
  1365. }
  1366. if (argc > 1)
  1367. {
  1368. if (strcmp(argv[1], "-m") == 0)
  1369. {
  1370. multiple = 1;
  1371. status_dots_requested = 0;
  1372. }
  1373. else if (strcmp(argv[1], "-mv") == 0 ||
  1374. strcmp(argv[1], "-vm") == 0 )
  1375. {
  1376. multiple = 1;
  1377. verbose = 1;
  1378. status_dots_requested = 1;
  1379. }
  1380. else if (strcmp(argv[1], "-v") == 0)
  1381. {
  1382. verbose = 1;
  1383. status_dots_requested = 1;
  1384. inname = argv[2];
  1385. }
  1386. else if (strcmp(argv[1], "--strict") == 0)
  1387. {
  1388. status_dots_requested = 0;
  1389. verbose = 1;
  1390. inname = argv[2];
  1391. strict++;
  1392. }
  1393. else
  1394. {
  1395. inname = argv[1];
  1396. status_dots_requested = 0;
  1397. }
  1398. }
  1399. if (!multiple && argc == 3 + verbose)
  1400. outname = argv[2 + verbose];
  1401. if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2))
  1402. {
  1403. fprintf(STDERR,
  1404. "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
  1405. argv[0], argv[0]);
  1406. fprintf(STDERR,
  1407. " reads/writes one PNG file (without -m) or multiple files (-m)\n");
  1408. fprintf(STDERR,
  1409. " with -m %s is used as a temporary file\n", outname);
  1410. exit(1);
  1411. }
  1412. if (multiple)
  1413. {
  1414. int i;
  1415. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  1416. int allocation_now = current_allocation;
  1417. #endif
  1418. for (i=2; i<argc; ++i)
  1419. {
  1420. int kerror;
  1421. fprintf(STDERR, "\n Testing %s:", argv[i]);
  1422. kerror = test_one_file(argv[i], outname);
  1423. if (kerror == 0)
  1424. {
  1425. #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
  1426. int k;
  1427. #endif
  1428. #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
  1429. fprintf(STDERR, "\n PASS (%lu zero samples)\n",
  1430. (unsigned long)zero_samples);
  1431. #else
  1432. fprintf(STDERR, " PASS\n");
  1433. #endif
  1434. #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
  1435. for (k = 0; k<256; k++)
  1436. if (filters_used[k])
  1437. fprintf(STDERR, " Filter %d was used %lu times\n",
  1438. k, (unsigned long)filters_used[k]);
  1439. #endif
  1440. #ifdef PNG_TIME_RFC1123_SUPPORTED
  1441. if (tIME_chunk_present != 0)
  1442. fprintf(STDERR, " tIME = %s\n", tIME_string);
  1443. tIME_chunk_present = 0;
  1444. #endif /* PNG_TIME_RFC1123_SUPPORTED */
  1445. }
  1446. else
  1447. {
  1448. fprintf(STDERR, " FAIL\n");
  1449. ierror += kerror;
  1450. }
  1451. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  1452. if (allocation_now != current_allocation)
  1453. fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
  1454. current_allocation - allocation_now);
  1455. if (current_allocation != 0)
  1456. {
  1457. memory_infop pinfo = pinformation;
  1458. fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
  1459. current_allocation);
  1460. while (pinfo != NULL)
  1461. {
  1462. fprintf(STDERR, " %lu bytes at %x\n",
  1463. (unsigned long)pinfo->size,
  1464. (unsigned int)pinfo->pointer);
  1465. pinfo = pinfo->next;
  1466. }
  1467. }
  1468. #endif
  1469. }
  1470. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  1471. fprintf(STDERR, " Current memory allocation: %10d bytes\n",
  1472. current_allocation);
  1473. fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
  1474. maximum_allocation);
  1475. fprintf(STDERR, " Total memory allocation: %10d bytes\n",
  1476. total_allocation);
  1477. fprintf(STDERR, " Number of allocations: %10d\n",
  1478. num_allocations);
  1479. #endif
  1480. }
  1481. else
  1482. {
  1483. int i;
  1484. for (i = 0; i<3; ++i)
  1485. {
  1486. int kerror;
  1487. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  1488. int allocation_now = current_allocation;
  1489. #endif
  1490. if (i == 1)
  1491. status_dots_requested = 1;
  1492. else if (verbose == 0)
  1493. status_dots_requested = 0;
  1494. if (i == 0 || verbose == 1 || ierror != 0)
  1495. fprintf(STDERR, "\n Testing %s:", inname);
  1496. kerror = test_one_file(inname, outname);
  1497. if (kerror == 0)
  1498. {
  1499. if (verbose == 1 || i == 2)
  1500. {
  1501. #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
  1502. int k;
  1503. #endif
  1504. #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
  1505. fprintf(STDERR, "\n PASS (%lu zero samples)\n",
  1506. (unsigned long)zero_samples);
  1507. #else
  1508. fprintf(STDERR, " PASS\n");
  1509. #endif
  1510. #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
  1511. for (k = 0; k<256; k++)
  1512. if (filters_used[k])
  1513. fprintf(STDERR, " Filter %d was used %lu times\n",
  1514. k, (unsigned long)filters_used[k]);
  1515. #endif
  1516. #ifdef PNG_TIME_RFC1123_SUPPORTED
  1517. if (tIME_chunk_present != 0)
  1518. fprintf(STDERR, " tIME = %s\n", tIME_string);
  1519. #endif /* PNG_TIME_RFC1123_SUPPORTED */
  1520. }
  1521. }
  1522. else
  1523. {
  1524. if (verbose == 0 && i != 2)
  1525. fprintf(STDERR, "\n Testing %s:", inname);
  1526. fprintf(STDERR, " FAIL\n");
  1527. ierror += kerror;
  1528. }
  1529. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  1530. if (allocation_now != current_allocation)
  1531. fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
  1532. current_allocation - allocation_now);
  1533. if (current_allocation != 0)
  1534. {
  1535. memory_infop pinfo = pinformation;
  1536. fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
  1537. current_allocation);
  1538. while (pinfo != NULL)
  1539. {
  1540. fprintf(STDERR, " %lu bytes at %x\n",
  1541. (unsigned long)pinfo->size, (unsigned int)pinfo->pointer);
  1542. pinfo = pinfo->next;
  1543. }
  1544. }
  1545. #endif
  1546. }
  1547. #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
  1548. fprintf(STDERR, " Current memory allocation: %10d bytes\n",
  1549. current_allocation);
  1550. fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
  1551. maximum_allocation);
  1552. fprintf(STDERR, " Total memory allocation: %10d bytes\n",
  1553. total_allocation);
  1554. fprintf(STDERR, " Number of allocations: %10d\n",
  1555. num_allocations);
  1556. #endif
  1557. }
  1558. #ifdef PNGTEST_TIMING
  1559. t_stop = (float)clock();
  1560. t_misc += (t_stop - t_start);
  1561. t_start = t_stop;
  1562. fprintf(STDERR, " CPU time used = %.3f seconds",
  1563. (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
  1564. fprintf(STDERR, " (decoding %.3f,\n",
  1565. t_decode/(float)CLOCKS_PER_SEC);
  1566. fprintf(STDERR, " encoding %.3f ,",
  1567. t_encode/(float)CLOCKS_PER_SEC);
  1568. fprintf(STDERR, " other %.3f seconds)\n\n",
  1569. t_misc/(float)CLOCKS_PER_SEC);
  1570. #endif
  1571. if (ierror == 0)
  1572. fprintf(STDERR, " libpng passes test\n");
  1573. else
  1574. fprintf(STDERR, " libpng FAILS test\n");
  1575. return (int)(ierror != 0);
  1576. }
  1577. /* Generate a compiler error if there is an old png.h in the search path. */
  1578. typedef png_libpng_version_1_5_9 Your_png_h_is_not_version_1_5_9;