The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4288 lines
148KB

  1. /* pngrtran.c - transforms the data in a row for PNG readers
  2. *
  3. * Last changed in libpng 1.2.21 [October 4, 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. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  517. #endif
  518. }
  519. #if !defined(PNG_1_0_X)
  520. /* Expand grayscale images of less than 8-bit depth to 8 bits. */
  521. void PNGAPI
  522. png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
  523. {
  524. png_debug(1, "in png_set_expand_gray_1_2_4_to_8\n");
  525. if(png_ptr == NULL) return;
  526. png_ptr->transformations |= PNG_EXPAND;
  527. #ifdef PNG_WARN_UNINITIALIZED_ROW
  528. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  529. #endif
  530. }
  531. #endif
  532. #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
  533. /* Expand grayscale images of less than 8-bit depth to 8 bits. */
  534. /* Deprecated as of libpng-1.2.9 */
  535. void PNGAPI
  536. png_set_gray_1_2_4_to_8(png_structp png_ptr)
  537. {
  538. png_debug(1, "in png_set_gray_1_2_4_to_8\n");
  539. if(png_ptr == NULL) return;
  540. png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  541. }
  542. #endif
  543. /* Expand tRNS chunks to alpha channels. */
  544. void PNGAPI
  545. png_set_tRNS_to_alpha(png_structp png_ptr)
  546. {
  547. png_debug(1, "in png_set_tRNS_to_alpha\n");
  548. png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
  549. #ifdef PNG_WARN_UNINITIALIZED_ROW
  550. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  551. #endif
  552. }
  553. #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
  554. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  555. void PNGAPI
  556. png_set_gray_to_rgb(png_structp png_ptr)
  557. {
  558. png_debug(1, "in png_set_gray_to_rgb\n");
  559. png_ptr->transformations |= PNG_GRAY_TO_RGB;
  560. #ifdef PNG_WARN_UNINITIALIZED_ROW
  561. png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
  562. #endif
  563. }
  564. #endif
  565. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  566. #if defined(PNG_FLOATING_POINT_SUPPORTED)
  567. /* Convert a RGB image to a grayscale of the same width. This allows us,
  568. * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
  569. */
  570. void PNGAPI
  571. png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
  572. double green)
  573. {
  574. int red_fixed = (int)((float)red*100000.0 + 0.5);
  575. int green_fixed = (int)((float)green*100000.0 + 0.5);
  576. if(png_ptr == NULL) return;
  577. png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
  578. }
  579. #endif
  580. void PNGAPI
  581. png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
  582. png_fixed_point red, png_fixed_point green)
  583. {
  584. png_debug(1, "in png_set_rgb_to_gray\n");
  585. if(png_ptr == NULL) return;
  586. switch(error_action)
  587. {
  588. case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
  589. break;
  590. case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
  591. break;
  592. case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
  593. }
  594. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  595. #if defined(PNG_READ_EXPAND_SUPPORTED)
  596. png_ptr->transformations |= PNG_EXPAND;
  597. #else
  598. {
  599. png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
  600. png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
  601. }
  602. #endif
  603. {
  604. png_uint_16 red_int, green_int;
  605. if(red < 0 || green < 0)
  606. {
  607. red_int = 6968; /* .212671 * 32768 + .5 */
  608. green_int = 23434; /* .715160 * 32768 + .5 */
  609. }
  610. else if(red + green < 100000L)
  611. {
  612. red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
  613. green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
  614. }
  615. else
  616. {
  617. png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
  618. red_int = 6968;
  619. green_int = 23434;
  620. }
  621. png_ptr->rgb_to_gray_red_coeff = red_int;
  622. png_ptr->rgb_to_gray_green_coeff = green_int;
  623. png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int);
  624. }
  625. }
  626. #endif
  627. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
  628. defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
  629. defined(PNG_LEGACY_SUPPORTED)
  630. void PNGAPI
  631. png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
  632. read_user_transform_fn)
  633. {
  634. png_debug(1, "in png_set_read_user_transform_fn\n");
  635. if(png_ptr == NULL) return;
  636. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
  637. png_ptr->transformations |= PNG_USER_TRANSFORM;
  638. png_ptr->read_user_transform_fn = read_user_transform_fn;
  639. #endif
  640. #ifdef PNG_LEGACY_SUPPORTED
  641. if(read_user_transform_fn)
  642. png_warning(png_ptr,
  643. "This version of libpng does not support user transforms");
  644. #endif
  645. }
  646. #endif
  647. /* Initialize everything needed for the read. This includes modifying
  648. * the palette.
  649. */
  650. void /* PRIVATE */
  651. png_init_read_transformations(png_structp png_ptr)
  652. {
  653. png_debug(1, "in png_init_read_transformations\n");
  654. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  655. if(png_ptr != NULL)
  656. #endif
  657. {
  658. #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
  659. || defined(PNG_READ_GAMMA_SUPPORTED)
  660. int color_type = png_ptr->color_type;
  661. #endif
  662. #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
  663. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  664. /* Detect gray background and attempt to enable optimization
  665. * for gray --> RGB case */
  666. /* Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
  667. * RGB_ALPHA (in which case need_expand is superfluous anyway), the
  668. * background color might actually be gray yet not be flagged as such.
  669. * This is not a problem for the current code, which uses
  670. * PNG_BACKGROUND_IS_GRAY only to decide when to do the
  671. * png_do_gray_to_rgb() transformation.
  672. */
  673. if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  674. !(color_type & PNG_COLOR_MASK_COLOR))
  675. {
  676. png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
  677. } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
  678. !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  679. (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  680. png_ptr->background.red == png_ptr->background.green &&
  681. png_ptr->background.red == png_ptr->background.blue)
  682. {
  683. png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
  684. png_ptr->background.gray = png_ptr->background.red;
  685. }
  686. #endif
  687. if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
  688. (png_ptr->transformations & PNG_EXPAND))
  689. {
  690. if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
  691. {
  692. /* expand background and tRNS chunks */
  693. switch (png_ptr->bit_depth)
  694. {
  695. case 1:
  696. png_ptr->background.gray *= (png_uint_16)0xff;
  697. png_ptr->background.red = png_ptr->background.green
  698. = png_ptr->background.blue = png_ptr->background.gray;
  699. if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  700. {
  701. png_ptr->trans_values.gray *= (png_uint_16)0xff;
  702. png_ptr->trans_values.red = png_ptr->trans_values.green
  703. = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  704. }
  705. break;
  706. case 2:
  707. png_ptr->background.gray *= (png_uint_16)0x55;
  708. png_ptr->background.red = png_ptr->background.green
  709. = png_ptr->background.blue = png_ptr->background.gray;
  710. if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  711. {
  712. png_ptr->trans_values.gray *= (png_uint_16)0x55;
  713. png_ptr->trans_values.red = png_ptr->trans_values.green
  714. = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  715. }
  716. break;
  717. case 4:
  718. png_ptr->background.gray *= (png_uint_16)0x11;
  719. png_ptr->background.red = png_ptr->background.green
  720. = png_ptr->background.blue = png_ptr->background.gray;
  721. if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  722. {
  723. png_ptr->trans_values.gray *= (png_uint_16)0x11;
  724. png_ptr->trans_values.red = png_ptr->trans_values.green
  725. = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
  726. }
  727. break;
  728. case 8:
  729. case 16:
  730. png_ptr->background.red = png_ptr->background.green
  731. = png_ptr->background.blue = png_ptr->background.gray;
  732. break;
  733. }
  734. }
  735. else if (color_type == PNG_COLOR_TYPE_PALETTE)
  736. {
  737. png_ptr->background.red =
  738. png_ptr->palette[png_ptr->background.index].red;
  739. png_ptr->background.green =
  740. png_ptr->palette[png_ptr->background.index].green;
  741. png_ptr->background.blue =
  742. png_ptr->palette[png_ptr->background.index].blue;
  743. #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
  744. if (png_ptr->transformations & PNG_INVERT_ALPHA)
  745. {
  746. #if defined(PNG_READ_EXPAND_SUPPORTED)
  747. if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
  748. #endif
  749. {
  750. /* invert the alpha channel (in tRNS) unless the pixels are
  751. going to be expanded, in which case leave it for later */
  752. int i,istop;
  753. istop=(int)png_ptr->num_trans;
  754. for (i=0; i<istop; i++)
  755. png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
  756. }
  757. }
  758. #endif
  759. }
  760. }
  761. #endif
  762. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
  763. png_ptr->background_1 = png_ptr->background;
  764. #endif
  765. #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
  766. if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
  767. && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
  768. < PNG_GAMMA_THRESHOLD))
  769. {
  770. int i,k;
  771. k=0;
  772. for (i=0; i<png_ptr->num_trans; i++)
  773. {
  774. if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
  775. k=1; /* partial transparency is present */
  776. }
  777. if (k == 0)
  778. png_ptr->transformations &= (~PNG_GAMMA);
  779. }
  780. if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
  781. png_ptr->gamma != 0.0)
  782. {
  783. png_build_gamma_table(png_ptr);
  784. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  785. if (png_ptr->transformations & PNG_BACKGROUND)
  786. {
  787. if (color_type == PNG_COLOR_TYPE_PALETTE)
  788. {
  789. /* could skip if no transparency and
  790. */
  791. png_color back, back_1;
  792. png_colorp palette = png_ptr->palette;
  793. int num_palette = png_ptr->num_palette;
  794. int i;
  795. if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
  796. {
  797. back.red = png_ptr->gamma_table[png_ptr->background.red];
  798. back.green = png_ptr->gamma_table[png_ptr->background.green];
  799. back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  800. back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  801. back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  802. back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  803. }
  804. else
  805. {
  806. double g, gs;
  807. switch (png_ptr->background_gamma_type)
  808. {
  809. case PNG_BACKGROUND_GAMMA_SCREEN:
  810. g = (png_ptr->screen_gamma);
  811. gs = 1.0;
  812. break;
  813. case PNG_BACKGROUND_GAMMA_FILE:
  814. g = 1.0 / (png_ptr->gamma);
  815. gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  816. break;
  817. case PNG_BACKGROUND_GAMMA_UNIQUE:
  818. g = 1.0 / (png_ptr->background_gamma);
  819. gs = 1.0 / (png_ptr->background_gamma *
  820. png_ptr->screen_gamma);
  821. break;
  822. default:
  823. g = 1.0; /* back_1 */
  824. gs = 1.0; /* back */
  825. }
  826. if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
  827. {
  828. back.red = (png_byte)png_ptr->background.red;
  829. back.green = (png_byte)png_ptr->background.green;
  830. back.blue = (png_byte)png_ptr->background.blue;
  831. }
  832. else
  833. {
  834. back.red = (png_byte)(pow(
  835. (double)png_ptr->background.red/255, gs) * 255.0 + .5);
  836. back.green = (png_byte)(pow(
  837. (double)png_ptr->background.green/255, gs) * 255.0 + .5);
  838. back.blue = (png_byte)(pow(
  839. (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
  840. }
  841. back_1.red = (png_byte)(pow(
  842. (double)png_ptr->background.red/255, g) * 255.0 + .5);
  843. back_1.green = (png_byte)(pow(
  844. (double)png_ptr->background.green/255, g) * 255.0 + .5);
  845. back_1.blue = (png_byte)(pow(
  846. (double)png_ptr->background.blue/255, g) * 255.0 + .5);
  847. }
  848. for (i = 0; i < num_palette; i++)
  849. {
  850. if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
  851. {
  852. if (png_ptr->trans[i] == 0)
  853. {
  854. palette[i] = back;
  855. }
  856. else /* if (png_ptr->trans[i] != 0xff) */
  857. {
  858. png_byte v, w;
  859. v = png_ptr->gamma_to_1[palette[i].red];
  860. png_composite(w, v, png_ptr->trans[i], back_1.red);
  861. palette[i].red = png_ptr->gamma_from_1[w];
  862. v = png_ptr->gamma_to_1[palette[i].green];
  863. png_composite(w, v, png_ptr->trans[i], back_1.green);
  864. palette[i].green = png_ptr->gamma_from_1[w];
  865. v = png_ptr->gamma_to_1[palette[i].blue];
  866. png_composite(w, v, png_ptr->trans[i], back_1.blue);
  867. palette[i].blue = png_ptr->gamma_from_1[w];
  868. }
  869. }
  870. else
  871. {
  872. palette[i].red = png_ptr->gamma_table[palette[i].red];
  873. palette[i].green = png_ptr->gamma_table[palette[i].green];
  874. palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  875. }
  876. }
  877. }
  878. /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
  879. else
  880. /* color_type != PNG_COLOR_TYPE_PALETTE */
  881. {
  882. double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
  883. double g = 1.0;
  884. double gs = 1.0;
  885. switch (png_ptr->background_gamma_type)
  886. {
  887. case PNG_BACKGROUND_GAMMA_SCREEN:
  888. g = (png_ptr->screen_gamma);
  889. gs = 1.0;
  890. break;
  891. case PNG_BACKGROUND_GAMMA_FILE:
  892. g = 1.0 / (png_ptr->gamma);
  893. gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  894. break;
  895. case PNG_BACKGROUND_GAMMA_UNIQUE:
  896. g = 1.0 / (png_ptr->background_gamma);
  897. gs = 1.0 / (png_ptr->background_gamma *
  898. png_ptr->screen_gamma);
  899. break;
  900. }
  901. png_ptr->background_1.gray = (png_uint_16)(pow(
  902. (double)png_ptr->background.gray / m, g) * m + .5);
  903. png_ptr->background.gray = (png_uint_16)(pow(
  904. (double)png_ptr->background.gray / m, gs) * m + .5);
  905. if ((png_ptr->background.red != png_ptr->background.green) ||
  906. (png_ptr->background.red != png_ptr->background.blue) ||
  907. (png_ptr->background.red != png_ptr->background.gray))
  908. {
  909. /* RGB or RGBA with color background */
  910. png_ptr->background_1.red = (png_uint_16)(pow(
  911. (double)png_ptr->background.red / m, g) * m + .5);
  912. png_ptr->background_1.green = (png_uint_16)(pow(
  913. (double)png_ptr->background.green / m, g) * m + .5);
  914. png_ptr->background_1.blue = (png_uint_16)(pow(
  915. (double)png_ptr->background.blue / m, g) * m + .5);
  916. png_ptr->background.red = (png_uint_16)(pow(
  917. (double)png_ptr->background.red / m, gs) * m + .5);
  918. png_ptr->background.green = (png_uint_16)(pow(
  919. (double)png_ptr->background.green / m, gs) * m + .5);
  920. png_ptr->background.blue = (png_uint_16)(pow(
  921. (double)png_ptr->background.blue / m, gs) * m + .5);
  922. }
  923. else
  924. {
  925. /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
  926. png_ptr->background_1.red = png_ptr->background_1.green
  927. = png_ptr->background_1.blue = png_ptr->background_1.gray;
  928. png_ptr->background.red = png_ptr->background.green
  929. = png_ptr->background.blue = png_ptr->background.gray;
  930. }
  931. }
  932. }
  933. else
  934. /* transformation does not include PNG_BACKGROUND */
  935. #endif /* PNG_READ_BACKGROUND_SUPPORTED */
  936. if (color_type == PNG_COLOR_TYPE_PALETTE)
  937. {
  938. png_colorp palette = png_ptr->palette;
  939. int num_palette = png_ptr->num_palette;
  940. int i;
  941. for (i = 0; i < num_palette; i++)
  942. {
  943. palette[i].red = png_ptr->gamma_table[palette[i].red];
  944. palette[i].green = png_ptr->gamma_table[palette[i].green];
  945. palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  946. }
  947. }
  948. }
  949. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  950. else
  951. #endif
  952. #endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
  953. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  954. /* No GAMMA transformation */
  955. if ((png_ptr->transformations & PNG_BACKGROUND) &&
  956. (color_type == PNG_COLOR_TYPE_PALETTE))
  957. {
  958. int i;
  959. int istop = (int)png_ptr->num_trans;
  960. png_color back;
  961. png_colorp palette = png_ptr->palette;
  962. back.red = (png_byte)png_ptr->background.red;
  963. back.green = (png_byte)png_ptr->background.green;
  964. back.blue = (png_byte)png_ptr->background.blue;
  965. for (i = 0; i < istop; i++)
  966. {
  967. if (png_ptr->trans[i] == 0)
  968. {
  969. palette[i] = back;
  970. }
  971. else if (png_ptr->trans[i] != 0xff)
  972. {
  973. /* The png_composite() macro is defined in png.h */
  974. png_composite(palette[i].red, palette[i].red,
  975. png_ptr->trans[i], back.red);
  976. png_composite(palette[i].green, palette[i].green,
  977. png_ptr->trans[i], back.green);
  978. png_composite(palette[i].blue, palette[i].blue,
  979. png_ptr->trans[i], back.blue);
  980. }
  981. }
  982. }
  983. #endif /* PNG_READ_BACKGROUND_SUPPORTED */
  984. #if defined(PNG_READ_SHIFT_SUPPORTED)
  985. if ((png_ptr->transformations & PNG_SHIFT) &&
  986. (color_type == PNG_COLOR_TYPE_PALETTE))
  987. {
  988. png_uint_16 i;
  989. png_uint_16 istop = png_ptr->num_palette;
  990. int sr = 8 - png_ptr->sig_bit.red;
  991. int sg = 8 - png_ptr->sig_bit.green;
  992. int sb = 8 - png_ptr->sig_bit.blue;
  993. if (sr < 0 || sr > 8)
  994. sr = 0;
  995. if (sg < 0 || sg > 8)
  996. sg = 0;
  997. if (sb < 0 || sb > 8)
  998. sb = 0;
  999. for (i = 0; i < istop; i++)
  1000. {
  1001. png_ptr->palette[i].red >>= sr;
  1002. png_ptr->palette[i].green >>= sg;
  1003. png_ptr->palette[i].blue >>= sb;
  1004. }
  1005. }
  1006. #endif /* PNG_READ_SHIFT_SUPPORTED */
  1007. }
  1008. #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
  1009. && !defined(PNG_READ_BACKGROUND_SUPPORTED)
  1010. if(png_ptr)
  1011. return;
  1012. #endif
  1013. }
  1014. /* Modify the info structure to reflect the transformations. The
  1015. * info should be updated so a PNG file could be written with it,
  1016. * assuming the transformations result in valid PNG data.
  1017. */
  1018. void /* PRIVATE */
  1019. png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
  1020. {
  1021. png_debug(1, "in png_read_transform_info\n");
  1022. #if defined(PNG_READ_EXPAND_SUPPORTED)
  1023. if (png_ptr->transformations & PNG_EXPAND)
  1024. {
  1025. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1026. {
  1027. if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS))
  1028. info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  1029. else
  1030. info_ptr->color_type = PNG_COLOR_TYPE_RGB;
  1031. info_ptr->bit_depth = 8;
  1032. info_ptr->num_trans = 0;
  1033. }
  1034. else
  1035. {
  1036. if (png_ptr->num_trans)
  1037. {
  1038. if (png_ptr->transformations & PNG_EXPAND_tRNS)
  1039. info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  1040. else
  1041. info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  1042. }
  1043. if (info_ptr->bit_depth < 8)
  1044. info_ptr->bit_depth = 8;
  1045. info_ptr->num_trans = 0;
  1046. }
  1047. }
  1048. #endif
  1049. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1050. if (png_ptr->transformations & PNG_BACKGROUND)
  1051. {
  1052. info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  1053. info_ptr->num_trans = 0;
  1054. info_ptr->background = png_ptr->background;
  1055. }
  1056. #endif
  1057. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1058. if (png_ptr->transformations & PNG_GAMMA)
  1059. {
  1060. #ifdef PNG_FLOATING_POINT_SUPPORTED
  1061. info_ptr->gamma = png_ptr->gamma;
  1062. #endif
  1063. #ifdef PNG_FIXED_POINT_SUPPORTED
  1064. info_ptr->int_gamma = png_ptr->int_gamma;
  1065. #endif
  1066. }
  1067. #endif
  1068. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1069. if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
  1070. info_ptr->bit_depth = 8;
  1071. #endif
  1072. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1073. if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  1074. info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
  1075. #endif
  1076. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1077. if (png_ptr->transformations & PNG_RGB_TO_GRAY)
  1078. info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
  1079. #endif
  1080. #if defined(PNG_READ_DITHER_SUPPORTED)
  1081. if (png_ptr->transformations & PNG_DITHER)
  1082. {
  1083. if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  1084. (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
  1085. png_ptr->palette_lookup && info_ptr->bit_depth == 8)
  1086. {
  1087. info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
  1088. }
  1089. }
  1090. #endif
  1091. #if defined(PNG_READ_PACK_SUPPORTED)
  1092. if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
  1093. info_ptr->bit_depth = 8;
  1094. #endif
  1095. if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1096. info_ptr->channels = 1;
  1097. else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
  1098. info_ptr->channels = 3;
  1099. else
  1100. info_ptr->channels = 1;
  1101. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  1102. if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
  1103. info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
  1104. #endif
  1105. if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
  1106. info_ptr->channels++;
  1107. #if defined(PNG_READ_FILLER_SUPPORTED)
  1108. /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
  1109. if ((png_ptr->transformations & PNG_FILLER) &&
  1110. ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
  1111. (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
  1112. {
  1113. info_ptr->channels++;
  1114. /* if adding a true alpha channel not just filler */
  1115. #if !defined(PNG_1_0_X)
  1116. if (png_ptr->transformations & PNG_ADD_ALPHA)
  1117. info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
  1118. #endif
  1119. }
  1120. #endif
  1121. #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
  1122. defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
  1123. if(png_ptr->transformations & PNG_USER_TRANSFORM)
  1124. {
  1125. if(info_ptr->bit_depth < png_ptr->user_transform_depth)
  1126. info_ptr->bit_depth = png_ptr->user_transform_depth;
  1127. if(info_ptr->channels < png_ptr->user_transform_channels)
  1128. info_ptr->channels = png_ptr->user_transform_channels;
  1129. }
  1130. #endif
  1131. info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
  1132. info_ptr->bit_depth);
  1133. info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width);
  1134. #if !defined(PNG_READ_EXPAND_SUPPORTED)
  1135. if(png_ptr)
  1136. return;
  1137. #endif
  1138. }
  1139. /* Transform the row. The order of transformations is significant,
  1140. * and is very touchy. If you add a transformation, take care to
  1141. * decide how it fits in with the other transformations here.
  1142. */
  1143. void /* PRIVATE */
  1144. png_do_read_transformations(png_structp png_ptr)
  1145. {
  1146. png_debug(1, "in png_do_read_transformations\n");
  1147. if (png_ptr->row_buf == NULL)
  1148. {
  1149. #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
  1150. char msg[50];
  1151. png_snprintf2(msg, 50,
  1152. "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
  1153. png_ptr->pass);
  1154. png_error(png_ptr, msg);
  1155. #else
  1156. png_error(png_ptr, "NULL row buffer");
  1157. #endif
  1158. }
  1159. #ifdef PNG_WARN_UNINITIALIZED_ROW
  1160. if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
  1161. /* Application has failed to call either png_read_start_image()
  1162. * or png_read_update_info() after setting transforms that expand
  1163. * pixels. This check added to libpng-1.2.19 */
  1164. #if (PNG_WARN_UNINITIALIZED_ROW==1)
  1165. png_error(png_ptr, "Uninitialized row");
  1166. #else
  1167. png_warning(png_ptr, "Uninitialized row");
  1168. #endif
  1169. #endif
  1170. #if defined(PNG_READ_EXPAND_SUPPORTED)
  1171. if (png_ptr->transformations & PNG_EXPAND)
  1172. {
  1173. if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
  1174. {
  1175. png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1176. png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
  1177. }
  1178. else
  1179. {
  1180. if (png_ptr->num_trans &&
  1181. (png_ptr->transformations & PNG_EXPAND_tRNS))
  1182. png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1183. &(png_ptr->trans_values));
  1184. else
  1185. png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1186. NULL);
  1187. }
  1188. }
  1189. #endif
  1190. #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
  1191. if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
  1192. png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1193. PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
  1194. #endif
  1195. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  1196. if (png_ptr->transformations & PNG_RGB_TO_GRAY)
  1197. {
  1198. int rgb_error =
  1199. png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
  1200. if(rgb_error)
  1201. {
  1202. png_ptr->rgb_to_gray_status=1;
  1203. if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
  1204. PNG_RGB_TO_GRAY_WARN)
  1205. png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
  1206. if((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
  1207. PNG_RGB_TO_GRAY_ERR)
  1208. png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
  1209. }
  1210. }
  1211. #endif
  1212. /*
  1213. From Andreas Dilger e-mail to png-implement, 26 March 1998:
  1214. In most cases, the "simple transparency" should be done prior to doing
  1215. gray-to-RGB, or you will have to test 3x as many bytes to check if a
  1216. pixel is transparent. You would also need to make sure that the
  1217. transparency information is upgraded to RGB.
  1218. To summarize, the current flow is:
  1219. - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
  1220. with background "in place" if transparent,
  1221. convert to RGB if necessary
  1222. - Gray + alpha -> composite with gray background and remove alpha bytes,
  1223. convert to RGB if necessary
  1224. To support RGB backgrounds for gray images we need:
  1225. - Gray + simple transparency -> convert to RGB + simple transparency, compare
  1226. 3 or 6 bytes and composite with background
  1227. "in place" if transparent (3x compare/pixel
  1228. compared to doing composite with gray bkgrnd)
  1229. - Gray + alpha -> convert to RGB + alpha, composite with background and
  1230. remove alpha bytes (3x float operations/pixel
  1231. compared with composite on gray background)
  1232. Greg's change will do this. The reason it wasn't done before is for
  1233. performance, as this increases the per-pixel operations. If we would check
  1234. in advance if the background was gray or RGB, and position the gray-to-RGB
  1235. transform appropriately, then it would save a lot of work/time.
  1236. */
  1237. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1238. /* if gray -> RGB, do so now only if background is non-gray; else do later
  1239. * for performance reasons */
  1240. if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  1241. !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
  1242. png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1243. #endif
  1244. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1245. if ((png_ptr->transformations & PNG_BACKGROUND) &&
  1246. ((png_ptr->num_trans != 0 ) ||
  1247. (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
  1248. png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1249. &(png_ptr->trans_values), &(png_ptr->background)
  1250. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1251. , &(png_ptr->background_1),
  1252. png_ptr->gamma_table, png_ptr->gamma_from_1,
  1253. png_ptr->gamma_to_1, png_ptr->gamma_16_table,
  1254. png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
  1255. png_ptr->gamma_shift
  1256. #endif
  1257. );
  1258. #endif
  1259. #if defined(PNG_READ_GAMMA_SUPPORTED)
  1260. if ((png_ptr->transformations & PNG_GAMMA) &&
  1261. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  1262. !((png_ptr->transformations & PNG_BACKGROUND) &&
  1263. ((png_ptr->num_trans != 0) ||
  1264. (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
  1265. #endif
  1266. (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
  1267. png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1268. png_ptr->gamma_table, png_ptr->gamma_16_table,
  1269. png_ptr->gamma_shift);
  1270. #endif
  1271. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1272. if (png_ptr->transformations & PNG_16_TO_8)
  1273. png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1274. #endif
  1275. #if defined(PNG_READ_DITHER_SUPPORTED)
  1276. if (png_ptr->transformations & PNG_DITHER)
  1277. {
  1278. png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
  1279. png_ptr->palette_lookup, png_ptr->dither_index);
  1280. if(png_ptr->row_info.rowbytes == (png_uint_32)0)
  1281. png_error(png_ptr, "png_do_dither returned rowbytes=0");
  1282. }
  1283. #endif
  1284. #if defined(PNG_READ_INVERT_SUPPORTED)
  1285. if (png_ptr->transformations & PNG_INVERT_MONO)
  1286. png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1287. #endif
  1288. #if defined(PNG_READ_SHIFT_SUPPORTED)
  1289. if (png_ptr->transformations & PNG_SHIFT)
  1290. png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1291. &(png_ptr->shift));
  1292. #endif
  1293. #if defined(PNG_READ_PACK_SUPPORTED)
  1294. if (png_ptr->transformations & PNG_PACK)
  1295. png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1296. #endif
  1297. #if defined(PNG_READ_BGR_SUPPORTED)
  1298. if (png_ptr->transformations & PNG_BGR)
  1299. png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1300. #endif
  1301. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1302. if (png_ptr->transformations & PNG_PACKSWAP)
  1303. png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1304. #endif
  1305. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1306. /* if gray -> RGB, do so now only if we did not do so above */
  1307. if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
  1308. (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
  1309. png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1310. #endif
  1311. #if defined(PNG_READ_FILLER_SUPPORTED)
  1312. if (png_ptr->transformations & PNG_FILLER)
  1313. png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
  1314. (png_uint_32)png_ptr->filler, png_ptr->flags);
  1315. #endif
  1316. #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
  1317. if (png_ptr->transformations & PNG_INVERT_ALPHA)
  1318. png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1319. #endif
  1320. #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
  1321. if (png_ptr->transformations & PNG_SWAP_ALPHA)
  1322. png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1323. #endif
  1324. #if defined(PNG_READ_SWAP_SUPPORTED)
  1325. if (png_ptr->transformations & PNG_SWAP_BYTES)
  1326. png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
  1327. #endif
  1328. #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
  1329. if (png_ptr->transformations & PNG_USER_TRANSFORM)
  1330. {
  1331. if(png_ptr->read_user_transform_fn != NULL)
  1332. (*(png_ptr->read_user_transform_fn)) /* user read transform function */
  1333. (png_ptr, /* png_ptr */
  1334. &(png_ptr->row_info), /* row_info: */
  1335. /* png_uint_32 width; width of row */
  1336. /* png_uint_32 rowbytes; number of bytes in row */
  1337. /* png_byte color_type; color type of pixels */
  1338. /* png_byte bit_depth; bit depth of samples */
  1339. /* png_byte channels; number of channels (1-4) */
  1340. /* png_byte pixel_depth; bits per pixel (depth*channels) */
  1341. png_ptr->row_buf + 1); /* start of pixel data for row */
  1342. #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
  1343. if(png_ptr->user_transform_depth)
  1344. png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
  1345. if(png_ptr->user_transform_channels)
  1346. png_ptr->row_info.channels = png_ptr->user_transform_channels;
  1347. #endif
  1348. png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
  1349. png_ptr->row_info.channels);
  1350. png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
  1351. png_ptr->row_info.width);
  1352. }
  1353. #endif
  1354. }
  1355. #if defined(PNG_READ_PACK_SUPPORTED)
  1356. /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
  1357. * without changing the actual values. Thus, if you had a row with
  1358. * a bit depth of 1, you would end up with bytes that only contained
  1359. * the numbers 0 or 1. If you would rather they contain 0 and 255, use
  1360. * png_do_shift() after this.
  1361. */
  1362. void /* PRIVATE */
  1363. png_do_unpack(png_row_infop row_info, png_bytep row)
  1364. {
  1365. png_debug(1, "in png_do_unpack\n");
  1366. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1367. if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
  1368. #else
  1369. if (row_info->bit_depth < 8)
  1370. #endif
  1371. {
  1372. png_uint_32 i;
  1373. png_uint_32 row_width=row_info->width;
  1374. switch (row_info->bit_depth)
  1375. {
  1376. case 1:
  1377. {
  1378. png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
  1379. png_bytep dp = row + (png_size_t)row_width - 1;
  1380. png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
  1381. for (i = 0; i < row_width; i++)
  1382. {
  1383. *dp = (png_byte)((*sp >> shift) & 0x01);
  1384. if (shift == 7)
  1385. {
  1386. shift = 0;
  1387. sp--;
  1388. }
  1389. else
  1390. shift++;
  1391. dp--;
  1392. }
  1393. break;
  1394. }
  1395. case 2:
  1396. {
  1397. png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
  1398. png_bytep dp = row + (png_size_t)row_width - 1;
  1399. png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
  1400. for (i = 0; i < row_width; i++)
  1401. {
  1402. *dp = (png_byte)((*sp >> shift) & 0x03);
  1403. if (shift == 6)
  1404. {
  1405. shift = 0;
  1406. sp--;
  1407. }
  1408. else
  1409. shift += 2;
  1410. dp--;
  1411. }
  1412. break;
  1413. }
  1414. case 4:
  1415. {
  1416. png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
  1417. png_bytep dp = row + (png_size_t)row_width - 1;
  1418. png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
  1419. for (i = 0; i < row_width; i++)
  1420. {
  1421. *dp = (png_byte)((*sp >> shift) & 0x0f);
  1422. if (shift == 4)
  1423. {
  1424. shift = 0;
  1425. sp--;
  1426. }
  1427. else
  1428. shift = 4;
  1429. dp--;
  1430. }
  1431. break;
  1432. }
  1433. }
  1434. row_info->bit_depth = 8;
  1435. row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  1436. row_info->rowbytes = row_width * row_info->channels;
  1437. }
  1438. }
  1439. #endif
  1440. #if defined(PNG_READ_SHIFT_SUPPORTED)
  1441. /* Reverse the effects of png_do_shift. This routine merely shifts the
  1442. * pixels back to their significant bits values. Thus, if you have
  1443. * a row of bit depth 8, but only 5 are significant, this will shift
  1444. * the values back to 0 through 31.
  1445. */
  1446. void /* PRIVATE */
  1447. png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
  1448. {
  1449. png_debug(1, "in png_do_unshift\n");
  1450. if (
  1451. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1452. row != NULL && row_info != NULL && sig_bits != NULL &&
  1453. #endif
  1454. row_info->color_type != PNG_COLOR_TYPE_PALETTE)
  1455. {
  1456. int shift[4];
  1457. int channels = 0;
  1458. int c;
  1459. png_uint_16 value = 0;
  1460. png_uint_32 row_width = row_info->width;
  1461. if (row_info->color_type & PNG_COLOR_MASK_COLOR)
  1462. {
  1463. shift[channels++] = row_info->bit_depth - sig_bits->red;
  1464. shift[channels++] = row_info->bit_depth - sig_bits->green;
  1465. shift[channels++] = row_info->bit_depth - sig_bits->blue;
  1466. }
  1467. else
  1468. {
  1469. shift[channels++] = row_info->bit_depth - sig_bits->gray;
  1470. }
  1471. if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  1472. {
  1473. shift[channels++] = row_info->bit_depth - sig_bits->alpha;
  1474. }
  1475. for (c = 0; c < channels; c++)
  1476. {
  1477. if (shift[c] <= 0)
  1478. shift[c] = 0;
  1479. else
  1480. value = 1;
  1481. }
  1482. if (!value)
  1483. return;
  1484. switch (row_info->bit_depth)
  1485. {
  1486. case 2:
  1487. {
  1488. png_bytep bp;
  1489. png_uint_32 i;
  1490. png_uint_32 istop = row_info->rowbytes;
  1491. for (bp = row, i = 0; i < istop; i++)
  1492. {
  1493. *bp >>= 1;
  1494. *bp++ &= 0x55;
  1495. }
  1496. break;
  1497. }
  1498. case 4:
  1499. {
  1500. png_bytep bp = row;
  1501. png_uint_32 i;
  1502. png_uint_32 istop = row_info->rowbytes;
  1503. png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
  1504. (png_byte)((int)0xf >> shift[0]));
  1505. for (i = 0; i < istop; i++)
  1506. {
  1507. *bp >>= shift[0];
  1508. *bp++ &= mask;
  1509. }
  1510. break;
  1511. }
  1512. case 8:
  1513. {
  1514. png_bytep bp = row;
  1515. png_uint_32 i;
  1516. png_uint_32 istop = row_width * channels;
  1517. for (i = 0; i < istop; i++)
  1518. {
  1519. *bp++ >>= shift[i%channels];
  1520. }
  1521. break;
  1522. }
  1523. case 16:
  1524. {
  1525. png_bytep bp = row;
  1526. png_uint_32 i;
  1527. png_uint_32 istop = channels * row_width;
  1528. for (i = 0; i < istop; i++)
  1529. {
  1530. value = (png_uint_16)((*bp << 8) + *(bp + 1));
  1531. value >>= shift[i%channels];
  1532. *bp++ = (png_byte)(value >> 8);
  1533. *bp++ = (png_byte)(value & 0xff);
  1534. }
  1535. break;
  1536. }
  1537. }
  1538. }
  1539. }
  1540. #endif
  1541. #if defined(PNG_READ_16_TO_8_SUPPORTED)
  1542. /* chop rows of bit depth 16 down to 8 */
  1543. void /* PRIVATE */
  1544. png_do_chop(png_row_infop row_info, png_bytep row)
  1545. {
  1546. png_debug(1, "in png_do_chop\n");
  1547. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1548. if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
  1549. #else
  1550. if (row_info->bit_depth == 16)
  1551. #endif
  1552. {
  1553. png_bytep sp = row;
  1554. png_bytep dp = row;
  1555. png_uint_32 i;
  1556. png_uint_32 istop = row_info->width * row_info->channels;
  1557. for (i = 0; i<istop; i++, sp += 2, dp++)
  1558. {
  1559. #if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
  1560. /* This does a more accurate scaling of the 16-bit color
  1561. * value, rather than a simple low-byte truncation.
  1562. *
  1563. * What the ideal calculation should be:
  1564. * *dp = (((((png_uint_32)(*sp) << 8) |
  1565. * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
  1566. *
  1567. * GRR: no, I think this is what it really should be:
  1568. * *dp = (((((png_uint_32)(*sp) << 8) |
  1569. * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
  1570. *
  1571. * GRR: here's the exact calculation with shifts:
  1572. * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
  1573. * *dp = (temp - (temp >> 8)) >> 8;
  1574. *
  1575. * Approximate calculation with shift/add instead of multiply/divide:
  1576. * *dp = ((((png_uint_32)(*sp) << 8) |
  1577. * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
  1578. *
  1579. * What we actually do to avoid extra shifting and conversion:
  1580. */
  1581. *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
  1582. #else
  1583. /* Simply discard the low order byte */
  1584. *dp = *sp;
  1585. #endif
  1586. }
  1587. row_info->bit_depth = 8;
  1588. row_info->pixel_depth = (png_byte)(8 * row_info->channels);
  1589. row_info->rowbytes = row_info->width * row_info->channels;
  1590. }
  1591. }
  1592. #endif
  1593. #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
  1594. void /* PRIVATE */
  1595. png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
  1596. {
  1597. png_debug(1, "in png_do_read_swap_alpha\n");
  1598. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1599. if (row != NULL && row_info != NULL)
  1600. #endif
  1601. {
  1602. png_uint_32 row_width = row_info->width;
  1603. if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1604. {
  1605. /* This converts from RGBA to ARGB */
  1606. if (row_info->bit_depth == 8)
  1607. {
  1608. png_bytep sp = row + row_info->rowbytes;
  1609. png_bytep dp = sp;
  1610. png_byte save;
  1611. png_uint_32 i;
  1612. for (i = 0; i < row_width; i++)
  1613. {
  1614. save = *(--sp);
  1615. *(--dp) = *(--sp);
  1616. *(--dp) = *(--sp);
  1617. *(--dp) = *(--sp);
  1618. *(--dp) = save;
  1619. }
  1620. }
  1621. /* This converts from RRGGBBAA to AARRGGBB */
  1622. else
  1623. {
  1624. png_bytep sp = row + row_info->rowbytes;
  1625. png_bytep dp = sp;
  1626. png_byte save[2];
  1627. png_uint_32 i;
  1628. for (i = 0; i < row_width; i++)
  1629. {
  1630. save[0] = *(--sp);
  1631. save[1] = *(--sp);
  1632. *(--dp) = *(--sp);
  1633. *(--dp) = *(--sp);
  1634. *(--dp) = *(--sp);
  1635. *(--dp) = *(--sp);
  1636. *(--dp) = *(--sp);
  1637. *(--dp) = *(--sp);
  1638. *(--dp) = save[0];
  1639. *(--dp) = save[1];
  1640. }
  1641. }
  1642. }
  1643. else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1644. {
  1645. /* This converts from GA to AG */
  1646. if (row_info->bit_depth == 8)
  1647. {
  1648. png_bytep sp = row + row_info->rowbytes;
  1649. png_bytep dp = sp;
  1650. png_byte save;
  1651. png_uint_32 i;
  1652. for (i = 0; i < row_width; i++)
  1653. {
  1654. save = *(--sp);
  1655. *(--dp) = *(--sp);
  1656. *(--dp) = save;
  1657. }
  1658. }
  1659. /* This converts from GGAA to AAGG */
  1660. else
  1661. {
  1662. png_bytep sp = row + row_info->rowbytes;
  1663. png_bytep dp = sp;
  1664. png_byte save[2];
  1665. png_uint_32 i;
  1666. for (i = 0; i < row_width; i++)
  1667. {
  1668. save[0] = *(--sp);
  1669. save[1] = *(--sp);
  1670. *(--dp) = *(--sp);
  1671. *(--dp) = *(--sp);
  1672. *(--dp) = save[0];
  1673. *(--dp) = save[1];
  1674. }
  1675. }
  1676. }
  1677. }
  1678. }
  1679. #endif
  1680. #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
  1681. void /* PRIVATE */
  1682. png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
  1683. {
  1684. png_debug(1, "in png_do_read_invert_alpha\n");
  1685. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1686. if (row != NULL && row_info != NULL)
  1687. #endif
  1688. {
  1689. png_uint_32 row_width = row_info->width;
  1690. if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  1691. {
  1692. /* This inverts the alpha channel in RGBA */
  1693. if (row_info->bit_depth == 8)
  1694. {
  1695. png_bytep sp = row + row_info->rowbytes;
  1696. png_bytep dp = sp;
  1697. png_uint_32 i;
  1698. for (i = 0; i < row_width; i++)
  1699. {
  1700. *(--dp) = (png_byte)(255 - *(--sp));
  1701. /* This does nothing:
  1702. *(--dp) = *(--sp);
  1703. *(--dp) = *(--sp);
  1704. *(--dp) = *(--sp);
  1705. We can replace it with:
  1706. */
  1707. sp-=3;
  1708. dp=sp;
  1709. }
  1710. }
  1711. /* This inverts the alpha channel in RRGGBBAA */
  1712. else
  1713. {
  1714. png_bytep sp = row + row_info->rowbytes;
  1715. png_bytep dp = sp;
  1716. png_uint_32 i;
  1717. for (i = 0; i < row_width; i++)
  1718. {
  1719. *(--dp) = (png_byte)(255 - *(--sp));
  1720. *(--dp) = (png_byte)(255 - *(--sp));
  1721. /* This does nothing:
  1722. *(--dp) = *(--sp);
  1723. *(--dp) = *(--sp);
  1724. *(--dp) = *(--sp);
  1725. *(--dp) = *(--sp);
  1726. *(--dp) = *(--sp);
  1727. *(--dp) = *(--sp);
  1728. We can replace it with:
  1729. */
  1730. sp-=6;
  1731. dp=sp;
  1732. }
  1733. }
  1734. }
  1735. else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1736. {
  1737. /* This inverts the alpha channel in GA */
  1738. if (row_info->bit_depth == 8)
  1739. {
  1740. png_bytep sp = row + row_info->rowbytes;
  1741. png_bytep dp = sp;
  1742. png_uint_32 i;
  1743. for (i = 0; i < row_width; i++)
  1744. {
  1745. *(--dp) = (png_byte)(255 - *(--sp));
  1746. *(--dp) = *(--sp);
  1747. }
  1748. }
  1749. /* This inverts the alpha channel in GGAA */
  1750. else
  1751. {
  1752. png_bytep sp = row + row_info->rowbytes;
  1753. png_bytep dp = sp;
  1754. png_uint_32 i;
  1755. for (i = 0; i < row_width; i++)
  1756. {
  1757. *(--dp) = (png_byte)(255 - *(--sp));
  1758. *(--dp) = (png_byte)(255 - *(--sp));
  1759. /*
  1760. *(--dp) = *(--sp);
  1761. *(--dp) = *(--sp);
  1762. */
  1763. sp-=2;
  1764. dp=sp;
  1765. }
  1766. }
  1767. }
  1768. }
  1769. }
  1770. #endif
  1771. #if defined(PNG_READ_FILLER_SUPPORTED)
  1772. /* Add filler channel if we have RGB color */
  1773. void /* PRIVATE */
  1774. png_do_read_filler(png_row_infop row_info, png_bytep row,
  1775. png_uint_32 filler, png_uint_32 flags)
  1776. {
  1777. png_uint_32 i;
  1778. png_uint_32 row_width = row_info->width;
  1779. png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
  1780. png_byte lo_filler = (png_byte)(filler & 0xff);
  1781. png_debug(1, "in png_do_read_filler\n");
  1782. if (
  1783. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1784. row != NULL && row_info != NULL &&
  1785. #endif
  1786. row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1787. {
  1788. if(row_info->bit_depth == 8)
  1789. {
  1790. /* This changes the data from G to GX */
  1791. if (flags & PNG_FLAG_FILLER_AFTER)
  1792. {
  1793. png_bytep sp = row + (png_size_t)row_width;
  1794. png_bytep dp = sp + (png_size_t)row_width;
  1795. for (i = 1; i < row_width; i++)
  1796. {
  1797. *(--dp) = lo_filler;
  1798. *(--dp) = *(--sp);
  1799. }
  1800. *(--dp) = lo_filler;
  1801. row_info->channels = 2;
  1802. row_info->pixel_depth = 16;
  1803. row_info->rowbytes = row_width * 2;
  1804. }
  1805. /* This changes the data from G to XG */
  1806. else
  1807. {
  1808. png_bytep sp = row + (png_size_t)row_width;
  1809. png_bytep dp = sp + (png_size_t)row_width;
  1810. for (i = 0; i < row_width; i++)
  1811. {
  1812. *(--dp) = *(--sp);
  1813. *(--dp) = lo_filler;
  1814. }
  1815. row_info->channels = 2;
  1816. row_info->pixel_depth = 16;
  1817. row_info->rowbytes = row_width * 2;
  1818. }
  1819. }
  1820. else if(row_info->bit_depth == 16)
  1821. {
  1822. /* This changes the data from GG to GGXX */
  1823. if (flags & PNG_FLAG_FILLER_AFTER)
  1824. {
  1825. png_bytep sp = row + (png_size_t)row_width * 2;
  1826. png_bytep dp = sp + (png_size_t)row_width * 2;
  1827. for (i = 1; i < row_width; i++)
  1828. {
  1829. *(--dp) = hi_filler;
  1830. *(--dp) = lo_filler;
  1831. *(--dp) = *(--sp);
  1832. *(--dp) = *(--sp);
  1833. }
  1834. *(--dp) = hi_filler;
  1835. *(--dp) = lo_filler;
  1836. row_info->channels = 2;
  1837. row_info->pixel_depth = 32;
  1838. row_info->rowbytes = row_width * 4;
  1839. }
  1840. /* This changes the data from GG to XXGG */
  1841. else
  1842. {
  1843. png_bytep sp = row + (png_size_t)row_width * 2;
  1844. png_bytep dp = sp + (png_size_t)row_width * 2;
  1845. for (i = 0; i < row_width; i++)
  1846. {
  1847. *(--dp) = *(--sp);
  1848. *(--dp) = *(--sp);
  1849. *(--dp) = hi_filler;
  1850. *(--dp) = lo_filler;
  1851. }
  1852. row_info->channels = 2;
  1853. row_info->pixel_depth = 32;
  1854. row_info->rowbytes = row_width * 4;
  1855. }
  1856. }
  1857. } /* COLOR_TYPE == GRAY */
  1858. else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
  1859. {
  1860. if(row_info->bit_depth == 8)
  1861. {
  1862. /* This changes the data from RGB to RGBX */
  1863. if (flags & PNG_FLAG_FILLER_AFTER)
  1864. {
  1865. png_bytep sp = row + (png_size_t)row_width * 3;
  1866. png_bytep dp = sp + (png_size_t)row_width;
  1867. for (i = 1; i < row_width; i++)
  1868. {
  1869. *(--dp) = lo_filler;
  1870. *(--dp) = *(--sp);
  1871. *(--dp) = *(--sp);
  1872. *(--dp) = *(--sp);
  1873. }
  1874. *(--dp) = lo_filler;
  1875. row_info->channels = 4;
  1876. row_info->pixel_depth = 32;
  1877. row_info->rowbytes = row_width * 4;
  1878. }
  1879. /* This changes the data from RGB to XRGB */
  1880. else
  1881. {
  1882. png_bytep sp = row + (png_size_t)row_width * 3;
  1883. png_bytep dp = sp + (png_size_t)row_width;
  1884. for (i = 0; i < row_width; i++)
  1885. {
  1886. *(--dp) = *(--sp);
  1887. *(--dp) = *(--sp);
  1888. *(--dp) = *(--sp);
  1889. *(--dp) = lo_filler;
  1890. }
  1891. row_info->channels = 4;
  1892. row_info->pixel_depth = 32;
  1893. row_info->rowbytes = row_width * 4;
  1894. }
  1895. }
  1896. else if(row_info->bit_depth == 16)
  1897. {
  1898. /* This changes the data from RRGGBB to RRGGBBXX */
  1899. if (flags & PNG_FLAG_FILLER_AFTER)
  1900. {
  1901. png_bytep sp = row + (png_size_t)row_width * 6;
  1902. png_bytep dp = sp + (png_size_t)row_width * 2;
  1903. for (i = 1; i < row_width; i++)
  1904. {
  1905. *(--dp) = hi_filler;
  1906. *(--dp) = lo_filler;
  1907. *(--dp) = *(--sp);
  1908. *(--dp) = *(--sp);
  1909. *(--dp) = *(--sp);
  1910. *(--dp) = *(--sp);
  1911. *(--dp) = *(--sp);
  1912. *(--dp) = *(--sp);
  1913. }
  1914. *(--dp) = hi_filler;
  1915. *(--dp) = lo_filler;
  1916. row_info->channels = 4;
  1917. row_info->pixel_depth = 64;
  1918. row_info->rowbytes = row_width * 8;
  1919. }
  1920. /* This changes the data from RRGGBB to XXRRGGBB */
  1921. else
  1922. {
  1923. png_bytep sp = row + (png_size_t)row_width * 6;
  1924. png_bytep dp = sp + (png_size_t)row_width * 2;
  1925. for (i = 0; i < row_width; i++)
  1926. {
  1927. *(--dp) = *(--sp);
  1928. *(--dp) = *(--sp);
  1929. *(--dp) = *(--sp);
  1930. *(--dp) = *(--sp);
  1931. *(--dp) = *(--sp);
  1932. *(--dp) = *(--sp);
  1933. *(--dp) = hi_filler;
  1934. *(--dp) = lo_filler;
  1935. }
  1936. row_info->channels = 4;
  1937. row_info->pixel_depth = 64;
  1938. row_info->rowbytes = row_width * 8;
  1939. }
  1940. }
  1941. } /* COLOR_TYPE == RGB */
  1942. }
  1943. #endif
  1944. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  1945. /* expand grayscale files to RGB, with or without alpha */
  1946. void /* PRIVATE */
  1947. png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
  1948. {
  1949. png_uint_32 i;
  1950. png_uint_32 row_width = row_info->width;
  1951. png_debug(1, "in png_do_gray_to_rgb\n");
  1952. if (row_info->bit_depth >= 8 &&
  1953. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  1954. row != NULL && row_info != NULL &&
  1955. #endif
  1956. !(row_info->color_type & PNG_COLOR_MASK_COLOR))
  1957. {
  1958. if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  1959. {
  1960. if (row_info->bit_depth == 8)
  1961. {
  1962. png_bytep sp = row + (png_size_t)row_width - 1;
  1963. png_bytep dp = sp + (png_size_t)row_width * 2;
  1964. for (i = 0; i < row_width; i++)
  1965. {
  1966. *(dp--) = *sp;
  1967. *(dp--) = *sp;
  1968. *(dp--) = *(sp--);
  1969. }
  1970. }
  1971. else
  1972. {
  1973. png_bytep sp = row + (png_size_t)row_width * 2 - 1;
  1974. png_bytep dp = sp + (png_size_t)row_width * 4;
  1975. for (i = 0; i < row_width; i++)
  1976. {
  1977. *(dp--) = *sp;
  1978. *(dp--) = *(sp - 1);
  1979. *(dp--) = *sp;
  1980. *(dp--) = *(sp - 1);
  1981. *(dp--) = *(sp--);
  1982. *(dp--) = *(sp--);
  1983. }
  1984. }
  1985. }
  1986. else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1987. {
  1988. if (row_info->bit_depth == 8)
  1989. {
  1990. png_bytep sp = row + (png_size_t)row_width * 2 - 1;
  1991. png_bytep dp = sp + (png_size_t)row_width * 2;
  1992. for (i = 0; i < row_width; i++)
  1993. {
  1994. *(dp--) = *(sp--);
  1995. *(dp--) = *sp;
  1996. *(dp--) = *sp;
  1997. *(dp--) = *(sp--);
  1998. }
  1999. }
  2000. else
  2001. {
  2002. png_bytep sp = row + (png_size_t)row_width * 4 - 1;
  2003. png_bytep dp = sp + (png_size_t)row_width * 4;
  2004. for (i = 0; i < row_width; i++)
  2005. {
  2006. *(dp--) = *(sp--);
  2007. *(dp--) = *(sp--);
  2008. *(dp--) = *sp;
  2009. *(dp--) = *(sp - 1);
  2010. *(dp--) = *sp;
  2011. *(dp--) = *(sp - 1);
  2012. *(dp--) = *(sp--);
  2013. *(dp--) = *(sp--);
  2014. }
  2015. }
  2016. }
  2017. row_info->channels += (png_byte)2;
  2018. row_info->color_type |= PNG_COLOR_MASK_COLOR;
  2019. row_info->pixel_depth = (png_byte)(row_info->channels *
  2020. row_info->bit_depth);
  2021. row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  2022. }
  2023. }
  2024. #endif
  2025. #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  2026. /* reduce RGB files to grayscale, with or without alpha
  2027. * using the equation given in Poynton's ColorFAQ at
  2028. * <http://www.inforamp.net/~poynton/>
  2029. * Copyright (c) 1998-01-04 Charles Poynton poynton at inforamp.net
  2030. *
  2031. * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
  2032. *
  2033. * We approximate this with
  2034. *
  2035. * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
  2036. *
  2037. * which can be expressed with integers as
  2038. *
  2039. * Y = (6969 * R + 23434 * G + 2365 * B)/32768
  2040. *
  2041. * The calculation is to be done in a linear colorspace.
  2042. *
  2043. * Other integer coefficents can be used via png_set_rgb_to_gray().
  2044. */
  2045. int /* PRIVATE */
  2046. png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
  2047. {
  2048. png_uint_32 i;
  2049. png_uint_32 row_width = row_info->width;
  2050. int rgb_error = 0;
  2051. png_debug(1, "in png_do_rgb_to_gray\n");
  2052. if (
  2053. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  2054. row != NULL && row_info != NULL &&
  2055. #endif
  2056. (row_info->color_type & PNG_COLOR_MASK_COLOR))
  2057. {
  2058. png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
  2059. png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
  2060. png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
  2061. if (row_info->color_type == PNG_COLOR_TYPE_RGB)
  2062. {
  2063. if (row_info->bit_depth == 8)
  2064. {
  2065. #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  2066. if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
  2067. {
  2068. png_bytep sp = row;
  2069. png_bytep dp = row;
  2070. for (i = 0; i < row_width; i++)
  2071. {
  2072. png_byte red = png_ptr->gamma_to_1[*(sp++)];
  2073. png_byte green = png_ptr->gamma_to_1[*(sp++)];
  2074. png_byte blue = png_ptr->gamma_to_1[*(sp++)];
  2075. if(red != green || red != blue)
  2076. {
  2077. rgb_error |= 1;
  2078. *(dp++) = png_ptr->gamma_from_1[
  2079. (rc*red+gc*green+bc*blue)>>15];
  2080. }
  2081. else
  2082. *(dp++) = *(sp-1);
  2083. }
  2084. }
  2085. else
  2086. #endif
  2087. {
  2088. png_bytep sp = row;
  2089. png_bytep dp = row;
  2090. for (i = 0; i < row_width; i++)
  2091. {
  2092. png_byte red = *(sp++);
  2093. png_byte green = *(sp++);
  2094. png_byte blue = *(sp++);
  2095. if(red != green || red != blue)
  2096. {
  2097. rgb_error |= 1;
  2098. *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
  2099. }
  2100. else
  2101. *(dp++) = *(sp-1);
  2102. }
  2103. }
  2104. }
  2105. else /* RGB bit_depth == 16 */
  2106. {
  2107. #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  2108. if (png_ptr->gamma_16_to_1 != NULL &&
  2109. png_ptr->gamma_16_from_1 != NULL)
  2110. {
  2111. png_bytep sp = row;
  2112. png_bytep dp = row;
  2113. for (i = 0; i < row_width; i++)
  2114. {
  2115. png_uint_16 red, green, blue, w;
  2116. red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2117. green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2118. blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2119. if(red == green && red == blue)
  2120. w = red;
  2121. else
  2122. {
  2123. png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
  2124. png_ptr->gamma_shift][red>>8];
  2125. png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
  2126. png_ptr->gamma_shift][green>>8];
  2127. png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
  2128. png_ptr->gamma_shift][blue>>8];
  2129. png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
  2130. + bc*blue_1)>>15);
  2131. w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
  2132. png_ptr->gamma_shift][gray16 >> 8];
  2133. rgb_error |= 1;
  2134. }
  2135. *(dp++) = (png_byte)((w>>8) & 0xff);
  2136. *(dp++) = (png_byte)(w & 0xff);
  2137. }
  2138. }
  2139. else
  2140. #endif
  2141. {
  2142. png_bytep sp = row;
  2143. png_bytep dp = row;
  2144. for (i = 0; i < row_width; i++)
  2145. {
  2146. png_uint_16 red, green, blue, gray16;
  2147. red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2148. green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2149. blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2150. if(red != green || red != blue)
  2151. rgb_error |= 1;
  2152. gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
  2153. *(dp++) = (png_byte)((gray16>>8) & 0xff);
  2154. *(dp++) = (png_byte)(gray16 & 0xff);
  2155. }
  2156. }
  2157. }
  2158. }
  2159. if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  2160. {
  2161. if (row_info->bit_depth == 8)
  2162. {
  2163. #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  2164. if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
  2165. {
  2166. png_bytep sp = row;
  2167. png_bytep dp = row;
  2168. for (i = 0; i < row_width; i++)
  2169. {
  2170. png_byte red = png_ptr->gamma_to_1[*(sp++)];
  2171. png_byte green = png_ptr->gamma_to_1[*(sp++)];
  2172. png_byte blue = png_ptr->gamma_to_1[*(sp++)];
  2173. if(red != green || red != blue)
  2174. rgb_error |= 1;
  2175. *(dp++) = png_ptr->gamma_from_1
  2176. [(rc*red + gc*green + bc*blue)>>15];
  2177. *(dp++) = *(sp++); /* alpha */
  2178. }
  2179. }
  2180. else
  2181. #endif
  2182. {
  2183. png_bytep sp = row;
  2184. png_bytep dp = row;
  2185. for (i = 0; i < row_width; i++)
  2186. {
  2187. png_byte red = *(sp++);
  2188. png_byte green = *(sp++);
  2189. png_byte blue = *(sp++);
  2190. if(red != green || red != blue)
  2191. rgb_error |= 1;
  2192. *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
  2193. *(dp++) = *(sp++); /* alpha */
  2194. }
  2195. }
  2196. }
  2197. else /* RGBA bit_depth == 16 */
  2198. {
  2199. #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
  2200. if (png_ptr->gamma_16_to_1 != NULL &&
  2201. png_ptr->gamma_16_from_1 != NULL)
  2202. {
  2203. png_bytep sp = row;
  2204. png_bytep dp = row;
  2205. for (i = 0; i < row_width; i++)
  2206. {
  2207. png_uint_16 red, green, blue, w;
  2208. red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2209. green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2210. blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
  2211. if(red == green && red == blue)
  2212. w = red;
  2213. else
  2214. {
  2215. png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
  2216. png_ptr->gamma_shift][red>>8];
  2217. png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
  2218. png_ptr->gamma_shift][green>>8];
  2219. png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
  2220. png_ptr->gamma_shift][blue>>8];
  2221. png_uint_16 gray16 = (png_uint_16)((rc * red_1
  2222. + gc * green_1 + bc * blue_1)>>15);
  2223. w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
  2224. png_ptr->gamma_shift][gray16 >> 8];
  2225. rgb_error |= 1;
  2226. }
  2227. *(dp++) = (png_byte)((w>>8) & 0xff);
  2228. *(dp++) = (png_byte)(w & 0xff);
  2229. *(dp++) = *(sp++); /* alpha */
  2230. *(dp++) = *(sp++);
  2231. }
  2232. }
  2233. else
  2234. #endif
  2235. {
  2236. png_bytep sp = row;
  2237. png_bytep dp = row;
  2238. for (i = 0; i < row_width; i++)
  2239. {
  2240. png_uint_16 red, green, blue, gray16;
  2241. red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
  2242. green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
  2243. blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
  2244. if(red != green || red != blue)
  2245. rgb_error |= 1;
  2246. gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
  2247. *(dp++) = (png_byte)((gray16>>8) & 0xff);
  2248. *(dp++) = (png_byte)(gray16 & 0xff);
  2249. *(dp++) = *(sp++); /* alpha */
  2250. *(dp++) = *(sp++);
  2251. }
  2252. }
  2253. }
  2254. }
  2255. row_info->channels -= (png_byte)2;
  2256. row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
  2257. row_info->pixel_depth = (png_byte)(row_info->channels *
  2258. row_info->bit_depth);
  2259. row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  2260. }
  2261. return rgb_error;
  2262. }
  2263. #endif
  2264. /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
  2265. * large of png_color. This lets grayscale images be treated as
  2266. * paletted. Most useful for gamma correction and simplification
  2267. * of code.
  2268. */
  2269. void PNGAPI
  2270. png_build_grayscale_palette(int bit_depth, png_colorp palette)
  2271. {
  2272. int num_palette;
  2273. int color_inc;
  2274. int i;
  2275. int v;
  2276. png_debug(1, "in png_do_build_grayscale_palette\n");
  2277. if (palette == NULL)
  2278. return;
  2279. switch (bit_depth)
  2280. {
  2281. case 1:
  2282. num_palette = 2;
  2283. color_inc = 0xff;
  2284. break;
  2285. case 2:
  2286. num_palette = 4;
  2287. color_inc = 0x55;
  2288. break;
  2289. case 4:
  2290. num_palette = 16;
  2291. color_inc = 0x11;
  2292. break;
  2293. case 8:
  2294. num_palette = 256;
  2295. color_inc = 1;
  2296. break;
  2297. default:
  2298. num_palette = 0;
  2299. color_inc = 0;
  2300. break;
  2301. }
  2302. for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
  2303. {
  2304. palette[i].red = (png_byte)v;
  2305. palette[i].green = (png_byte)v;
  2306. palette[i].blue = (png_byte)v;
  2307. }
  2308. }
  2309. /* This function is currently unused. Do we really need it? */
  2310. #if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
  2311. void /* PRIVATE */
  2312. png_correct_palette(png_structp png_ptr, png_colorp palette,
  2313. int num_palette)
  2314. {
  2315. png_debug(1, "in png_correct_palette\n");
  2316. #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
  2317. defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
  2318. if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
  2319. {
  2320. png_color back, back_1;
  2321. if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
  2322. {
  2323. back.red = png_ptr->gamma_table[png_ptr->background.red];
  2324. back.green = png_ptr->gamma_table[png_ptr->background.green];
  2325. back.blue = png_ptr->gamma_table[png_ptr->background.blue];
  2326. back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
  2327. back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
  2328. back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
  2329. }
  2330. else
  2331. {
  2332. double g;
  2333. g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
  2334. if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
  2335. fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
  2336. {
  2337. back.red = png_ptr->background.red;
  2338. back.green = png_ptr->background.green;
  2339. back.blue = png_ptr->background.blue;
  2340. }
  2341. else
  2342. {
  2343. back.red =
  2344. (png_byte)(pow((double)png_ptr->background.red/255, g) *
  2345. 255.0 + 0.5);
  2346. back.green =
  2347. (png_byte)(pow((double)png_ptr->background.green/255, g) *
  2348. 255.0 + 0.5);
  2349. back.blue =
  2350. (png_byte)(pow((double)png_ptr->background.blue/255, g) *
  2351. 255.0 + 0.5);
  2352. }
  2353. g = 1.0 / png_ptr->background_gamma;
  2354. back_1.red =
  2355. (png_byte)(pow((double)png_ptr->background.red/255, g) *
  2356. 255.0 + 0.5);
  2357. back_1.green =
  2358. (png_byte)(pow((double)png_ptr->background.green/255, g) *
  2359. 255.0 + 0.5);
  2360. back_1.blue =
  2361. (png_byte)(pow((double)png_ptr->background.blue/255, g) *
  2362. 255.0 + 0.5);
  2363. }
  2364. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  2365. {
  2366. png_uint_32 i;
  2367. for (i = 0; i < (png_uint_32)num_palette; i++)
  2368. {
  2369. if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
  2370. {
  2371. palette[i] = back;
  2372. }
  2373. else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
  2374. {
  2375. png_byte v, w;
  2376. v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
  2377. png_composite(w, v, png_ptr->trans[i], back_1.red);
  2378. palette[i].red = png_ptr->gamma_from_1[w];
  2379. v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
  2380. png_composite(w, v, png_ptr->trans[i], back_1.green);
  2381. palette[i].green = png_ptr->gamma_from_1[w];
  2382. v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
  2383. png_composite(w, v, png_ptr->trans[i], back_1.blue);
  2384. palette[i].blue = png_ptr->gamma_from_1[w];
  2385. }
  2386. else
  2387. {
  2388. palette[i].red = png_ptr->gamma_table[palette[i].red];
  2389. palette[i].green = png_ptr->gamma_table[palette[i].green];
  2390. palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  2391. }
  2392. }
  2393. }
  2394. else
  2395. {
  2396. int i;
  2397. for (i = 0; i < num_palette; i++)
  2398. {
  2399. if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
  2400. {
  2401. palette[i] = back;
  2402. }
  2403. else
  2404. {
  2405. palette[i].red = png_ptr->gamma_table[palette[i].red];
  2406. palette[i].green = png_ptr->gamma_table[palette[i].green];
  2407. palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  2408. }
  2409. }
  2410. }
  2411. }
  2412. else
  2413. #endif
  2414. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2415. if (png_ptr->transformations & PNG_GAMMA)
  2416. {
  2417. int i;
  2418. for (i = 0; i < num_palette; i++)
  2419. {
  2420. palette[i].red = png_ptr->gamma_table[palette[i].red];
  2421. palette[i].green = png_ptr->gamma_table[palette[i].green];
  2422. palette[i].blue = png_ptr->gamma_table[palette[i].blue];
  2423. }
  2424. }
  2425. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  2426. else
  2427. #endif
  2428. #endif
  2429. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  2430. if (png_ptr->transformations & PNG_BACKGROUND)
  2431. {
  2432. if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  2433. {
  2434. png_color back;
  2435. back.red = (png_byte)png_ptr->background.red;
  2436. back.green = (png_byte)png_ptr->background.green;
  2437. back.blue = (png_byte)png_ptr->background.blue;
  2438. for (i = 0; i < (int)png_ptr->num_trans; i++)
  2439. {
  2440. if (png_ptr->trans[i] == 0)
  2441. {
  2442. palette[i].red = back.red;
  2443. palette[i].green = back.green;
  2444. palette[i].blue = back.blue;
  2445. }
  2446. else if (png_ptr->trans[i] != 0xff)
  2447. {
  2448. png_composite(palette[i].red, png_ptr->palette[i].red,
  2449. png_ptr->trans[i], back.red);
  2450. png_composite(palette[i].green, png_ptr->palette[i].green,
  2451. png_ptr->trans[i], back.green);
  2452. png_composite(palette[i].blue, png_ptr->palette[i].blue,
  2453. png_ptr->trans[i], back.blue);
  2454. }
  2455. }
  2456. }
  2457. else /* assume grayscale palette (what else could it be?) */
  2458. {
  2459. int i;
  2460. for (i = 0; i < num_palette; i++)
  2461. {
  2462. if (i == (png_byte)png_ptr->trans_values.gray)
  2463. {
  2464. palette[i].red = (png_byte)png_ptr->background.red;
  2465. palette[i].green = (png_byte)png_ptr->background.green;
  2466. palette[i].blue = (png_byte)png_ptr->background.blue;
  2467. }
  2468. }
  2469. }
  2470. }
  2471. #endif
  2472. }
  2473. #endif
  2474. #if defined(PNG_READ_BACKGROUND_SUPPORTED)
  2475. /* Replace any alpha or transparency with the supplied background color.
  2476. * "background" is already in the screen gamma, while "background_1" is
  2477. * at a gamma of 1.0. Paletted files have already been taken care of.
  2478. */
  2479. void /* PRIVATE */
  2480. png_do_background(png_row_infop row_info, png_bytep row,
  2481. png_color_16p trans_values, png_color_16p background
  2482. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2483. , png_color_16p background_1,
  2484. png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
  2485. png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
  2486. png_uint_16pp gamma_16_to_1, int gamma_shift
  2487. #endif
  2488. )
  2489. {
  2490. png_bytep sp, dp;
  2491. png_uint_32 i;
  2492. png_uint_32 row_width=row_info->width;
  2493. int shift;
  2494. png_debug(1, "in png_do_background\n");
  2495. if (background != NULL &&
  2496. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  2497. row != NULL && row_info != NULL &&
  2498. #endif
  2499. (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
  2500. (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
  2501. {
  2502. switch (row_info->color_type)
  2503. {
  2504. case PNG_COLOR_TYPE_GRAY:
  2505. {
  2506. switch (row_info->bit_depth)
  2507. {
  2508. case 1:
  2509. {
  2510. sp = row;
  2511. shift = 7;
  2512. for (i = 0; i < row_width; i++)
  2513. {
  2514. if ((png_uint_16)((*sp >> shift) & 0x01)
  2515. == trans_values->gray)
  2516. {
  2517. *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  2518. *sp |= (png_byte)(background->gray << shift);
  2519. }
  2520. if (!shift)
  2521. {
  2522. shift = 7;
  2523. sp++;
  2524. }
  2525. else
  2526. shift--;
  2527. }
  2528. break;
  2529. }
  2530. case 2:
  2531. {
  2532. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2533. if (gamma_table != NULL)
  2534. {
  2535. sp = row;
  2536. shift = 6;
  2537. for (i = 0; i < row_width; i++)
  2538. {
  2539. if ((png_uint_16)((*sp >> shift) & 0x03)
  2540. == trans_values->gray)
  2541. {
  2542. *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  2543. *sp |= (png_byte)(background->gray << shift);
  2544. }
  2545. else
  2546. {
  2547. png_byte p = (png_byte)((*sp >> shift) & 0x03);
  2548. png_byte g = (png_byte)((gamma_table [p | (p << 2) |
  2549. (p << 4) | (p << 6)] >> 6) & 0x03);
  2550. *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  2551. *sp |= (png_byte)(g << shift);
  2552. }
  2553. if (!shift)
  2554. {
  2555. shift = 6;
  2556. sp++;
  2557. }
  2558. else
  2559. shift -= 2;
  2560. }
  2561. }
  2562. else
  2563. #endif
  2564. {
  2565. sp = row;
  2566. shift = 6;
  2567. for (i = 0; i < row_width; i++)
  2568. {
  2569. if ((png_uint_16)((*sp >> shift) & 0x03)
  2570. == trans_values->gray)
  2571. {
  2572. *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  2573. *sp |= (png_byte)(background->gray << shift);
  2574. }
  2575. if (!shift)
  2576. {
  2577. shift = 6;
  2578. sp++;
  2579. }
  2580. else
  2581. shift -= 2;
  2582. }
  2583. }
  2584. break;
  2585. }
  2586. case 4:
  2587. {
  2588. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2589. if (gamma_table != NULL)
  2590. {
  2591. sp = row;
  2592. shift = 4;
  2593. for (i = 0; i < row_width; i++)
  2594. {
  2595. if ((png_uint_16)((*sp >> shift) & 0x0f)
  2596. == trans_values->gray)
  2597. {
  2598. *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  2599. *sp |= (png_byte)(background->gray << shift);
  2600. }
  2601. else
  2602. {
  2603. png_byte p = (png_byte)((*sp >> shift) & 0x0f);
  2604. png_byte g = (png_byte)((gamma_table[p |
  2605. (p << 4)] >> 4) & 0x0f);
  2606. *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  2607. *sp |= (png_byte)(g << shift);
  2608. }
  2609. if (!shift)
  2610. {
  2611. shift = 4;
  2612. sp++;
  2613. }
  2614. else
  2615. shift -= 4;
  2616. }
  2617. }
  2618. else
  2619. #endif
  2620. {
  2621. sp = row;
  2622. shift = 4;
  2623. for (i = 0; i < row_width; i++)
  2624. {
  2625. if ((png_uint_16)((*sp >> shift) & 0x0f)
  2626. == trans_values->gray)
  2627. {
  2628. *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  2629. *sp |= (png_byte)(background->gray << shift);
  2630. }
  2631. if (!shift)
  2632. {
  2633. shift = 4;
  2634. sp++;
  2635. }
  2636. else
  2637. shift -= 4;
  2638. }
  2639. }
  2640. break;
  2641. }
  2642. case 8:
  2643. {
  2644. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2645. if (gamma_table != NULL)
  2646. {
  2647. sp = row;
  2648. for (i = 0; i < row_width; i++, sp++)
  2649. {
  2650. if (*sp == trans_values->gray)
  2651. {
  2652. *sp = (png_byte)background->gray;
  2653. }
  2654. else
  2655. {
  2656. *sp = gamma_table[*sp];
  2657. }
  2658. }
  2659. }
  2660. else
  2661. #endif
  2662. {
  2663. sp = row;
  2664. for (i = 0; i < row_width; i++, sp++)
  2665. {
  2666. if (*sp == trans_values->gray)
  2667. {
  2668. *sp = (png_byte)background->gray;
  2669. }
  2670. }
  2671. }
  2672. break;
  2673. }
  2674. case 16:
  2675. {
  2676. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2677. if (gamma_16 != NULL)
  2678. {
  2679. sp = row;
  2680. for (i = 0; i < row_width; i++, sp += 2)
  2681. {
  2682. png_uint_16 v;
  2683. v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  2684. if (v == trans_values->gray)
  2685. {
  2686. /* background is already in screen gamma */
  2687. *sp = (png_byte)((background->gray >> 8) & 0xff);
  2688. *(sp + 1) = (png_byte)(background->gray & 0xff);
  2689. }
  2690. else
  2691. {
  2692. v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  2693. *sp = (png_byte)((v >> 8) & 0xff);
  2694. *(sp + 1) = (png_byte)(v & 0xff);
  2695. }
  2696. }
  2697. }
  2698. else
  2699. #endif
  2700. {
  2701. sp = row;
  2702. for (i = 0; i < row_width; i++, sp += 2)
  2703. {
  2704. png_uint_16 v;
  2705. v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  2706. if (v == trans_values->gray)
  2707. {
  2708. *sp = (png_byte)((background->gray >> 8) & 0xff);
  2709. *(sp + 1) = (png_byte)(background->gray & 0xff);
  2710. }
  2711. }
  2712. }
  2713. break;
  2714. }
  2715. }
  2716. break;
  2717. }
  2718. case PNG_COLOR_TYPE_RGB:
  2719. {
  2720. if (row_info->bit_depth == 8)
  2721. {
  2722. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2723. if (gamma_table != NULL)
  2724. {
  2725. sp = row;
  2726. for (i = 0; i < row_width; i++, sp += 3)
  2727. {
  2728. if (*sp == trans_values->red &&
  2729. *(sp + 1) == trans_values->green &&
  2730. *(sp + 2) == trans_values->blue)
  2731. {
  2732. *sp = (png_byte)background->red;
  2733. *(sp + 1) = (png_byte)background->green;
  2734. *(sp + 2) = (png_byte)background->blue;
  2735. }
  2736. else
  2737. {
  2738. *sp = gamma_table[*sp];
  2739. *(sp + 1) = gamma_table[*(sp + 1)];
  2740. *(sp + 2) = gamma_table[*(sp + 2)];
  2741. }
  2742. }
  2743. }
  2744. else
  2745. #endif
  2746. {
  2747. sp = row;
  2748. for (i = 0; i < row_width; i++, sp += 3)
  2749. {
  2750. if (*sp == trans_values->red &&
  2751. *(sp + 1) == trans_values->green &&
  2752. *(sp + 2) == trans_values->blue)
  2753. {
  2754. *sp = (png_byte)background->red;
  2755. *(sp + 1) = (png_byte)background->green;
  2756. *(sp + 2) = (png_byte)background->blue;
  2757. }
  2758. }
  2759. }
  2760. }
  2761. else /* if (row_info->bit_depth == 16) */
  2762. {
  2763. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2764. if (gamma_16 != NULL)
  2765. {
  2766. sp = row;
  2767. for (i = 0; i < row_width; i++, sp += 6)
  2768. {
  2769. png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  2770. png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
  2771. png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
  2772. if (r == trans_values->red && g == trans_values->green &&
  2773. b == trans_values->blue)
  2774. {
  2775. /* background is already in screen gamma */
  2776. *sp = (png_byte)((background->red >> 8) & 0xff);
  2777. *(sp + 1) = (png_byte)(background->red & 0xff);
  2778. *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  2779. *(sp + 3) = (png_byte)(background->green & 0xff);
  2780. *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  2781. *(sp + 5) = (png_byte)(background->blue & 0xff);
  2782. }
  2783. else
  2784. {
  2785. png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  2786. *sp = (png_byte)((v >> 8) & 0xff);
  2787. *(sp + 1) = (png_byte)(v & 0xff);
  2788. v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
  2789. *(sp + 2) = (png_byte)((v >> 8) & 0xff);
  2790. *(sp + 3) = (png_byte)(v & 0xff);
  2791. v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
  2792. *(sp + 4) = (png_byte)((v >> 8) & 0xff);
  2793. *(sp + 5) = (png_byte)(v & 0xff);
  2794. }
  2795. }
  2796. }
  2797. else
  2798. #endif
  2799. {
  2800. sp = row;
  2801. for (i = 0; i < row_width; i++, sp += 6)
  2802. {
  2803. png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
  2804. png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
  2805. png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
  2806. if (r == trans_values->red && g == trans_values->green &&
  2807. b == trans_values->blue)
  2808. {
  2809. *sp = (png_byte)((background->red >> 8) & 0xff);
  2810. *(sp + 1) = (png_byte)(background->red & 0xff);
  2811. *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
  2812. *(sp + 3) = (png_byte)(background->green & 0xff);
  2813. *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  2814. *(sp + 5) = (png_byte)(background->blue & 0xff);
  2815. }
  2816. }
  2817. }
  2818. }
  2819. break;
  2820. }
  2821. case PNG_COLOR_TYPE_GRAY_ALPHA:
  2822. {
  2823. if (row_info->bit_depth == 8)
  2824. {
  2825. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2826. if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
  2827. gamma_table != NULL)
  2828. {
  2829. sp = row;
  2830. dp = row;
  2831. for (i = 0; i < row_width; i++, sp += 2, dp++)
  2832. {
  2833. png_uint_16 a = *(sp + 1);
  2834. if (a == 0xff)
  2835. {
  2836. *dp = gamma_table[*sp];
  2837. }
  2838. else if (a == 0)
  2839. {
  2840. /* background is already in screen gamma */
  2841. *dp = (png_byte)background->gray;
  2842. }
  2843. else
  2844. {
  2845. png_byte v, w;
  2846. v = gamma_to_1[*sp];
  2847. png_composite(w, v, a, background_1->gray);
  2848. *dp = gamma_from_1[w];
  2849. }
  2850. }
  2851. }
  2852. else
  2853. #endif
  2854. {
  2855. sp = row;
  2856. dp = row;
  2857. for (i = 0; i < row_width; i++, sp += 2, dp++)
  2858. {
  2859. png_byte a = *(sp + 1);
  2860. if (a == 0xff)
  2861. {
  2862. *dp = *sp;
  2863. }
  2864. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2865. else if (a == 0)
  2866. {
  2867. *dp = (png_byte)background->gray;
  2868. }
  2869. else
  2870. {
  2871. png_composite(*dp, *sp, a, background_1->gray);
  2872. }
  2873. #else
  2874. *dp = (png_byte)background->gray;
  2875. #endif
  2876. }
  2877. }
  2878. }
  2879. else /* if (png_ptr->bit_depth == 16) */
  2880. {
  2881. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2882. if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
  2883. gamma_16_to_1 != NULL)
  2884. {
  2885. sp = row;
  2886. dp = row;
  2887. for (i = 0; i < row_width; i++, sp += 4, dp += 2)
  2888. {
  2889. png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
  2890. if (a == (png_uint_16)0xffff)
  2891. {
  2892. png_uint_16 v;
  2893. v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  2894. *dp = (png_byte)((v >> 8) & 0xff);
  2895. *(dp + 1) = (png_byte)(v & 0xff);
  2896. }
  2897. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2898. else if (a == 0)
  2899. #else
  2900. else
  2901. #endif
  2902. {
  2903. /* background is already in screen gamma */
  2904. *dp = (png_byte)((background->gray >> 8) & 0xff);
  2905. *(dp + 1) = (png_byte)(background->gray & 0xff);
  2906. }
  2907. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2908. else
  2909. {
  2910. png_uint_16 g, v, w;
  2911. g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
  2912. png_composite_16(v, g, a, background_1->gray);
  2913. w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
  2914. *dp = (png_byte)((w >> 8) & 0xff);
  2915. *(dp + 1) = (png_byte)(w & 0xff);
  2916. }
  2917. #endif
  2918. }
  2919. }
  2920. else
  2921. #endif
  2922. {
  2923. sp = row;
  2924. dp = row;
  2925. for (i = 0; i < row_width; i++, sp += 4, dp += 2)
  2926. {
  2927. png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
  2928. if (a == (png_uint_16)0xffff)
  2929. {
  2930. png_memcpy(dp, sp, 2);
  2931. }
  2932. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2933. else if (a == 0)
  2934. #else
  2935. else
  2936. #endif
  2937. {
  2938. *dp = (png_byte)((background->gray >> 8) & 0xff);
  2939. *(dp + 1) = (png_byte)(background->gray & 0xff);
  2940. }
  2941. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2942. else
  2943. {
  2944. png_uint_16 g, v;
  2945. g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  2946. png_composite_16(v, g, a, background_1->gray);
  2947. *dp = (png_byte)((v >> 8) & 0xff);
  2948. *(dp + 1) = (png_byte)(v & 0xff);
  2949. }
  2950. #endif
  2951. }
  2952. }
  2953. }
  2954. break;
  2955. }
  2956. case PNG_COLOR_TYPE_RGB_ALPHA:
  2957. {
  2958. if (row_info->bit_depth == 8)
  2959. {
  2960. #if defined(PNG_READ_GAMMA_SUPPORTED)
  2961. if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
  2962. gamma_table != NULL)
  2963. {
  2964. sp = row;
  2965. dp = row;
  2966. for (i = 0; i < row_width; i++, sp += 4, dp += 3)
  2967. {
  2968. png_byte a = *(sp + 3);
  2969. if (a == 0xff)
  2970. {
  2971. *dp = gamma_table[*sp];
  2972. *(dp + 1) = gamma_table[*(sp + 1)];
  2973. *(dp + 2) = gamma_table[*(sp + 2)];
  2974. }
  2975. else if (a == 0)
  2976. {
  2977. /* background is already in screen gamma */
  2978. *dp = (png_byte)background->red;
  2979. *(dp + 1) = (png_byte)background->green;
  2980. *(dp + 2) = (png_byte)background->blue;
  2981. }
  2982. else
  2983. {
  2984. png_byte v, w;
  2985. v = gamma_to_1[*sp];
  2986. png_composite(w, v, a, background_1->red);
  2987. *dp = gamma_from_1[w];
  2988. v = gamma_to_1[*(sp + 1)];
  2989. png_composite(w, v, a, background_1->green);
  2990. *(dp + 1) = gamma_from_1[w];
  2991. v = gamma_to_1[*(sp + 2)];
  2992. png_composite(w, v, a, background_1->blue);
  2993. *(dp + 2) = gamma_from_1[w];
  2994. }
  2995. }
  2996. }
  2997. else
  2998. #endif
  2999. {
  3000. sp = row;
  3001. dp = row;
  3002. for (i = 0; i < row_width; i++, sp += 4, dp += 3)
  3003. {
  3004. png_byte a = *(sp + 3);
  3005. if (a == 0xff)
  3006. {
  3007. *dp = *sp;
  3008. *(dp + 1) = *(sp + 1);
  3009. *(dp + 2) = *(sp + 2);
  3010. }
  3011. else if (a == 0)
  3012. {
  3013. *dp = (png_byte)background->red;
  3014. *(dp + 1) = (png_byte)background->green;
  3015. *(dp + 2) = (png_byte)background->blue;
  3016. }
  3017. else
  3018. {
  3019. png_composite(*dp, *sp, a, background->red);
  3020. png_composite(*(dp + 1), *(sp + 1), a,
  3021. background->green);
  3022. png_composite(*(dp + 2), *(sp + 2), a,
  3023. background->blue);
  3024. }
  3025. }
  3026. }
  3027. }
  3028. else /* if (row_info->bit_depth == 16) */
  3029. {
  3030. #if defined(PNG_READ_GAMMA_SUPPORTED)
  3031. if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
  3032. gamma_16_to_1 != NULL)
  3033. {
  3034. sp = row;
  3035. dp = row;
  3036. for (i = 0; i < row_width; i++, sp += 8, dp += 6)
  3037. {
  3038. png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
  3039. << 8) + (png_uint_16)(*(sp + 7)));
  3040. if (a == (png_uint_16)0xffff)
  3041. {
  3042. png_uint_16 v;
  3043. v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
  3044. *dp = (png_byte)((v >> 8) & 0xff);
  3045. *(dp + 1) = (png_byte)(v & 0xff);
  3046. v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
  3047. *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  3048. *(dp + 3) = (png_byte)(v & 0xff);
  3049. v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
  3050. *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  3051. *(dp + 5) = (png_byte)(v & 0xff);
  3052. }
  3053. else if (a == 0)
  3054. {
  3055. /* background is already in screen gamma */
  3056. *dp = (png_byte)((background->red >> 8) & 0xff);
  3057. *(dp + 1) = (png_byte)(background->red & 0xff);
  3058. *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  3059. *(dp + 3) = (png_byte)(background->green & 0xff);
  3060. *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  3061. *(dp + 5) = (png_byte)(background->blue & 0xff);
  3062. }
  3063. else
  3064. {
  3065. png_uint_16 v, w, x;
  3066. v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
  3067. png_composite_16(w, v, a, background_1->red);
  3068. x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
  3069. *dp = (png_byte)((x >> 8) & 0xff);
  3070. *(dp + 1) = (png_byte)(x & 0xff);
  3071. v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
  3072. png_composite_16(w, v, a, background_1->green);
  3073. x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
  3074. *(dp + 2) = (png_byte)((x >> 8) & 0xff);
  3075. *(dp + 3) = (png_byte)(x & 0xff);
  3076. v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
  3077. png_composite_16(w, v, a, background_1->blue);
  3078. x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
  3079. *(dp + 4) = (png_byte)((x >> 8) & 0xff);
  3080. *(dp + 5) = (png_byte)(x & 0xff);
  3081. }
  3082. }
  3083. }
  3084. else
  3085. #endif
  3086. {
  3087. sp = row;
  3088. dp = row;
  3089. for (i = 0; i < row_width; i++, sp += 8, dp += 6)
  3090. {
  3091. png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
  3092. << 8) + (png_uint_16)(*(sp + 7)));
  3093. if (a == (png_uint_16)0xffff)
  3094. {
  3095. png_memcpy(dp, sp, 6);
  3096. }
  3097. else if (a == 0)
  3098. {
  3099. *dp = (png_byte)((background->red >> 8) & 0xff);
  3100. *(dp + 1) = (png_byte)(background->red & 0xff);
  3101. *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
  3102. *(dp + 3) = (png_byte)(background->green & 0xff);
  3103. *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
  3104. *(dp + 5) = (png_byte)(background->blue & 0xff);
  3105. }
  3106. else
  3107. {
  3108. png_uint_16 v;
  3109. png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
  3110. png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
  3111. + *(sp + 3));
  3112. png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
  3113. + *(sp + 5));
  3114. png_composite_16(v, r, a, background->red);
  3115. *dp = (png_byte)((v >> 8) & 0xff);
  3116. *(dp + 1) = (png_byte)(v & 0xff);
  3117. png_composite_16(v, g, a, background->green);
  3118. *(dp + 2) = (png_byte)((v >> 8) & 0xff);
  3119. *(dp + 3) = (png_byte)(v & 0xff);
  3120. png_composite_16(v, b, a, background->blue);
  3121. *(dp + 4) = (png_byte)((v >> 8) & 0xff);
  3122. *(dp + 5) = (png_byte)(v & 0xff);
  3123. }
  3124. }
  3125. }
  3126. }
  3127. break;
  3128. }
  3129. }
  3130. if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
  3131. {
  3132. row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
  3133. row_info->channels--;
  3134. row_info->pixel_depth = (png_byte)(row_info->channels *
  3135. row_info->bit_depth);
  3136. row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  3137. }
  3138. }
  3139. }
  3140. #endif
  3141. #if defined(PNG_READ_GAMMA_SUPPORTED)
  3142. /* Gamma correct the image, avoiding the alpha channel. Make sure
  3143. * you do this after you deal with the transparency issue on grayscale
  3144. * or RGB images. If your bit depth is 8, use gamma_table, if it
  3145. * is 16, use gamma_16_table and gamma_shift. Build these with
  3146. * build_gamma_table().
  3147. */
  3148. // (Note: the reason I've pulled this block of code out of png_do_gamma and into its own function
  3149. // is because the android NDK compiler was crashing when it tried to compile it)
  3150. static void doGamma_RGB (png_uint_32 row_width, png_row_infop row_info, png_bytep row, png_bytep gamma_table, png_uint_16pp gamma_16_table, int gamma_shift)
  3151. {
  3152. if (row_info->bit_depth == 8)
  3153. {
  3154. png_bytep sp = row;
  3155. for (png_uint_32 i = 0; i < row_width; i++)
  3156. {
  3157. *sp = gamma_table[*sp];
  3158. sp++;
  3159. *sp = gamma_table[*sp];
  3160. sp++;
  3161. *sp = gamma_table[*sp];
  3162. sp++;
  3163. }
  3164. }
  3165. else /* if (row_info->bit_depth == 16) */
  3166. {
  3167. png_bytep sp = row;
  3168. for (png_uint_32 i = 0; i < row_width; i++)
  3169. {
  3170. png_uint_16 v;
  3171. v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  3172. *sp = (png_byte)((v >> 8) & 0xff);
  3173. *(sp + 1) = (png_byte)(v & 0xff);
  3174. sp += 2;
  3175. v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  3176. *sp = (png_byte)((v >> 8) & 0xff);
  3177. *(sp + 1) = (png_byte)(v & 0xff);
  3178. sp += 2;
  3179. v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  3180. *sp = (png_byte)((v >> 8) & 0xff);
  3181. *(sp + 1) = (png_byte)(v & 0xff);
  3182. sp += 2;
  3183. }
  3184. }
  3185. }
  3186. void /* PRIVATE */
  3187. png_do_gamma(png_row_infop row_info, png_bytep row,
  3188. png_bytep gamma_table, png_uint_16pp gamma_16_table,
  3189. int gamma_shift)
  3190. {
  3191. png_bytep sp;
  3192. const png_uint_32 row_width=row_info->width;
  3193. png_debug(1, "in png_do_gamma\n");
  3194. if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
  3195. (row_info->bit_depth == 16 && gamma_16_table != NULL)))
  3196. {
  3197. switch (row_info->color_type)
  3198. {
  3199. case PNG_COLOR_TYPE_RGB:
  3200. doGamma_RGB (row_width, row_info, row, gamma_table, gamma_16_table, gamma_shift);
  3201. break;
  3202. case PNG_COLOR_TYPE_RGB_ALPHA:
  3203. {
  3204. if (row_info->bit_depth == 8)
  3205. {
  3206. sp = row;
  3207. for (png_uint_32 i = 0; i < row_width; i++)
  3208. {
  3209. *sp = gamma_table[*sp];
  3210. sp++;
  3211. *sp = gamma_table[*sp];
  3212. sp++;
  3213. *sp = gamma_table[*sp];
  3214. sp++;
  3215. sp++;
  3216. }
  3217. }
  3218. else /* if (row_info->bit_depth == 16) */
  3219. {
  3220. sp = row;
  3221. for (png_uint_32 i = 0; i < row_width; i++)
  3222. {
  3223. png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  3224. *sp = (png_byte)((v >> 8) & 0xff);
  3225. *(sp + 1) = (png_byte)(v & 0xff);
  3226. sp += 2;
  3227. v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  3228. *sp = (png_byte)((v >> 8) & 0xff);
  3229. *(sp + 1) = (png_byte)(v & 0xff);
  3230. sp += 2;
  3231. v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  3232. *sp = (png_byte)((v >> 8) & 0xff);
  3233. *(sp + 1) = (png_byte)(v & 0xff);
  3234. sp += 4;
  3235. }
  3236. }
  3237. break;
  3238. }
  3239. case PNG_COLOR_TYPE_GRAY_ALPHA:
  3240. {
  3241. if (row_info->bit_depth == 8)
  3242. {
  3243. sp = row;
  3244. for (png_uint_32 i = 0; i < row_width; i++)
  3245. {
  3246. *sp = gamma_table[*sp];
  3247. sp += 2;
  3248. }
  3249. }
  3250. else /* if (row_info->bit_depth == 16) */
  3251. {
  3252. sp = row;
  3253. for (png_uint_32 i = 0; i < row_width; i++)
  3254. {
  3255. png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  3256. *sp = (png_byte)((v >> 8) & 0xff);
  3257. *(sp + 1) = (png_byte)(v & 0xff);
  3258. sp += 4;
  3259. }
  3260. }
  3261. break;
  3262. }
  3263. case PNG_COLOR_TYPE_GRAY:
  3264. {
  3265. if (row_info->bit_depth == 2)
  3266. {
  3267. sp = row;
  3268. for (png_uint_32 i = 0; i < row_width; i += 4)
  3269. {
  3270. int a = *sp & 0xc0;
  3271. int b = *sp & 0x30;
  3272. int c = *sp & 0x0c;
  3273. int d = *sp & 0x03;
  3274. *sp = (png_byte)(
  3275. ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
  3276. ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
  3277. ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
  3278. ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
  3279. sp++;
  3280. }
  3281. }
  3282. if (row_info->bit_depth == 4)
  3283. {
  3284. sp = row;
  3285. for (png_uint_32 i = 0; i < row_width; i += 2)
  3286. {
  3287. int msb = *sp & 0xf0;
  3288. int lsb = *sp & 0x0f;
  3289. *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
  3290. | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
  3291. sp++;
  3292. }
  3293. }
  3294. else if (row_info->bit_depth == 8)
  3295. {
  3296. sp = row;
  3297. for (png_uint_32 i = 0; i < row_width; i++)
  3298. {
  3299. *sp = gamma_table[*sp];
  3300. sp++;
  3301. }
  3302. }
  3303. else if (row_info->bit_depth == 16)
  3304. {
  3305. sp = row;
  3306. for (png_uint_32 i = 0; i < row_width; i++)
  3307. {
  3308. png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
  3309. *sp = (png_byte)((v >> 8) & 0xff);
  3310. *(sp + 1) = (png_byte)(v & 0xff);
  3311. sp += 2;
  3312. }
  3313. }
  3314. break;
  3315. }
  3316. }
  3317. }
  3318. }
  3319. #endif
  3320. #if defined(PNG_READ_EXPAND_SUPPORTED)
  3321. /* Expands a palette row to an RGB or RGBA row depending
  3322. * upon whether you supply trans and num_trans.
  3323. */
  3324. void /* PRIVATE */
  3325. png_do_expand_palette(png_row_infop row_info, png_bytep row,
  3326. png_colorp palette, png_bytep trans, int num_trans)
  3327. {
  3328. int shift, value;
  3329. png_bytep sp, dp;
  3330. png_uint_32 i;
  3331. png_uint_32 row_width=row_info->width;
  3332. png_debug(1, "in png_do_expand_palette\n");
  3333. if (
  3334. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  3335. row != NULL && row_info != NULL &&
  3336. #endif
  3337. row_info->color_type == PNG_COLOR_TYPE_PALETTE)
  3338. {
  3339. if (row_info->bit_depth < 8)
  3340. {
  3341. switch (row_info->bit_depth)
  3342. {
  3343. case 1:
  3344. {
  3345. sp = row + (png_size_t)((row_width - 1) >> 3);
  3346. dp = row + (png_size_t)row_width - 1;
  3347. shift = 7 - (int)((row_width + 7) & 0x07);
  3348. for (i = 0; i < row_width; i++)
  3349. {
  3350. if ((*sp >> shift) & 0x01)
  3351. *dp = 1;
  3352. else
  3353. *dp = 0;
  3354. if (shift == 7)
  3355. {
  3356. shift = 0;
  3357. sp--;
  3358. }
  3359. else
  3360. shift++;
  3361. dp--;
  3362. }
  3363. break;
  3364. }
  3365. case 2:
  3366. {
  3367. sp = row + (png_size_t)((row_width - 1) >> 2);
  3368. dp = row + (png_size_t)row_width - 1;
  3369. shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
  3370. for (i = 0; i < row_width; i++)
  3371. {
  3372. value = (*sp >> shift) & 0x03;
  3373. *dp = (png_byte)value;
  3374. if (shift == 6)
  3375. {
  3376. shift = 0;
  3377. sp--;
  3378. }
  3379. else
  3380. shift += 2;
  3381. dp--;
  3382. }
  3383. break;
  3384. }
  3385. case 4:
  3386. {
  3387. sp = row + (png_size_t)((row_width - 1) >> 1);
  3388. dp = row + (png_size_t)row_width - 1;
  3389. shift = (int)((row_width & 0x01) << 2);
  3390. for (i = 0; i < row_width; i++)
  3391. {
  3392. value = (*sp >> shift) & 0x0f;
  3393. *dp = (png_byte)value;
  3394. if (shift == 4)
  3395. {
  3396. shift = 0;
  3397. sp--;
  3398. }
  3399. else
  3400. shift += 4;
  3401. dp--;
  3402. }
  3403. break;
  3404. }
  3405. }
  3406. row_info->bit_depth = 8;
  3407. row_info->pixel_depth = 8;
  3408. row_info->rowbytes = row_width;
  3409. }
  3410. switch (row_info->bit_depth)
  3411. {
  3412. case 8:
  3413. {
  3414. if (trans != NULL)
  3415. {
  3416. sp = row + (png_size_t)row_width - 1;
  3417. dp = row + (png_size_t)(row_width << 2) - 1;
  3418. for (i = 0; i < row_width; i++)
  3419. {
  3420. if ((int)(*sp) >= num_trans)
  3421. *dp-- = 0xff;
  3422. else
  3423. *dp-- = trans[*sp];
  3424. *dp-- = palette[*sp].blue;
  3425. *dp-- = palette[*sp].green;
  3426. *dp-- = palette[*sp].red;
  3427. sp--;
  3428. }
  3429. row_info->bit_depth = 8;
  3430. row_info->pixel_depth = 32;
  3431. row_info->rowbytes = row_width * 4;
  3432. row_info->color_type = 6;
  3433. row_info->channels = 4;
  3434. }
  3435. else
  3436. {
  3437. sp = row + (png_size_t)row_width - 1;
  3438. dp = row + (png_size_t)(row_width * 3) - 1;
  3439. for (i = 0; i < row_width; i++)
  3440. {
  3441. *dp-- = palette[*sp].blue;
  3442. *dp-- = palette[*sp].green;
  3443. *dp-- = palette[*sp].red;
  3444. sp--;
  3445. }
  3446. row_info->bit_depth = 8;
  3447. row_info->pixel_depth = 24;
  3448. row_info->rowbytes = row_width * 3;
  3449. row_info->color_type = 2;
  3450. row_info->channels = 3;
  3451. }
  3452. break;
  3453. }
  3454. }
  3455. }
  3456. }
  3457. /* If the bit depth < 8, it is expanded to 8. Also, if the already
  3458. * expanded transparency value is supplied, an alpha channel is built.
  3459. */
  3460. void /* PRIVATE */
  3461. png_do_expand(png_row_infop row_info, png_bytep row,
  3462. png_color_16p trans_value)
  3463. {
  3464. int shift, value;
  3465. png_bytep sp, dp;
  3466. png_uint_32 i;
  3467. png_uint_32 row_width=row_info->width;
  3468. png_debug(1, "in png_do_expand\n");
  3469. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  3470. if (row != NULL && row_info != NULL)
  3471. #endif
  3472. {
  3473. if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
  3474. {
  3475. png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
  3476. if (row_info->bit_depth < 8)
  3477. {
  3478. switch (row_info->bit_depth)
  3479. {
  3480. case 1:
  3481. {
  3482. gray = (png_uint_16)((gray&0x01)*0xff);
  3483. sp = row + (png_size_t)((row_width - 1) >> 3);
  3484. dp = row + (png_size_t)row_width - 1;
  3485. shift = 7 - (int)((row_width + 7) & 0x07);
  3486. for (i = 0; i < row_width; i++)
  3487. {
  3488. if ((*sp >> shift) & 0x01)
  3489. *dp = 0xff;
  3490. else
  3491. *dp = 0;
  3492. if (shift == 7)
  3493. {
  3494. shift = 0;
  3495. sp--;
  3496. }
  3497. else
  3498. shift++;
  3499. dp--;
  3500. }
  3501. break;
  3502. }
  3503. case 2:
  3504. {
  3505. gray = (png_uint_16)((gray&0x03)*0x55);
  3506. sp = row + (png_size_t)((row_width - 1) >> 2);
  3507. dp = row + (png_size_t)row_width - 1;
  3508. shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
  3509. for (i = 0; i < row_width; i++)
  3510. {
  3511. value = (*sp >> shift) & 0x03;
  3512. *dp = (png_byte)(value | (value << 2) | (value << 4) |
  3513. (value << 6));
  3514. if (shift == 6)
  3515. {
  3516. shift = 0;
  3517. sp--;
  3518. }
  3519. else
  3520. shift += 2;
  3521. dp--;
  3522. }
  3523. break;
  3524. }
  3525. case 4:
  3526. {
  3527. gray = (png_uint_16)((gray&0x0f)*0x11);
  3528. sp = row + (png_size_t)((row_width - 1) >> 1);
  3529. dp = row + (png_size_t)row_width - 1;
  3530. shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
  3531. for (i = 0; i < row_width; i++)
  3532. {
  3533. value = (*sp >> shift) & 0x0f;
  3534. *dp = (png_byte)(value | (value << 4));
  3535. if (shift == 4)
  3536. {
  3537. shift = 0;
  3538. sp--;
  3539. }
  3540. else
  3541. shift = 4;
  3542. dp--;
  3543. }
  3544. break;
  3545. }
  3546. }
  3547. row_info->bit_depth = 8;
  3548. row_info->pixel_depth = 8;
  3549. row_info->rowbytes = row_width;
  3550. }
  3551. if (trans_value != NULL)
  3552. {
  3553. if (row_info->bit_depth == 8)
  3554. {
  3555. gray = gray & 0xff;
  3556. sp = row + (png_size_t)row_width - 1;
  3557. dp = row + (png_size_t)(row_width << 1) - 1;
  3558. for (i = 0; i < row_width; i++)
  3559. {
  3560. if (*sp == gray)
  3561. *dp-- = 0;
  3562. else
  3563. *dp-- = 0xff;
  3564. *dp-- = *sp--;
  3565. }
  3566. }
  3567. else if (row_info->bit_depth == 16)
  3568. {
  3569. png_byte gray_high = (gray >> 8) & 0xff;
  3570. png_byte gray_low = gray & 0xff;
  3571. sp = row + row_info->rowbytes - 1;
  3572. dp = row + (row_info->rowbytes << 1) - 1;
  3573. for (i = 0; i < row_width; i++)
  3574. {
  3575. if (*(sp-1) == gray_high && *(sp) == gray_low)
  3576. {
  3577. *dp-- = 0;
  3578. *dp-- = 0;
  3579. }
  3580. else
  3581. {
  3582. *dp-- = 0xff;
  3583. *dp-- = 0xff;
  3584. }
  3585. *dp-- = *sp--;
  3586. *dp-- = *sp--;
  3587. }
  3588. }
  3589. row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
  3590. row_info->channels = 2;
  3591. row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
  3592. row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
  3593. row_width);
  3594. }
  3595. }
  3596. else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
  3597. {
  3598. if (row_info->bit_depth == 8)
  3599. {
  3600. png_byte red = trans_value->red & 0xff;
  3601. png_byte green = trans_value->green & 0xff;
  3602. png_byte blue = trans_value->blue & 0xff;
  3603. sp = row + (png_size_t)row_info->rowbytes - 1;
  3604. dp = row + (png_size_t)(row_width << 2) - 1;
  3605. for (i = 0; i < row_width; i++)
  3606. {
  3607. if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
  3608. *dp-- = 0;
  3609. else
  3610. *dp-- = 0xff;
  3611. *dp-- = *sp--;
  3612. *dp-- = *sp--;
  3613. *dp-- = *sp--;
  3614. }
  3615. }
  3616. else if (row_info->bit_depth == 16)
  3617. {
  3618. png_byte red_high = (trans_value->red >> 8) & 0xff;
  3619. png_byte green_high = (trans_value->green >> 8) & 0xff;
  3620. png_byte blue_high = (trans_value->blue >> 8) & 0xff;
  3621. png_byte red_low = trans_value->red & 0xff;
  3622. png_byte green_low = trans_value->green & 0xff;
  3623. png_byte blue_low = trans_value->blue & 0xff;
  3624. sp = row + row_info->rowbytes - 1;
  3625. dp = row + (png_size_t)(row_width << 3) - 1;
  3626. for (i = 0; i < row_width; i++)
  3627. {
  3628. if (*(sp - 5) == red_high &&
  3629. *(sp - 4) == red_low &&
  3630. *(sp - 3) == green_high &&
  3631. *(sp - 2) == green_low &&
  3632. *(sp - 1) == blue_high &&
  3633. *(sp ) == blue_low)
  3634. {
  3635. *dp-- = 0;
  3636. *dp-- = 0;
  3637. }
  3638. else
  3639. {
  3640. *dp-- = 0xff;
  3641. *dp-- = 0xff;
  3642. }
  3643. *dp-- = *sp--;
  3644. *dp-- = *sp--;
  3645. *dp-- = *sp--;
  3646. *dp-- = *sp--;
  3647. *dp-- = *sp--;
  3648. *dp-- = *sp--;
  3649. }
  3650. }
  3651. row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  3652. row_info->channels = 4;
  3653. row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
  3654. row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  3655. }
  3656. }
  3657. }
  3658. #endif
  3659. #if defined(PNG_READ_DITHER_SUPPORTED)
  3660. void /* PRIVATE */
  3661. png_do_dither(png_row_infop row_info, png_bytep row,
  3662. png_bytep palette_lookup, png_bytep dither_lookup)
  3663. {
  3664. png_bytep sp, dp;
  3665. png_uint_32 i;
  3666. png_uint_32 row_width=row_info->width;
  3667. png_debug(1, "in png_do_dither\n");
  3668. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  3669. if (row != NULL && row_info != NULL)
  3670. #endif
  3671. {
  3672. if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
  3673. palette_lookup && row_info->bit_depth == 8)
  3674. {
  3675. int r, g, b, p;
  3676. sp = row;
  3677. dp = row;
  3678. for (i = 0; i < row_width; i++)
  3679. {
  3680. r = *sp++;
  3681. g = *sp++;
  3682. b = *sp++;
  3683. /* this looks real messy, but the compiler will reduce
  3684. it down to a reasonable formula. For example, with
  3685. 5 bits per color, we get:
  3686. p = (((r >> 3) & 0x1f) << 10) |
  3687. (((g >> 3) & 0x1f) << 5) |
  3688. ((b >> 3) & 0x1f);
  3689. */
  3690. p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  3691. ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  3692. (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  3693. (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  3694. ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  3695. (PNG_DITHER_BLUE_BITS)) |
  3696. ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  3697. ((1 << PNG_DITHER_BLUE_BITS) - 1));
  3698. *dp++ = palette_lookup[p];
  3699. }
  3700. row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  3701. row_info->channels = 1;
  3702. row_info->pixel_depth = row_info->bit_depth;
  3703. row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  3704. }
  3705. else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
  3706. palette_lookup != NULL && row_info->bit_depth == 8)
  3707. {
  3708. int r, g, b, p;
  3709. sp = row;
  3710. dp = row;
  3711. for (i = 0; i < row_width; i++)
  3712. {
  3713. r = *sp++;
  3714. g = *sp++;
  3715. b = *sp++;
  3716. sp++;
  3717. p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
  3718. ((1 << PNG_DITHER_RED_BITS) - 1)) <<
  3719. (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
  3720. (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
  3721. ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
  3722. (PNG_DITHER_BLUE_BITS)) |
  3723. ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
  3724. ((1 << PNG_DITHER_BLUE_BITS) - 1));
  3725. *dp++ = palette_lookup[p];
  3726. }
  3727. row_info->color_type = PNG_COLOR_TYPE_PALETTE;
  3728. row_info->channels = 1;
  3729. row_info->pixel_depth = row_info->bit_depth;
  3730. row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width);
  3731. }
  3732. else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
  3733. dither_lookup && row_info->bit_depth == 8)
  3734. {
  3735. sp = row;
  3736. for (i = 0; i < row_width; i++, sp++)
  3737. {
  3738. *sp = dither_lookup[*sp];
  3739. }
  3740. }
  3741. }
  3742. }
  3743. #endif
  3744. #ifdef PNG_FLOATING_POINT_SUPPORTED
  3745. #if defined(PNG_READ_GAMMA_SUPPORTED)
  3746. static PNG_CONST int png_gamma_shift[] =
  3747. {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
  3748. /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
  3749. * tables, we don't make a full table if we are reducing to 8-bit in
  3750. * the future. Note also how the gamma_16 tables are segmented so that
  3751. * we don't need to allocate > 64K chunks for a full 16-bit table.
  3752. */
  3753. void /* PRIVATE */
  3754. png_build_gamma_table(png_structp png_ptr)
  3755. {
  3756. png_debug(1, "in png_build_gamma_table\n");
  3757. if (png_ptr->bit_depth <= 8)
  3758. {
  3759. int i;
  3760. double g;
  3761. if (png_ptr->screen_gamma > .000001)
  3762. g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  3763. else
  3764. g = 1.0;
  3765. png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
  3766. (png_uint_32)256);
  3767. for (i = 0; i < 256; i++)
  3768. {
  3769. png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
  3770. g) * 255.0 + .5);
  3771. }
  3772. #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
  3773. defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  3774. if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
  3775. {
  3776. g = 1.0 / (png_ptr->gamma);
  3777. png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
  3778. (png_uint_32)256);
  3779. for (i = 0; i < 256; i++)
  3780. {
  3781. png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
  3782. g) * 255.0 + .5);
  3783. }
  3784. png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
  3785. (png_uint_32)256);
  3786. if(png_ptr->screen_gamma > 0.000001)
  3787. g = 1.0 / png_ptr->screen_gamma;
  3788. else
  3789. g = png_ptr->gamma; /* probably doing rgb_to_gray */
  3790. for (i = 0; i < 256; i++)
  3791. {
  3792. png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
  3793. g) * 255.0 + .5);
  3794. }
  3795. }
  3796. #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
  3797. }
  3798. else
  3799. {
  3800. double g;
  3801. int i, j, shift, num;
  3802. int sig_bit;
  3803. png_uint_32 ig;
  3804. if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  3805. {
  3806. sig_bit = (int)png_ptr->sig_bit.red;
  3807. if ((int)png_ptr->sig_bit.green > sig_bit)
  3808. sig_bit = png_ptr->sig_bit.green;
  3809. if ((int)png_ptr->sig_bit.blue > sig_bit)
  3810. sig_bit = png_ptr->sig_bit.blue;
  3811. }
  3812. else
  3813. {
  3814. sig_bit = (int)png_ptr->sig_bit.gray;
  3815. }
  3816. if (sig_bit > 0)
  3817. shift = 16 - sig_bit;
  3818. else
  3819. shift = 0;
  3820. if (png_ptr->transformations & PNG_16_TO_8)
  3821. {
  3822. if (shift < (16 - PNG_MAX_GAMMA_8))
  3823. shift = (16 - PNG_MAX_GAMMA_8);
  3824. }
  3825. if (shift > 8)
  3826. shift = 8;
  3827. if (shift < 0)
  3828. shift = 0;
  3829. png_ptr->gamma_shift = (png_byte)shift;
  3830. num = (1 << (8 - shift));
  3831. if (png_ptr->screen_gamma > .000001)
  3832. g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
  3833. else
  3834. g = 1.0;
  3835. png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
  3836. (png_uint_32)(num * png_sizeof (png_uint_16p)));
  3837. if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
  3838. {
  3839. double fin, fout;
  3840. png_uint_32 last, max;
  3841. for (i = 0; i < num; i++)
  3842. {
  3843. png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
  3844. (png_uint_32)(256 * png_sizeof (png_uint_16)));
  3845. }
  3846. g = 1.0 / g;
  3847. last = 0;
  3848. for (i = 0; i < 256; i++)
  3849. {
  3850. fout = ((double)i + 0.5) / 256.0;
  3851. fin = pow(fout, g);
  3852. max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
  3853. while (last <= max)
  3854. {
  3855. png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  3856. [(int)(last >> (8 - shift))] = (png_uint_16)(
  3857. (png_uint_16)i | ((png_uint_16)i << 8));
  3858. last++;
  3859. }
  3860. }
  3861. while (last < ((png_uint_32)num << 8))
  3862. {
  3863. png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
  3864. [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
  3865. last++;
  3866. }
  3867. }
  3868. else
  3869. {
  3870. for (i = 0; i < num; i++)
  3871. {
  3872. png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
  3873. (png_uint_32)(256 * png_sizeof (png_uint_16)));
  3874. ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
  3875. for (j = 0; j < 256; j++)
  3876. {
  3877. png_ptr->gamma_16_table[i][j] =
  3878. (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  3879. 65535.0, g) * 65535.0 + .5);
  3880. }
  3881. }
  3882. }
  3883. #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
  3884. defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
  3885. if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
  3886. {
  3887. g = 1.0 / (png_ptr->gamma);
  3888. png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
  3889. (png_uint_32)(num * png_sizeof (png_uint_16p )));
  3890. for (i = 0; i < num; i++)
  3891. {
  3892. png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
  3893. (png_uint_32)(256 * png_sizeof (png_uint_16)));
  3894. ig = (((png_uint_32)i *
  3895. (png_uint_32)png_gamma_shift[shift]) >> 4);
  3896. for (j = 0; j < 256; j++)
  3897. {
  3898. png_ptr->gamma_16_to_1[i][j] =
  3899. (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  3900. 65535.0, g) * 65535.0 + .5);
  3901. }
  3902. }
  3903. if(png_ptr->screen_gamma > 0.000001)
  3904. g = 1.0 / png_ptr->screen_gamma;
  3905. else
  3906. g = png_ptr->gamma; /* probably doing rgb_to_gray */
  3907. png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
  3908. (png_uint_32)(num * png_sizeof (png_uint_16p)));
  3909. for (i = 0; i < num; i++)
  3910. {
  3911. png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
  3912. (png_uint_32)(256 * png_sizeof (png_uint_16)));
  3913. ig = (((png_uint_32)i *
  3914. (png_uint_32)png_gamma_shift[shift]) >> 4);
  3915. for (j = 0; j < 256; j++)
  3916. {
  3917. png_ptr->gamma_16_from_1[i][j] =
  3918. (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
  3919. 65535.0, g) * 65535.0 + .5);
  3920. }
  3921. }
  3922. }
  3923. #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
  3924. }
  3925. }
  3926. #endif
  3927. /* To do: install integer version of png_build_gamma_table here */
  3928. #endif
  3929. #if defined(PNG_MNG_FEATURES_SUPPORTED)
  3930. /* undoes intrapixel differencing */
  3931. void /* PRIVATE */
  3932. png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
  3933. {
  3934. png_debug(1, "in png_do_read_intrapixel\n");
  3935. if (
  3936. #if defined(PNG_USELESS_TESTS_SUPPORTED)
  3937. row != NULL && row_info != NULL &&
  3938. #endif
  3939. (row_info->color_type & PNG_COLOR_MASK_COLOR))
  3940. {
  3941. int bytes_per_pixel;
  3942. png_uint_32 row_width = row_info->width;
  3943. if (row_info->bit_depth == 8)
  3944. {
  3945. png_bytep rp;
  3946. png_uint_32 i;
  3947. if (row_info->color_type == PNG_COLOR_TYPE_RGB)
  3948. bytes_per_pixel = 3;
  3949. else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  3950. bytes_per_pixel = 4;
  3951. else
  3952. return;
  3953. for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
  3954. {
  3955. *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
  3956. *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
  3957. }
  3958. }
  3959. else if (row_info->bit_depth == 16)
  3960. {
  3961. png_bytep rp;
  3962. png_uint_32 i;
  3963. if (row_info->color_type == PNG_COLOR_TYPE_RGB)
  3964. bytes_per_pixel = 6;
  3965. else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  3966. bytes_per_pixel = 8;
  3967. else
  3968. return;
  3969. for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
  3970. {
  3971. png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
  3972. png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
  3973. png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
  3974. png_uint_32 red = (png_uint_32)((s0+s1+65536L) & 0xffffL);
  3975. png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL);
  3976. *(rp ) = (png_byte)((red >> 8) & 0xff);
  3977. *(rp+1) = (png_byte)(red & 0xff);
  3978. *(rp+4) = (png_byte)((blue >> 8) & 0xff);
  3979. *(rp+5) = (png_byte)(blue & 0xff);
  3980. }
  3981. }
  3982. }
  3983. }
  3984. #endif /* PNG_MNG_FEATURES_SUPPORTED */
  3985. #endif /* PNG_READ_SUPPORTED */