PageRenderTime 58ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/cximage-6.0/png/pngrtran.c

http://github.com/xbmc/xbmc
C | 4284 lines | 3680 code | 294 blank | 310 comment | 839 complexity | 53def9d74eafa141648c263f8de329f5 MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-3.0, LGPL-2.0, 0BSD, Unlicense, GPL-2.0, AGPL-1.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* pngrtran.c - transforms the data in a row for PNG readers
  2. *
  3. * Last changed in libpng 1.2.22 [October 13, 2007]
  4. * For conditions of distribution and use, see copyright notice in png.h
  5. * Copyright (c) 1998-2007 Glenn Randers-Pehrson
  6. * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  7. * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  8. *
  9. * This file contains functions optionally called by an application
  10. * in order to tell libpng how to handle data when reading a PNG.
  11. * Transformations that are used in both reading and writing are
  12. * in pngtrans.c.
  13. */
  14. #define PNG_INTERNAL
  15. #include "png.h"
  16. #if defined(PNG_READ_SUPPORTED)
  17. /* Set the action on getting a CRC error for an ancillary or critical chunk. */
  18. void PNGAPI
  19. png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
  20. {
  21. png_debug(1, "in png_set_crc_action\n");
  22. /* Tell libpng how we react to CRC errors in critical chunks */
  23. if(png_ptr == NULL) return;
  24. switch (crit_action)
  25. {
  26. case PNG_CRC_NO_CHANGE: /* leave setting as is */
  27. break;
  28. case PNG_CRC_WARN_USE: /* warn/use data */
  29. png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  30. png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
  31. break;
  32. case PNG_CRC_QUIET_USE: /* quiet/use data */
  33. png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  34. png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
  35. PNG_FLAG_CRC_CRITICAL_IGNORE;
  36. break;
  37. case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
  38. png_warning(png_ptr, "Can't discard critical data on CRC error.");
  39. case PNG_CRC_ERROR_QUIT: /* error/quit */
  40. case PNG_CRC_DEFAULT:
  41. default:
  42. png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  43. break;
  44. }
  45. switch (ancil_action)
  46. {
  47. case PNG_CRC_NO_CHANGE: /* leave setting as is */
  48. break;
  49. case PNG_CRC_WARN_USE: /* warn/use data */
  50. png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  51. png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
  52. break;
  53. case PNG_CRC_QUIET_USE: /* quiet/use data */
  54. png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  55. png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
  56. PNG_FLAG_CRC_ANCILLARY_NOWARN;
  57. break;
  58. case PNG_CRC_ERROR_QUIT: /* error/quit */
  59. png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  60. png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
  61. break;
  62. case PNG_CRC_WARN_DISCARD: /* warn/discard data */
  63. case PNG_CRC_DEFAULT:
  64. default:
  65. png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  66. break;
  67. }
  68. }
  69. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
  70. defined(PNG_FLOATING_POINT_SUPPORTED)
  71. /* handle alpha and tRNS via a background color */
  72. void PNGAPI
  73. png_set_background(png_structp png_ptr,
  74. png_color_16p background_color, int background_gamma_code,
  75. int need_expand, double background_gamma)
  76. {
  77. png_debug(1, "in png_set_background\n");
  78. if(png_ptr == NULL) return;
  79. if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
  80. {
  81. png_warning(png_ptr, "Application must supply a known background gamma");
  82. return;
  83. }
  84. png_ptr->transformations |= PNG_BACKGROUND;
  85. png_memcpy(&(png_ptr->background), background_color,
  86. png_sizeof(png_color_16));
  87. png_ptr->background_gamma = (float)background_gamma;
  88. png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
  89. png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
  90. }
  91. #endif
  92. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  93. /* strip 16 bit depth files to 8 bit depth */
  94. void PNGAPI
  95. png_set_strip_16(png_structp png_ptr)
  96. {
  97. png_debug(1, "in png_set_strip_16\n");
  98. if(png_ptr == NULL) return;
  99. png_ptr->transformations |= PNG_16_TO_8;
  100. }
  101. #endif
  102. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  103. void PNGAPI
  104. png_set_strip_alpha(png_structp png_ptr)
  105. {
  106. png_debug(1, "in png_set_strip_alpha\n");
  107. if(png_ptr == NULL) return;
  108. png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
  109. }
  110. #endif
  111. #if defined(PNG_READ_DITHER_SUPPORTED)
  112. /* Dither file to 8 bit. Supply a palette, the current number
  113. * of elements in the palette, the maximum number of elements
  114. * allowed, and a histogram if possible. If the current number
  115. * of colors is greater then the maximum number, the palette will be
  116. * modified to fit in the maximum number. "full_dither" indicates
  117. * whether we need a dithering cube set up for RGB images, or if we
  118. * simply are reducing the number of colors in a paletted image.
  119. */
  120. typedef struct png_dsort_struct
  121. {
  122. struct png_dsort_struct FAR * next;
  123. png_byte left;
  124. png_byte right;
  125. } png_dsort;
  126. typedef png_dsort FAR * png_dsortp;
  127. typedef png_dsort FAR * FAR * png_dsortpp;
  128. void PNGAPI
  129. png_set_dither(png_structp png_ptr, png_colorp palette,
  130. int num_palette, int maximum_colors, png_uint_16p histogram,
  131. int full_dither)
  132. {
  133. png_debug(1, "in png_set_dither\n");
  134. if(png_ptr == NULL) return;
  135. png_ptr->transformations |= PNG_DITHER;
  136. if (!full_dither)
  137. {
  138. int i;
  139. png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
  140. (png_uint_32)(num_palette * png_sizeof (png_byte)));
  141. for (i = 0; i < num_palette; i++)
  142. png_ptr->dither_index[i] = (png_byte)i;
  143. }
  144. if (num_palette > maximum_colors)
  145. {
  146. if (histogram != NULL)
  147. {
  148. /* This is easy enough, just throw out the least used colors.
  149. Perhaps not the best solution, but good enough. */
  150. int i;
  151. /* initialize an array to sort colors */
  152. png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
  153. (png_uint_32)(num_palette * png_sizeof (png_byte)));
  154. /* initialize the dither_sort array */
  155. for (i = 0; i < num_palette; i++)
  156. png_ptr->dither_sort[i] = (png_byte)i;
  157. /* Find the least used palette entries by starting a
  158. bubble sort, and running it until we have sorted
  159. out enough colors. Note that we don't care about
  160. sorting all the colors, just finding which are
  161. least used. */
  162. for (i = num_palette - 1; i >= maximum_colors; i--)
  163. {
  164. int done; /* to stop early if the list is pre-sorted */
  165. int j;
  166. done = 1;
  167. for (j = 0; j < i; j++)
  168. {
  169. if (histogram[png_ptr->dither_sort[j]]
  170. < histogram[png_ptr->dither_sort[j + 1]])
  171. {
  172. png_byte t;
  173. t = png_ptr->dither_sort[j];
  174. png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
  175. png_ptr->dither_sort[j + 1] = t;
  176. done = 0;
  177. }
  178. }
  179. if (done)
  180. break;
  181. }
  182. /* swap the palette around, and set up a table, if necessary */
  183. if (full_dither)
  184. {
  185. int j = num_palette;
  186. /* put all the useful colors within the max, but don't
  187. move the others */
  188. for (i = 0; i < maximum_colors; i++)
  189. {
  190. if ((int)png_ptr->dither_sort[i] >= maximum_colors)
  191. {
  192. do
  193. j--;
  194. while ((int)png_ptr->dither_sort[j] >= maximum_colors);
  195. palette[i] = palette[j];
  196. }
  197. }
  198. }
  199. else
  200. {
  201. int j = num_palette;
  202. /* move all the used colors inside the max limit, and
  203. develop a translation table */
  204. for (i = 0; i < maximum_colors; i++)
  205. {
  206. /* only move the colors we need to */
  207. if ((int)png_ptr->dither_sort[i] >= maximum_colors)
  208. {
  209. png_color tmp_color;
  210. do
  211. j--;
  212. while ((int)png_ptr->dither_sort[j] >= maximum_colors);
  213. tmp_color = palette[j];
  214. palette[j] = palette[i];
  215. palette[i] = tmp_color;
  216. /* indicate where the color went */
  217. png_ptr->dither_index[j] = (png_byte)i;
  218. png_ptr->dither_index[i] = (png_byte)j;
  219. }
  220. }
  221. /* find closest color for those colors we are not using */
  222. for (i = 0; i < num_palette; i++)
  223. {
  224. if ((int)png_ptr->dither_index[i] >= maximum_colors)
  225. {
  226. int min_d, k, min_k, d_index;
  227. /* find the closest color to one we threw out */
  228. d_index = png_ptr->dither_index[i];
  229. min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
  230. for (k = 1, min_k = 0; k < maximum_colors; k++)
  231. {
  232. int d;
  233. d = PNG_COLOR_DIST(palette[d_index], palette[k]);
  234. if (d < min_d)
  235. {
  236. min_d = d;
  237. min_k = k;
  238. }
  239. }
  240. /* point to closest color */
  241. png_ptr->dither_index[i] = (png_byte)min_k;
  242. }
  243. }
  244. }
  245. png_free(png_ptr, png_ptr->dither_sort);
  246. png_ptr->dither_sort=NULL;
  247. }
  248. else
  249. {
  250. /* This is much harder to do simply (and quickly). Perhaps
  251. we need to go through a median cut routine, but those
  252. don't always behave themselves with only a few colors
  253. as input. So we will just find the closest two colors,
  254. and throw out one of them (chosen somewhat randomly).
  255. [We don't understand this at all, so if someone wants to
  256. work on improving it, be our guest - AED, GRP]
  257. */
  258. int i;
  259. int max_d;
  260. int num_new_palette;
  261. png_dsortp t;
  262. png_dsortpp hash;
  263. t=NULL;
  264. /* initialize palette index arrays */
  265. png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
  266. (png_uint_32)(num_palette * png_sizeof (png_byte)));
  267. png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
  268. (png_uint_32)(num_palette * png_sizeof (png_byte)));
  269. /* initialize the sort array */
  270. for (i = 0; i < num_palette; i++)
  271. {
  272. png_ptr->index_to_palette[i] = (png_byte)i;
  273. png_ptr->palette_to_index[i] = (png_byte)i;
  274. }
  275. hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
  276. png_sizeof (png_dsortp)));
  277. for (i = 0; i < 769; i++)
  278. hash[i] = NULL;
  279. /* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */
  280. num_new_palette = num_palette;
  281. /* initial wild guess at how far apart the farthest pixel
  282. pair we will be eliminating will be. Larger
  283. numbers mean more areas will be allocated, Smaller
  284. numbers run the risk of not saving enough data, and
  285. having to do this all over again.
  286. I have not done extensive checking on this number.
  287. */
  288. max_d = 96;
  289. while (num_new_palette > maximum_colors)
  290. {
  291. for (i = 0; i < num_new_palette - 1; i++)
  292. {
  293. int j;
  294. for (j = i + 1; j < num_new_palette; j++)
  295. {
  296. int d;
  297. d = PNG_COLOR_DIST(palette[i], palette[j]);
  298. if (d <= max_d)
  299. {
  300. t = (png_dsortp)png_malloc_warn(png_ptr,
  301. (png_uint_32)(png_sizeof(png_dsort)));
  302. if (t == NULL)
  303. break;
  304. t->next = hash[d];
  305. t->left = (png_byte)i;
  306. t->right = (png_byte)j;
  307. hash[d] = t;
  308. }
  309. }
  310. if (t == NULL)
  311. break;
  312. }
  313. if (t != NULL)
  314. for (i = 0; i <= max_d; i++)
  315. {
  316. if (hash[i] != NULL)
  317. {
  318. png_dsortp p;
  319. for (p = hash[i]; p; p = p->next)
  320. {
  321. if ((int)png_ptr->index_to_palette[p->left]
  322. < num_new_palette &&
  323. (int)png_ptr->index_to_palette[p->right]
  324. < num_new_palette)
  325. {
  326. int j, next_j;
  327. if (num_new_palette & 0x01)
  328. {
  329. j = p->left;
  330. next_j = p->right;
  331. }
  332. else
  333. {
  334. j = p->right;
  335. next_j = p->left;
  336. }
  337. num_new_palette--;
  338. palette[png_ptr->index_to_palette[j]]
  339. = palette[num_new_palette];
  340. if (!full_dither)
  341. {
  342. int k;
  343. for (k = 0; k < num_palette; k++)
  344. {
  345. if (png_ptr->dither_index[k] ==
  346. png_ptr->index_to_palette[j])
  347. png_ptr->dither_index[k] =
  348. png_ptr->index_to_palette[next_j];
  349. if ((int)png_ptr->dither_index[k] ==
  350. num_new_palette)
  351. png_ptr->dither_index[k] =
  352. png_ptr->index_to_palette[j];
  353. }
  354. }
  355. png_ptr->index_to_palette[png_ptr->palette_to_index
  356. [num_new_palette]] = png_ptr->index_to_palette[j];
  357. png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
  358. = png_ptr->palette_to_index[num_new_palette];
  359. png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
  360. png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
  361. }
  362. if (num_new_palette <= maximum_colors)
  363. break;
  364. }
  365. if (num_new_palette <= maximum_colors)
  366. break;
  367. }
  368. }
  369. for (i = 0; i < 769; i++)
  370. {
  371. if (hash[i] != NULL)
  372. {
  373. png_dsortp p = hash[i];
  374. while (p)
  375. {
  376. t = p->next;
  377. png_free(png_ptr, p);
  378. p = t;
  379. }
  380. }
  381. hash[i] = 0;
  382. }
  383. max_d += 96;
  384. }
  385. png_free(png_ptr, hash);
  386. png_free(png_ptr, png_ptr->palette_to_index);
  387. png_free(png_ptr, png_ptr->index_to_palette);
  388. png_ptr->palette_to_index=NULL;
  389. png_ptr->index_to_palette=NULL;
  390. }
  391. num_palette = maximum_colors;
  392. }
  393. if (png_ptr->palette == NULL)
  394. {
  395. png_ptr->palette = palette;
  396. }
  397. png_ptr->num_palette = (png_uint_16)num_palette;
  398. if (full_dither)
  399. {
  400. int i;
  401. png_bytep distance;
  402. int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
  403. PNG_DITHER_BLUE_BITS;
  404. int num_red = (1 << PNG_DITHER_RED_BITS);
  405. int num_green = (1 << PNG_DITHER_GREEN_BITS);
  406. int num_blue = (1 << PNG_DITHER_BLUE_BITS);
  407. png_size_t num_entries = ((png_size_t)1 << total_bits);
  408. png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
  409. (png_uint_32)(num_entries * png_sizeof (png_byte)));
  410. png_memset(png_ptr->palette_lookup, 0, num_entries *
  411. png_sizeof (png_byte));
  412. distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
  413. png_sizeof(png_byte)));
  414. png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
  415. for (i = 0; i < num_palette; i++)
  416. {
  417. int ir, ig, ib;
  418. int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
  419. int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
  420. int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
  421. for (ir = 0; ir < num_red; ir++)
  422. {
  423. /* int dr = abs(ir - r); */
  424. int dr = ((ir > r) ? ir - r : r - ir);
  425. int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
  426. for (ig = 0; ig < num_green; ig++)
  427. {
  428. /* int dg = abs(ig - g); */
  429. int dg = ((ig > g) ? ig - g : g - ig);
  430. int dt = dr + dg;
  431. int dm = ((dr > dg) ? dr : dg);
  432. int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
  433. for (ib = 0; ib < num_blue; ib++)
  434. {
  435. int d_index = index_g | ib;
  436. /* int db = abs(ib - b); */
  437. int db = ((ib > b) ? ib - b : b - ib);
  438. int dmax = ((dm > db) ? dm : db);
  439. int d = dmax + dt + db;
  440. if (d < (int)distance[d_index])
  441. {
  442. distance[d_index] = (png_byte)d;
  443. png_ptr->palette_lookup[d_index] = (png_byte)i;
  444. }
  445. }
  446. }
  447. }
  448. }
  449. png_free(png_ptr, distance);
  450. }
  451. }
  452. #endif
  453. #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
  454. /* Transform the image from the file_gamma to the screen_gamma. We
  455. * only do transformations on images where the file_gamma and screen_gamma
  456. * are not close reciprocals, otherwise it slows things down slightly, and
  457. * also needlessly introduces small errors.
  458. *
  459. * We will turn off gamma transformation later if no semitransparent entries
  460. * are present in the tRNS array for palette images. We can't do it here
  461. * because we don't necessarily have the tRNS chunk yet.
  462. */
  463. void PNGAPI
  464. png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
  465. {
  466. png_debug(1, "in png_set_gamma\n");
  467. if(png_ptr == NULL) return;
  468. if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
  469. (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
  470. (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
  471. png_ptr->transformations |= PNG_GAMMA;
  472. png_ptr->gamma = (float)file_gamma;
  473. png_ptr->screen_gamma = (float)scrn_gamma;
  474. }
  475. #endif
  476. #if defined(PNG_READ_EXPAND_SUPPORTED)
  477. /* Expand paletted images to RGB, expand grayscale images of
  478. * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
  479. * to alpha channels.
  480. */
  481. void PNGAPI
  482. png_set_expand(png_structp png_ptr)
  483. {
  484. png_debug(1, "in png_set_expand\n");
  485. if(png_ptr == NULL) return;
  486. png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  487. #ifdef PNG_WARN_UNINITIALIZED_ROW
  488. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  489. #endif
  490. }
  491. /* GRR 19990627: the following three functions currently are identical
  492. * to png_set_expand(). However, it is entirely reasonable that someone
  493. * might wish to expand an indexed image to RGB but *not* expand a single,
  494. * fully transparent palette entry to a full alpha channel--perhaps instead
  495. * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
  496. * the transparent color with a particular RGB value, or drop tRNS entirely.
  497. * IOW, a future version of the library may make the transformations flag
  498. * a bit more fine-grained, with separate bits for each of these three
  499. * functions.
  500. *
  501. * More to the point, these functions make it obvious what libpng will be
  502. * doing, whereas "expand" can (and does) mean any number of things.
  503. *
  504. * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
  505. * to expand only the sample depth but not to expand the tRNS to alpha.
  506. */
  507. /* Expand paletted images to RGB. */
  508. void PNGAPI
  509. png_set_palette_to_rgb(png_structp png_ptr)
  510. {
  511. png_debug(1, "in png_set_palette_to_rgb\n");
  512. if(png_ptr == NULL) return;
  513. png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  514. #ifdef PNG_WARN_UNINITIALIZED_ROW
  515. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  516. #endif
  517. }
  518. #if !defined(PNG_1_0_X)
  519. /* Expand grayscale images of less than 8-bit depth to 8 bits. */
  520. void PNGAPI
  521. png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
  522. {
  523. png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
  524. if(png_ptr == NULL) return;
  525. png_ptr->transformations |= PNG_EXPAND;
  526. #ifdef PNG_WARN_UNINITIALIZED_ROW
  527. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  528. #endif
  529. }
  530. #endif
  531. #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
  532. /* Expand grayscale images of less than 8-bit depth to 8 bits. */
  533. /* Deprecated as of libpng-1.2.9 */
  534. void PNGAPI
  535. png_set_gray_1_2_4_to_8(png_structp png_ptr)
  536. {
  537. png_debug(1, "in png_set_gray_1_2_4_to_8\n");
  538. if(png_ptr == NULL) return;
  539. png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  540. }
  541. #endif
  542. /* Expand tRNS chunks to alpha channels. */
  543. void PNGAPI
  544. png_set_tRNS_to_alpha(png_structp png_ptr)
  545. {
  546. png_debug(1, "in png_set_tRNS_to_alpha\n");
  547. png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  548. #ifdef PNG_WARN_UNINITIALIZED_ROW
  549. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  550. #endif
  551. }
  552. #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
  553. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  554. void PNGAPI
  555. png_set_gray_to_rgb(png_structp png_ptr)
  556. {
  557. png_debug(1, "in png_set_gray_to_rgb\n");
  558. png_ptr->transformations |= PNG_GRAY_TO_RGB;
  559. #ifdef PNG_WARN_UNINITIALIZED_ROW
  560. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  561. #endif
  562. }
  563. #endif
  564. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  565. #if defined(PNG_FLOATING_POINT_SUPPORTED)
  566. /* Convert a RGB image to a grayscale of the same width. This allows us,
  567. * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
  568. */
  569. void PNGAPI
  570. png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
  571. double green)
  572. {
  573. int red_fixed = (int)((float)red*100000.0 + 0.5);
  574. int green_fixed = (int)((float)green*100000.0 + 0.5);
  575. if(png_ptr == NULL) return;
  576. png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
  577. }
  578. #endif
  579. void PNGAPI
  580. png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
  581. png_fixed_point red, png_fixed_point green)
  582. {
  583. png_debug(1, "in png_set_rgb_to_gray\n");
  584. if(png_ptr == NULL) return;
  585. switch(error_action)
  586. {
  587. case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
  588. break;
  589. case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
  590. break;
  591. case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
  592. }
  593. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  594. #if defined(PNG_READ_EXPAND_SUPPORTED)
  595. png_ptr->transformations |= PNG_EXPAND;
  596. #else
  597. {
  598. png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
  599. png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
  600. }
  601. #endif
  602. {
  603. png_uint_16 red_int, green_int;
  604. if(red < 0 || green < 0)
  605. {
  606. red_int = 6968; /* .212671 * 32768 + .5 */
  607. green_int = 23434; /* .715160 * 32768 + .5 */
  608. }
  609. else if(red + green < 100000L)
  610. {
  611. red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
  612. green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
  613. }
  614. else
  615. {
  616. png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
  617. red_int = 6968;
  618. green_int = 23434;
  619. }
  620. png_ptr->rgb_to_gray_red_coeff = red_int;
  621. png_ptr->rgb_to_gray_green_coeff = green_int;
  622. png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int);
  623. }
  624. }
  625. #endif
  626. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
  627. defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
  628. defined(PNG_LEGACY_SUPPORTED)
  629. void PNGAPI
  630. png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
  631. read_user_transform_fn)
  632. {
  633. png_debug(1, "in png_set_read_user_transform_fn\n");
  634. if(png_ptr == NULL) return;
  635. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
  636. png_ptr->transformations |= PNG_USER_TRANSFORM;
  637. png_ptr->read_user_transform_fn = read_user_transform_fn;
  638. #endif
  639. #ifdef PNG_LEGACY_SUPPORTED
  640. if(read_user_transform_fn)
  641. png_warning(png_ptr,
  642. "This version of libpng does not support user transforms");
  643. #endif
  644. }
  645. #endif
  646. /* Initialize everything needed for the read. This includes modifying
  647. * the palette.
  648. */
  649. void /* PRIVATE */
  650. png_init_read_transformations(png_structp png_ptr)
  651. {
  652. png_debug(1, "in png_init_read_transformations\n");
  653. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  654. if(png_ptr != NULL)
  655. #endif
  656. {
  657. #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
  658. || defined(PNG_READ_GAMMA_SUPPORTED)
  659. int color_type = png_ptr->color_type;
  660. #endif
  661. #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
  662. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  663. /* Detect gray background and attempt to enable optimization
  664. * for gray --> RGB case */
  665. /* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
  666. * RGB_ALPHA (in which case need_expand is superfluous anyway), the
  667. * background color might actually be gray yet not be flagged as such.
  668. * This is not a problem for the current code, which uses
  669. * PNG_BACKGROUND_IS_GRAY only to decide when to do the
  670. * png_do_gray_to_rgb() transformation.
  671. */
  672. if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  673. !(color_type & PNG_COLOR_MASK_COLOR))
  674. {
  675. png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
  676. } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
  677. !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  678. (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  679. png_ptr->background.red == png_ptr->background.green &&
  680. png_ptr->background.red == png_ptr->background.blue)
  681. {
  682. png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
  683. png_ptr->background.gray = png_ptr->background.red;
  684. }
  685. #endif
  686. if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  687. (png_ptr->transformations & PNG_EXPAND))
  688. {
  689. if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
  690. {
  691. /* expand background and tRNS chunks */
  692. switch (png_ptr->bit_depth)
  693. {
  694. case 1:
  695. png_ptr->background.gray *= (png_uint_16)0xff;
  696. png_ptr->background.red = png_ptr->background.green
  697. = png_ptr->background.blue = png_ptr->background.gray;
  698. if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  699. {
  700. png_ptr->trans_values.gray *= (png_uint_16)0xff;
  701. png_ptr->trans_values.red = png_ptr->trans_values.green
  702. = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  703. }
  704. break;
  705. case 2:
  706. png_ptr->background.gray *= (png_uint_16)0x55;
  707. png_ptr->background.red = png_ptr->background.green
  708. = png_ptr->background.blue = png_ptr->background.gray;
  709. if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  710. {
  711. png_ptr->trans_values.gray *= (png_uint_16)0x55;
  712. png_ptr->trans_values.red = png_ptr->trans_values.green
  713. = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  714. }
  715. break;
  716. case 4:
  717. png_ptr->background.gray *= (png_uint_16)0x11;
  718. png_ptr->background.red = png_ptr->background.green
  719. = png_ptr->background.blue = png_ptr->background.gray;
  720. if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  721. {
  722. png_ptr->trans_values.gray *= (png_uint_16)0x11;
  723. png_ptr->trans_values.red = png_ptr->trans_values.green
  724. = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  725. }
  726. break;
  727. case 8:
  728. case 16:
  729. png_ptr->background.red = png_ptr->background.green
  730. = png_ptr->background.blue = png_ptr->background.gray;
  731. break;
  732. }
  733. }
  734. else if (color_type == PNG_COLOR_TYPE_PALETTE)
  735. {
  736. png_ptr->background.red =
  737. png_ptr->palette[png_ptr->background.index].red;
  738. png_ptr->background.green =
  739. png_ptr->palette[png_ptr->background.index].green;
  740. png_ptr->background.blue =
  741. png_ptr->palette[png_ptr->background.index].blue;
  742. #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
  743. if (png_ptr->transformations & PNG_INVERT_ALPHA)
  744. {
  745. #if defined(PNG_READ_EXPAND_SUPPORTED)
  746. if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  747. #endif
  748. {
  749. /* invert the alpha channel (in tRNS) unless the pixels are
  750. going to be expanded, in which case leave it for later */
  751. int i,istop;
  752. istop=(int)png_ptr->num_trans;
  753. for (i=0; i<istop; i++)
  754. png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
  755. }
  756. }
  757. #endif
  758. }
  759. }
  760. #endif
  761. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  762. png_ptr->background_1 = png_ptr->background;
  763. #endif
  764. #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
  765. if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
  766. && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
  767. < PNG_GAMMA_THRESHOLD))
  768. {
  769. int i,k;
  770. k=0;
  771. for (i=0; i<png_ptr->num_trans; i++)
  772. {
  773. if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
  774. k=1; /* partial transparency is present */
  775. }
  776. if (k == 0)
  777. png_ptr->transformations &= ~PNG_GAMMA;
  778. }
  779. if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
  780. png_ptr->gamma != 0.0)
  781. {
  782. png_build_gamma_table(png_ptr);
  783. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  784. if (png_ptr->transformations & PNG_BACKGROUND)
  785. {
  786. if (color_type == PNG_COLOR_TYPE_PALETTE)
  787. {
  788. /* could skip if no transparency and
  789. */
  790. png_color back, back_1;
  791. png_colorp palette = png_ptr->palette;
  792. int num_palette = png_ptr->num_palette;
  793. int i;
  794. if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
  795. {
  796. back.red = png_ptr->gamma_table[png_ptr->background.red];
  797. back.green = png_ptr->gamma_table[png_ptr->background.green];
  798. back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  799. back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  800. back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  801. back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  802. }
  803. else
  804. {
  805. double g, gs;
  806. switch (png_ptr->background_gamma_type)
  807. {
  808. case PNG_BACKGROUND_GAMMA_SCREEN:
  809. g = (png_ptr->screen_gamma);
  810. gs = 1.0;
  811. break;
  812. case PNG_BACKGROUND_GAMMA_FILE:
  813. g = 1.0 / (png_ptr->gamma);
  814. gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  815. break;
  816. case PNG_BACKGROUND_GAMMA_UNIQUE:
  817. g = 1.0 / (png_ptr->background_gamma);
  818. gs = 1.0 / (png_ptr->background_gamma *
  819. png_ptr->screen_gamma);
  820. break;
  821. default:
  822. g = 1.0; /* back_1 */
  823. gs = 1.0; /* back */
  824. }
  825. if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
  826. {
  827. back.red = (png_byte)png_ptr->background.red;
  828. back.green = (png_byte)png_ptr->background.green;
  829. back.blue = (png_byte)png_ptr->background.blue;
  830. }
  831. else
  832. {
  833. back.red = (png_byte)(pow(
  834. (double)png_ptr->background.red/255, gs) * 255.0 + .5);
  835. back.green = (png_byte)(pow(
  836. (double)png_ptr->background.green/255, gs) * 255.0 + .5);
  837. back.blue = (png_byte)(pow(
  838. (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
  839. }
  840. back_1.red = (png_byte)(pow(
  841. (double)png_ptr->background.red/255, g) * 255.0 + .5);
  842. back_1.green = (png_byte)(pow(
  843. (double)png_ptr->background.green/255, g) * 255.0 + .5);
  844. back_1.blue = (png_byte)(pow(
  845. (double)png_ptr->background.blue/255, g) * 255.0 + .5);
  846. }
  847. for (i = 0; i < num_palette; i++)
  848. {
  849. if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
  850. {
  851. if (png_ptr->trans[i] == 0)
  852. {
  853. palette[i] = back;
  854. }
  855. else /* if (png_ptr->trans[i] != 0xff) */
  856. {
  857. png_byte v, w;
  858. v = png_ptr->gamma_to_1[palette[i].red];
  859. png_composite(w, v, png_ptr->trans[i], back_1.red);
  860. palette[i].red = png_ptr->gamma_from_1[w];
  861. v = png_ptr->gamma_to_1[palette[i].green];
  862. png_composite(w, v, png_ptr->trans[i], back_1.green);
  863. palette[i].green = png_ptr->gamma_from_1[w];
  864. v = png_ptr->gamma_to_1[palette[i].blue];
  865. png_composite(w, v, png_ptr->trans[i], back_1.blue);
  866. palette[i].blue = png_ptr->gamma_from_1[w];
  867. }
  868. }
  869. else
  870. {
  871. palette[i].red = png_ptr->gamma_table[palette[i].red];
  872. palette[i].green = png_ptr->gamma_table[palette[i].green];
  873. palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  874. }
  875. }
  876. }
  877. /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
  878. else
  879. /* color_type != PNG_COLOR_TYPE_PALETTE */
  880. {
  881. double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
  882. double g = 1.0;
  883. double gs = 1.0;
  884. switch (png_ptr->background_gamma_type)
  885. {
  886. case PNG_BACKGROUND_GAMMA_SCREEN:
  887. g = (png_ptr->screen_gamma);
  888. gs = 1.0;
  889. break;
  890. case PNG_BACKGROUND_GAMMA_FILE:
  891. g = 1.0 / (png_ptr->gamma);
  892. gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  893. break;
  894. case PNG_BACKGROUND_GAMMA_UNIQUE:
  895. g = 1.0 / (png_ptr->background_gamma);
  896. gs = 1.0 / (png_ptr->background_gamma *
  897. png_ptr->screen_gamma);
  898. break;
  899. }
  900. png_ptr->background_1.gray = (png_uint_16)(pow(
  901. (double)png_ptr->background.gray / m, g) * m + .5);
  902. png_ptr->background.gray = (png_uint_16)(pow(
  903. (double)png_ptr->background.gray / m, gs) * m + .5);
  904. if ((png_ptr->background.red != png_ptr->background.green) ||
  905. (png_ptr->background.red != png_ptr->background.blue) ||
  906. (png_ptr->background.red != png_ptr->background.gray))
  907. {
  908. /* RGB or RGBA with color background */
  909. png_ptr->background_1.red = (png_uint_16)(pow(
  910. (double)png_ptr->background.red / m, g) * m + .5);
  911. png_ptr->background_1.green = (png_uint_16)(pow(
  912. (double)png_ptr->background.green / m, g) * m + .5);
  913. png_ptr->background_1.blue = (png_uint_16)(pow(
  914. (double)png_ptr->background.blue / m, g) * m + .5);
  915. png_ptr->background.red = (png_uint_16)(pow(
  916. (double)png_ptr->background.red / m, gs) * m + .5);
  917. png_ptr->background.green = (png_uint_16)(pow(
  918. (double)png_ptr->background.green / m, gs) * m + .5);
  919. png_ptr->background.blue = (png_uint_16)(pow(
  920. (double)png_ptr->background.blue / m, gs) * m + .5);
  921. }
  922. else
  923. {
  924. /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
  925. png_ptr->background_1.red = png_ptr->background_1.green
  926. = png_ptr->background_1.blue = png_ptr->background_1.gray;
  927. png_ptr->background.red = png_ptr->background.green
  928. = png_ptr->background.blue = png_ptr->background.gray;
  929. }
  930. }
  931. }
  932. else
  933. /* transformation does not include PNG_BACKGROUND */
  934. #endif /* PNG_READ_BACKGROUND_SUPPORTED */
  935. if (color_type == PNG_COLOR_TYPE_PALETTE)
  936. {
  937. png_colorp palette = png_ptr->palette;
  938. int num_palette = png_ptr->num_palette;
  939. int i;
  940. for (i = 0; i < num_palette; i++)
  941. {
  942. palette[i].red = png_ptr->gamma_table[palette[i].red];
  943. palette[i].green = png_ptr->gamma_table[palette[i].green];
  944. palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  945. }
  946. }
  947. }
  948. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  949. else
  950. #endif
  951. #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
  952. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  953. /* No GAMMA transformation */
  954. if ((png_ptr->transformations & PNG_BACKGROUND) &&
  955. (color_type == PNG_COLOR_TYPE_PALETTE))
  956. {
  957. int i;
  958. int istop = (int)png_ptr->num_trans;
  959. png_color back;
  960. png_colorp palette = png_ptr->palette;
  961. back.red = (png_byte)png_ptr->background.red;
  962. back.green = (png_byte)png_ptr->background.green;
  963. back.blue = (png_byte)png_ptr->background.blue;
  964. for (i = 0; i < istop; i++)
  965. {
  966. if (png_ptr->trans[i] == 0)
  967. {
  968. palette[i] = back;
  969. }
  970. else if (png_ptr->trans[i] != 0xff)
  971. {
  972. /* The png_composite() macro is defined in png.h */
  973. png_composite(palette[i].red, palette[i].red,
  974. png_ptr->trans[i], back.red);
  975. png_composite(palette[i].green, palette[i].green,
  976. png_ptr->trans[i], back.green);
  977. png_composite(palette[i].blue, palette[i].blue,
  978. png_ptr->trans[i], back.blue);
  979. }
  980. }
  981. }
  982. #endif /* PNG_READ_BACKGROUND_SUPPORTED */
  983. #if defined(PNG_READ_SHIFT_SUPPORTED)
  984. if ((png_ptr->transformations & PNG_SHIFT) &&
  985. (color_type == PNG_COLOR_TYPE_PALETTE))
  986. {
  987. png_uint_16 i;
  988. png_uint_16 istop = png_ptr->num_palette;
  989. int sr = 8 - png_ptr->sig_bit.red;
  990. int sg = 8 - png_ptr->sig_bit.green;
  991. int sb = 8 - png_ptr->sig_bit.blue;
  992. if (sr < 0 || sr > 8)
  993. sr = 0;
  994. if (sg < 0 || sg > 8)
  995. sg = 0;
  996. if (sb < 0 || sb > 8)
  997. sb = 0;
  998. for (i = 0; i < istop; i++)
  999. {
  1000. png_ptr->palette[i].red >>= sr;
  1001. png_ptr->palette[i].green >>= sg;
  1002. png_ptr->palette[i].blue >>= sb;
  1003. }
  1004. }
  1005. #endif /* PNG_READ_SHIFT_SUPPORTED */
  1006. }
  1007. #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
  1008. && !defined(PNG_READ_BACKGROUND_SUPPORTED)
  1009. if(png_ptr)
  1010. return;
  1011. #endif
  1012. }
  1013. /* Modify the info structure to reflect the transformations. The
  1014. * info should be updated so a PNG file could be written with it,
  1015. * assuming the transformations result in valid PNG data.
  1016. */
  1017. void /* PRIVATE */
  1018. png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
  1019. {
  1020. png_debug(1, "in png_read_transform_info\n");
  1021. #if defined(PNG_READ_EXPAND_SUPPORTED)
  1022. if (png_ptr->transformations & PNG_EXPAND)
  1023. {
  1024. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1025. {
  1026. if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS))
  1027. info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  1028. else
  1029. info_ptr->color_type = PNG_COLOR_TYPE_RGB;
  1030. info_ptr->bit_depth = 8;
  1031. info_ptr->num_trans = 0;
  1032. }
  1033. else
  1034. {
  1035. if (png_ptr->num_trans)
  1036. {
  1037. if (png_ptr->transformations & PNG_EXPAND_tRNS)
  1038. info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  1039. else
  1040. info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  1041. }
  1042. if (info_ptr->bit_depth < 8)
  1043. info_ptr->bit_depth = 8;
  1044. info_ptr->num_trans = 0;
  1045. }
  1046. }
  1047. #endif
  1048. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1049. if (png_ptr->transformations & PNG_BACKGROUND)
  1050. {
  1051. info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  1052. info_ptr->num_trans = 0;
  1053. info_ptr->background = png_ptr->background;
  1054. }
  1055. #endif
  1056. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1057. if (png_ptr->transformations & PNG_GAMMA)
  1058. {
  1059. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1060. info_ptr->gamma = png_ptr->gamma;
  1061. #endif
  1062. #ifdef PNG_FIXED_POINT_SUPPORTED
  1063. info_ptr->int_gamma = png_ptr->int_gamma;
  1064. #endif
  1065. }
  1066. #endif
  1067. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1068. if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
  1069. info_ptr->bit_depth = 8;
  1070. #endif
  1071. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1072. if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  1073. info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  1074. #endif
  1075. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1076. if (png_ptr->transformations & PNG_RGB_TO_GRAY)
  1077. info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
  1078. #endif
  1079. #if defined(PNG_READ_DITHER_SUPPORTED)
  1080. if (png_ptr->transformations & PNG_DITHER)
  1081. {
  1082. if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  1083. (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
  1084. png_ptr->palette_lookup && info_ptr->bit_depth == 8)
  1085. {
  1086. info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
  1087. }
  1088. }
  1089. #endif
  1090. #if defined(PNG_READ_PACK_SUPPORTED)
  1091. if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
  1092. info_ptr->bit_depth = 8;
  1093. #endif
  1094. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1095. info_ptr->channels = 1;
  1096. else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1097. info_ptr->channels = 3;
  1098. else
  1099. info_ptr->channels = 1;
  1100. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  1101. if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
  1102. info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  1103. #endif
  1104. if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  1105. info_ptr->channels++;
  1106. #if defined(PNG_READ_FILLER_SUPPORTED)
  1107. /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
  1108. if ((png_ptr->transformations & PNG_FILLER) &&
  1109. ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  1110. (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
  1111. {
  1112. info_ptr->channels++;
  1113. /* if adding a true alpha channel not just filler */
  1114. #if !defined(PNG_1_0_X)
  1115. if (png_ptr->transformations & PNG_ADD_ALPHA)
  1116. info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  1117. #endif
  1118. }
  1119. #endif
  1120. #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
  1121. defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
  1122. if(png_ptr->transformations & PNG_USER_TRANSFORM)
  1123. {
  1124. if(info_ptr->bit_depth < png_ptr->user_transform_depth)
  1125. info_ptr->bit_depth = png_ptr->user_transform_depth;
  1126. if(info_ptr->channels < png_ptr->user_transform_channels)
  1127. info_ptr->channels = png_ptr->user_transform_channels;
  1128. }
  1129. #endif
  1130. info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
  1131. info_ptr->bit_depth);
  1132. info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
  1133. #if !defined(PNG_READ_EXPAND_SUPPORTED)
  1134. if(png_ptr)
  1135. return;
  1136. #endif
  1137. }
  1138. /* Transform the row. The order of transformations is significant,
  1139. * and is very touchy. If you add a transformation, take care to
  1140. * decide how it fits in with the other transformations here.
  1141. */
  1142. void /* PRIVATE */
  1143. png_do_read_transformations(png_structp png_ptr)
  1144. {
  1145. png_debug(1, "in png_do_read_transformations\n");
  1146. if (png_ptr->row_buf == NULL)
  1147. {
  1148. #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
  1149. char msg[50];
  1150. png_snprintf2(msg, 50,
  1151. "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
  1152. png_ptr->pass);
  1153. png_error(png_ptr, msg);
  1154. #else
  1155. png_error(png_ptr, "NULL row buffer");
  1156. #endif
  1157. }
  1158. #ifdef PNG_WARN_UNINITIALIZED_ROW
  1159. if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  1160. /* Application has failed to call either png_read_start_image()
  1161. * or png_read_update_info() after setting transforms that expand
  1162. * pixels. This check added to libpng-1.2.19 */
  1163. #if (PNG_WARN_UNINITIALIZED_ROW==1)
  1164. png_error(png_ptr, "Uninitialized row");
  1165. #else
  1166. png_warning(png_ptr, "Uninitialized row");
  1167. #endif
  1168. #endif
  1169. #if defined(PNG_READ_EXPAND_SUPPORTED)
  1170. if (png_ptr->transformations & PNG_EXPAND)
  1171. {
  1172. if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
  1173. {
  1174. png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1175. png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
  1176. }
  1177. else
  1178. {
  1179. if (png_ptr->num_trans &&
  1180. (png_ptr->transformations & PNG_EXPAND_tRNS))
  1181. png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1182. &(png_ptr->trans_values));
  1183. else
  1184. png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1185. NULL);
  1186. }
  1187. }
  1188. #endif
  1189. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  1190. if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
  1191. png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1192. PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
  1193. #endif
  1194. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1195. if (png_ptr->transformations & PNG_RGB_TO_GRAY)
  1196. {
  1197. int rgb_error =
  1198. png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
  1199. if(rgb_error)
  1200. {
  1201. png_ptr->rgb_to_gray_status=1;
  1202. if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
  1203. PNG_RGB_TO_GRAY_WARN)
  1204. png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
  1205. if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
  1206. PNG_RGB_TO_GRAY_ERR)
  1207. png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
  1208. }
  1209. }
  1210. #endif
  1211. /*
  1212. From Andreas Dilger e-mail to png-implement, 26 March 1998:
  1213. In most cases, the "simple transparency" should be done prior to doing
  1214. gray-to-RGB, or you will have to test 3x as many bytes to check if a
  1215. pixel is transparent. You would also need to make sure that the
  1216. transparency information is upgraded to RGB.
  1217. To summarize, the current flow is:
  1218. - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
  1219. with background "in place" if transparent,
  1220. convert to RGB if necessary
  1221. - Gray + alpha -> composite with gray background and remove alpha bytes,
  1222. convert to RGB if necessary
  1223. To support RGB backgrounds for gray images we need:
  1224. - Gray + simple transparency -> convert to RGB + simple transparency, compare
  1225. 3 or 6 bytes and composite with background
  1226. "in place" if transparent (3x compare/pixel
  1227. compared to doing composite with gray bkgrnd)
  1228. - Gray + alpha -> convert to RGB + alpha, composite with background and
  1229. remove alpha bytes (3x float operations/pixel
  1230. compared with composite on gray background)
  1231. Greg's change will do this. The reason it wasn't done before is for
  1232. performance, as this increases the per-pixel operations. If we would check
  1233. in advance if the background was gray or RGB, and position the gray-to-RGB
  1234. transform appropriately, then it would save a lot of work/time.
  1235. */
  1236. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1237. /* if gray -> RGB, do so now only if background is non-gray; else do later
  1238. * for performance reasons */
  1239. if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  1240. !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
  1241. png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1242. #endif
  1243. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1244. if ((png_ptr->transformations & PNG_BACKGROUND) &&
  1245. ((png_ptr->num_trans != 0 ) ||
  1246. (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
  1247. png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1248. &(png_ptr->trans_values), &(png_ptr->background)
  1249. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1250. , &(png_ptr->background_1),
  1251. png_ptr->gamma_table, png_ptr->gamma_from_1,
  1252. png_ptr->gamma_to_1, png_ptr->gamma_16_table,
  1253. png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
  1254. png_ptr->gamma_shift
  1255. #endif
  1256. );
  1257. #endif
  1258. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1259. if ((png_ptr->transformations & PNG_GAMMA) &&
  1260. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1261. !((png_ptr->transformations & PNG_BACKGROUND) &&
  1262. ((png_ptr->num_trans != 0) ||
  1263. (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
  1264. #endif
  1265. (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
  1266. png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1267. png_ptr->gamma_table, png_ptr->gamma_16_table,
  1268. png_ptr->gamma_shift);
  1269. #endif
  1270. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1271. if (png_pt

Large files files are truncated, but you can click here to view the full file