~thomas-voss/glmark2/build-for-mir

« back to all changes in this revision

Viewing changes to src/libpng/pngrtran.c

  • Committer: Package Import Robot
  • Author(s): Alexandros Frantzis
  • Date: 2011-09-22 11:32:17 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: package-import@ubuntu.com-20110922113217-wvok1qgruexari8d
Tags: 2011.09-0ubuntu1
* New upstream release 2011.09.
* debian/control:
  - Start the description of the glmark2-data package with
    a lowercase letter.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* pngrtran.c - transforms the data in a row for PNG readers
 
3
 *
 
4
 * Last changed in libpng 1.2.45 [July 7, 2011]
 
5
 * Copyright (c) 1998-2011 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 code is released under the libpng license.
 
10
 * For conditions of distribution and use, see the disclaimer
 
11
 * and license in png.h
 
12
 *
 
13
 * This file contains functions optionally called by an application
 
14
 * in order to tell libpng how to handle data when reading a PNG.
 
15
 * Transformations that are used in both reading and writing are
 
16
 * in pngtrans.c.
 
17
 */
 
18
 
 
19
#define PNG_INTERNAL
 
20
#define PNG_NO_PEDANTIC_WARNINGS
 
21
#include "png.h"
 
22
#ifdef PNG_READ_SUPPORTED
 
23
 
 
24
/* Set the action on getting a CRC error for an ancillary or critical chunk. */
 
25
void PNGAPI
 
26
png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
 
27
{
 
28
   png_debug(1, "in png_set_crc_action");
 
29
 
 
30
   if (png_ptr == NULL)
 
31
      return;
 
32
 
 
33
   /* Tell libpng how we react to CRC errors in critical chunks */
 
34
   switch (crit_action)
 
35
   {
 
36
      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
 
37
         break;
 
38
 
 
39
      case PNG_CRC_WARN_USE:                               /* Warn/use data */
 
40
         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
 
41
         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
 
42
         break;
 
43
 
 
44
      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
 
45
         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
 
46
         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
 
47
                           PNG_FLAG_CRC_CRITICAL_IGNORE;
 
48
         break;
 
49
 
 
50
      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
 
51
         png_warning(png_ptr,
 
52
            "Can't discard critical data on CRC error.");
 
53
      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
 
54
 
 
55
      case PNG_CRC_DEFAULT:
 
56
      default:
 
57
         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
 
58
         break;
 
59
   }
 
60
 
 
61
   /* Tell libpng how we react to CRC errors in ancillary chunks */
 
62
   switch (ancil_action)
 
63
   {
 
64
      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
 
65
         break;
 
66
 
 
67
      case PNG_CRC_WARN_USE:                              /* Warn/use data */
 
68
         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
 
69
         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
 
70
         break;
 
71
 
 
72
      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
 
73
         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
 
74
         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
 
75
                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
 
76
         break;
 
77
 
 
78
      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
 
79
         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
 
80
         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
 
81
         break;
 
82
 
 
83
      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
 
84
 
 
85
      case PNG_CRC_DEFAULT:
 
86
      default:
 
87
         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
 
88
         break;
 
89
   }
 
90
}
 
91
 
 
92
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
 
93
    defined(PNG_FLOATING_POINT_SUPPORTED)
 
94
/* Handle alpha and tRNS via a background color */
 
95
void PNGAPI
 
96
png_set_background(png_structp png_ptr,
 
97
   png_color_16p background_color, int background_gamma_code,
 
98
   int need_expand, double background_gamma)
 
99
{
 
100
   png_debug(1, "in png_set_background");
 
101
 
 
102
   if (png_ptr == NULL)
 
103
      return;
 
104
   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
 
105
   {
 
106
      png_warning(png_ptr, "Application must supply a known background gamma");
 
107
      return;
 
108
   }
 
109
 
 
110
   png_ptr->transformations |= PNG_BACKGROUND;
 
111
   png_memcpy(&(png_ptr->background), background_color,
 
112
      png_sizeof(png_color_16));
 
113
   png_ptr->background_gamma = (float)background_gamma;
 
114
   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
 
115
   png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
 
116
}
 
117
#endif
 
118
 
 
119
#ifdef PNG_READ_16_TO_8_SUPPORTED
 
120
/* Strip 16 bit depth files to 8 bit depth */
 
121
void PNGAPI
 
122
png_set_strip_16(png_structp png_ptr)
 
123
{
 
124
   png_debug(1, "in png_set_strip_16");
 
125
 
 
126
   if (png_ptr == NULL)
 
127
      return;
 
128
   png_ptr->transformations |= PNG_16_TO_8;
 
129
}
 
130
#endif
 
131
 
 
132
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
 
133
void PNGAPI
 
134
png_set_strip_alpha(png_structp png_ptr)
 
135
{
 
136
   png_debug(1, "in png_set_strip_alpha");
 
137
 
 
138
   if (png_ptr == NULL)
 
139
      return;
 
140
   png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
 
141
}
 
142
#endif
 
143
 
 
144
#ifdef PNG_READ_DITHER_SUPPORTED
 
145
/* Dither file to 8 bit.  Supply a palette, the current number
 
146
 * of elements in the palette, the maximum number of elements
 
147
 * allowed, and a histogram if possible.  If the current number
 
148
 * of colors is greater then the maximum number, the palette will be
 
149
 * modified to fit in the maximum number.  "full_dither" indicates
 
150
 * whether we need a dithering cube set up for RGB images, or if we
 
151
 * simply are reducing the number of colors in a paletted image.
 
152
 */
 
153
 
 
154
typedef struct png_dsort_struct
 
155
{
 
156
   struct png_dsort_struct FAR * next;
 
157
   png_byte left;
 
158
   png_byte right;
 
159
} png_dsort;
 
160
typedef png_dsort FAR *       png_dsortp;
 
161
typedef png_dsort FAR * FAR * png_dsortpp;
 
162
 
 
163
void PNGAPI
 
164
png_set_dither(png_structp png_ptr, png_colorp palette,
 
165
   int num_palette, int maximum_colors, png_uint_16p histogram,
 
166
   int full_dither)
 
167
{
 
168
   png_debug(1, "in png_set_dither");
 
169
 
 
170
   if (png_ptr == NULL)
 
171
      return;
 
172
   png_ptr->transformations |= PNG_DITHER;
 
173
 
 
174
   if (!full_dither)
 
175
   {
 
176
      int i;
 
177
 
 
178
      png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
 
179
         (png_uint_32)(num_palette * png_sizeof(png_byte)));
 
180
      for (i = 0; i < num_palette; i++)
 
181
         png_ptr->dither_index[i] = (png_byte)i;
 
182
   }
 
183
 
 
184
   if (num_palette > maximum_colors)
 
185
   {
 
186
      if (histogram != NULL)
 
187
      {
 
188
         /* This is easy enough, just throw out the least used colors.
 
189
          * Perhaps not the best solution, but good enough.
 
190
          */
 
191
 
 
192
         int i;
 
193
 
 
194
         /* Initialize an array to sort colors */
 
195
         png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
 
196
            (png_uint_32)(num_palette * png_sizeof(png_byte)));
 
197
 
 
198
         /* Initialize the dither_sort array */
 
199
         for (i = 0; i < num_palette; i++)
 
200
            png_ptr->dither_sort[i] = (png_byte)i;
 
201
 
 
202
         /* Find the least used palette entries by starting a
 
203
          * bubble sort, and running it until we have sorted
 
204
          * out enough colors.  Note that we don't care about
 
205
          * sorting all the colors, just finding which are
 
206
          * least used.
 
207
          */
 
208
 
 
209
         for (i = num_palette - 1; i >= maximum_colors; i--)
 
210
         {
 
211
            int done; /* To stop early if the list is pre-sorted */
 
212
            int j;
 
213
 
 
214
            done = 1;
 
215
            for (j = 0; j < i; j++)
 
216
            {
 
217
               if (histogram[png_ptr->dither_sort[j]]
 
218
                   < histogram[png_ptr->dither_sort[j + 1]])
 
219
               {
 
220
                  png_byte t;
 
221
 
 
222
                  t = png_ptr->dither_sort[j];
 
223
                  png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
 
224
                  png_ptr->dither_sort[j + 1] = t;
 
225
                  done = 0;
 
226
               }
 
227
            }
 
228
            if (done)
 
229
               break;
 
230
         }
 
231
 
 
232
         /* Swap the palette around, and set up a table, if necessary */
 
233
         if (full_dither)
 
234
         {
 
235
            int j = num_palette;
 
236
 
 
237
            /* Put all the useful colors within the max, but don't
 
238
             * move the others.
 
239
             */
 
240
            for (i = 0; i < maximum_colors; i++)
 
241
            {
 
242
               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
 
243
               {
 
244
                  do
 
245
                     j--;
 
246
                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
 
247
                  palette[i] = palette[j];
 
248
               }
 
249
            }
 
250
         }
 
251
         else
 
252
         {
 
253
            int j = num_palette;
 
254
 
 
255
            /* Move all the used colors inside the max limit, and
 
256
             * develop a translation table.
 
257
             */
 
258
            for (i = 0; i < maximum_colors; i++)
 
259
            {
 
260
               /* Only move the colors we need to */
 
261
               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
 
262
               {
 
263
                  png_color tmp_color;
 
264
 
 
265
                  do
 
266
                     j--;
 
267
                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
 
268
 
 
269
                  tmp_color = palette[j];
 
270
                  palette[j] = palette[i];
 
271
                  palette[i] = tmp_color;
 
272
                  /* Indicate where the color went */
 
273
                  png_ptr->dither_index[j] = (png_byte)i;
 
274
                  png_ptr->dither_index[i] = (png_byte)j;
 
275
               }
 
276
            }
 
277
 
 
278
            /* Find closest color for those colors we are not using */
 
279
            for (i = 0; i < num_palette; i++)
 
280
            {
 
281
               if ((int)png_ptr->dither_index[i] >= maximum_colors)
 
282
               {
 
283
                  int min_d, k, min_k, d_index;
 
284
 
 
285
                  /* Find the closest color to one we threw out */
 
286
                  d_index = png_ptr->dither_index[i];
 
287
                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
 
288
                  for (k = 1, min_k = 0; k < maximum_colors; k++)
 
289
                  {
 
290
                     int d;
 
291
 
 
292
                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
 
293
 
 
294
                     if (d < min_d)
 
295
                     {
 
296
                        min_d = d;
 
297
                        min_k = k;
 
298
                     }
 
299
                  }
 
300
                  /* Point to closest color */
 
301
                  png_ptr->dither_index[i] = (png_byte)min_k;
 
302
               }
 
303
            }
 
304
         }
 
305
         png_free(png_ptr, png_ptr->dither_sort);
 
306
         png_ptr->dither_sort = NULL;
 
307
      }
 
308
      else
 
309
      {
 
310
         /* This is much harder to do simply (and quickly).  Perhaps
 
311
          * we need to go through a median cut routine, but those
 
312
          * don't always behave themselves with only a few colors
 
313
          * as input.  So we will just find the closest two colors,
 
314
          * and throw out one of them (chosen somewhat randomly).
 
315
          * [We don't understand this at all, so if someone wants to
 
316
          *  work on improving it, be our guest - AED, GRP]
 
317
          */
 
318
         int i;
 
319
         int max_d;
 
320
         int num_new_palette;
 
321
         png_dsortp t;
 
322
         png_dsortpp hash;
 
323
 
 
324
         t = NULL;
 
325
 
 
326
         /* Initialize palette index arrays */
 
327
         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
 
328
            (png_uint_32)(num_palette * png_sizeof(png_byte)));
 
329
         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
 
330
            (png_uint_32)(num_palette * png_sizeof(png_byte)));
 
331
 
 
332
         /* Initialize the sort array */
 
333
         for (i = 0; i < num_palette; i++)
 
334
         {
 
335
            png_ptr->index_to_palette[i] = (png_byte)i;
 
336
            png_ptr->palette_to_index[i] = (png_byte)i;
 
337
         }
 
338
 
 
339
         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
 
340
            png_sizeof(png_dsortp)));
 
341
 
 
342
         num_new_palette = num_palette;
 
343
 
 
344
         /* Initial wild guess at how far apart the farthest pixel
 
345
          * pair we will be eliminating will be.  Larger
 
346
          * numbers mean more areas will be allocated, Smaller
 
347
          * numbers run the risk of not saving enough data, and
 
348
          * having to do this all over again.
 
349
          *
 
350
          * I have not done extensive checking on this number.
 
351
          */
 
352
         max_d = 96;
 
353
 
 
354
         while (num_new_palette > maximum_colors)
 
355
         {
 
356
            for (i = 0; i < num_new_palette - 1; i++)
 
357
            {
 
358
               int j;
 
359
 
 
360
               for (j = i + 1; j < num_new_palette; j++)
 
361
               {
 
362
                  int d;
 
363
 
 
364
                  d = PNG_COLOR_DIST(palette[i], palette[j]);
 
365
 
 
366
                  if (d <= max_d)
 
367
                  {
 
368
 
 
369
                     t = (png_dsortp)png_malloc_warn(png_ptr,
 
370
                         (png_uint_32)(png_sizeof(png_dsort)));
 
371
                     if (t == NULL)
 
372
                         break;
 
373
                     t->next = hash[d];
 
374
                     t->left = (png_byte)i;
 
375
                     t->right = (png_byte)j;
 
376
                     hash[d] = t;
 
377
                  }
 
378
               }
 
379
               if (t == NULL)
 
380
                  break;
 
381
            }
 
382
 
 
383
            if (t != NULL)
 
384
            for (i = 0; i <= max_d; i++)
 
385
            {
 
386
               if (hash[i] != NULL)
 
387
               {
 
388
                  png_dsortp p;
 
389
 
 
390
                  for (p = hash[i]; p; p = p->next)
 
391
                  {
 
392
                     if ((int)png_ptr->index_to_palette[p->left]
 
393
                        < num_new_palette &&
 
394
                        (int)png_ptr->index_to_palette[p->right]
 
395
                        < num_new_palette)
 
396
                     {
 
397
                        int j, next_j;
 
398
 
 
399
                        if (num_new_palette & 0x01)
 
400
                        {
 
401
                           j = p->left;
 
402
                           next_j = p->right;
 
403
                        }
 
404
                        else
 
405
                        {
 
406
                           j = p->right;
 
407
                           next_j = p->left;
 
408
                        }
 
409
 
 
410
                        num_new_palette--;
 
411
                        palette[png_ptr->index_to_palette[j]]
 
412
                          = palette[num_new_palette];
 
413
                        if (!full_dither)
 
414
                        {
 
415
                           int k;
 
416
 
 
417
                           for (k = 0; k < num_palette; k++)
 
418
                           {
 
419
                              if (png_ptr->dither_index[k] ==
 
420
                                 png_ptr->index_to_palette[j])
 
421
                                 png_ptr->dither_index[k] =
 
422
                                    png_ptr->index_to_palette[next_j];
 
423
                              if ((int)png_ptr->dither_index[k] ==
 
424
                                 num_new_palette)
 
425
                                 png_ptr->dither_index[k] =
 
426
                                    png_ptr->index_to_palette[j];
 
427
                           }
 
428
                        }
 
429
 
 
430
                        png_ptr->index_to_palette[png_ptr->palette_to_index
 
431
                           [num_new_palette]] = png_ptr->index_to_palette[j];
 
432
                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
 
433
                           = png_ptr->palette_to_index[num_new_palette];
 
434
 
 
435
                        png_ptr->index_to_palette[j] =
 
436
                            (png_byte)num_new_palette;
 
437
                        png_ptr->palette_to_index[num_new_palette] =
 
438
                            (png_byte)j;
 
439
                     }
 
440
                     if (num_new_palette <= maximum_colors)
 
441
                        break;
 
442
                  }
 
443
                  if (num_new_palette <= maximum_colors)
 
444
                     break;
 
445
               }
 
446
            }
 
447
 
 
448
            for (i = 0; i < 769; i++)
 
449
            {
 
450
               if (hash[i] != NULL)
 
451
               {
 
452
                  png_dsortp p = hash[i];
 
453
                  while (p)
 
454
                  {
 
455
                     t = p->next;
 
456
                     png_free(png_ptr, p);
 
457
                     p = t;
 
458
                  }
 
459
               }
 
460
               hash[i] = 0;
 
461
            }
 
462
            max_d += 96;
 
463
         }
 
464
         png_free(png_ptr, hash);
 
465
         png_free(png_ptr, png_ptr->palette_to_index);
 
466
         png_free(png_ptr, png_ptr->index_to_palette);
 
467
         png_ptr->palette_to_index = NULL;
 
468
         png_ptr->index_to_palette = NULL;
 
469
      }
 
470
      num_palette = maximum_colors;
 
471
   }
 
472
   if (png_ptr->palette == NULL)
 
473
   {
 
474
      png_ptr->palette = palette;
 
475
   }
 
476
   png_ptr->num_palette = (png_uint_16)num_palette;
 
477
 
 
478
   if (full_dither)
 
479
   {
 
480
      int i;
 
481
      png_bytep distance;
 
482
      int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
 
483
         PNG_DITHER_BLUE_BITS;
 
484
      int num_red = (1 << PNG_DITHER_RED_BITS);
 
485
      int num_green = (1 << PNG_DITHER_GREEN_BITS);
 
486
      int num_blue = (1 << PNG_DITHER_BLUE_BITS);
 
487
      png_size_t num_entries = ((png_size_t)1 << total_bits);
 
488
 
 
489
      png_ptr->palette_lookup = (png_bytep )png_calloc(png_ptr,
 
490
         (png_uint_32)(num_entries * png_sizeof(png_byte)));
 
491
 
 
492
      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
 
493
         png_sizeof(png_byte)));
 
494
      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
 
495
 
 
496
      for (i = 0; i < num_palette; i++)
 
497
      {
 
498
         int ir, ig, ib;
 
499
         int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
 
500
         int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
 
501
         int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
 
502
 
 
503
         for (ir = 0; ir < num_red; ir++)
 
504
         {
 
505
            /* int dr = abs(ir - r); */
 
506
            int dr = ((ir > r) ? ir - r : r - ir);
 
507
            int index_r = (ir << (PNG_DITHER_BLUE_BITS +
 
508
                PNG_DITHER_GREEN_BITS));
 
509
 
 
510
            for (ig = 0; ig < num_green; ig++)
 
511
            {
 
512
               /* int dg = abs(ig - g); */
 
513
               int dg = ((ig > g) ? ig - g : g - ig);
 
514
               int dt = dr + dg;
 
515
               int dm = ((dr > dg) ? dr : dg);
 
516
               int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
 
517
 
 
518
               for (ib = 0; ib < num_blue; ib++)
 
519
               {
 
520
                  int d_index = index_g | ib;
 
521
                  /* int db = abs(ib - b); */
 
522
                  int db = ((ib > b) ? ib - b : b - ib);
 
523
                  int dmax = ((dm > db) ? dm : db);
 
524
                  int d = dmax + dt + db;
 
525
 
 
526
                  if (d < (int)distance[d_index])
 
527
                  {
 
528
                     distance[d_index] = (png_byte)d;
 
529
                     png_ptr->palette_lookup[d_index] = (png_byte)i;
 
530
                  }
 
531
               }
 
532
            }
 
533
         }
 
534
      }
 
535
 
 
536
      png_free(png_ptr, distance);
 
537
   }
 
538
}
 
539
#endif
 
540
 
 
541
#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
 
542
/* Transform the image from the file_gamma to the screen_gamma.  We
 
543
 * only do transformations on images where the file_gamma and screen_gamma
 
544
 * are not close reciprocals, otherwise it slows things down slightly, and
 
545
 * also needlessly introduces small errors.
 
546
 *
 
547
 * We will turn off gamma transformation later if no semitransparent entries
 
548
 * are present in the tRNS array for palette images.  We can't do it here
 
549
 * because we don't necessarily have the tRNS chunk yet.
 
550
 */
 
551
void PNGAPI
 
552
png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
 
553
{
 
554
   png_debug(1, "in png_set_gamma");
 
555
 
 
556
   if (png_ptr == NULL)
 
557
      return;
 
558
 
 
559
   if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
 
560
       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
 
561
       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
 
562
     png_ptr->transformations |= PNG_GAMMA;
 
563
   png_ptr->gamma = (float)file_gamma;
 
564
   png_ptr->screen_gamma = (float)scrn_gamma;
 
565
}
 
566
#endif
 
567
 
 
568
#ifdef PNG_READ_EXPAND_SUPPORTED
 
569
/* Expand paletted images to RGB, expand grayscale images of
 
570
 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
 
571
 * to alpha channels.
 
572
 */
 
573
void PNGAPI
 
574
png_set_expand(png_structp png_ptr)
 
575
{
 
576
   png_debug(1, "in png_set_expand");
 
577
 
 
578
   if (png_ptr == NULL)
 
579
      return;
 
580
 
 
581
   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 
582
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 
583
}
 
584
 
 
585
/* GRR 19990627:  the following three functions currently are identical
 
586
 *  to png_set_expand().  However, it is entirely reasonable that someone
 
587
 *  might wish to expand an indexed image to RGB but *not* expand a single,
 
588
 *  fully transparent palette entry to a full alpha channel--perhaps instead
 
589
 *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
 
590
 *  the transparent color with a particular RGB value, or drop tRNS entirely.
 
591
 *  IOW, a future version of the library may make the transformations flag
 
592
 *  a bit more fine-grained, with separate bits for each of these three
 
593
 *  functions.
 
594
 *
 
595
 *  More to the point, these functions make it obvious what libpng will be
 
596
 *  doing, whereas "expand" can (and does) mean any number of things.
 
597
 *
 
598
 *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
 
599
 *  to expand only the sample depth but not to expand the tRNS to alpha
 
600
 *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
 
601
 */
 
602
 
 
603
/* Expand paletted images to RGB. */
 
604
void PNGAPI
 
605
png_set_palette_to_rgb(png_structp png_ptr)
 
606
{
 
607
   png_debug(1, "in png_set_palette_to_rgb");
 
608
 
 
609
   if (png_ptr == NULL)
 
610
      return;
 
611
 
 
612
   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 
613
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 
614
}
 
615
 
 
616
#ifndef PNG_1_0_X
 
617
/* Expand grayscale images of less than 8-bit depth to 8 bits. */
 
618
void PNGAPI
 
619
png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
 
620
{
 
621
   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
 
622
 
 
623
   if (png_ptr == NULL)
 
624
      return;
 
625
 
 
626
   png_ptr->transformations |= PNG_EXPAND;
 
627
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 
628
}
 
629
#endif
 
630
 
 
631
#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
 
632
/* Expand grayscale images of less than 8-bit depth to 8 bits. */
 
633
/* Deprecated as of libpng-1.2.9 */
 
634
void PNGAPI
 
635
png_set_gray_1_2_4_to_8(png_structp png_ptr)
 
636
{
 
637
   png_debug(1, "in png_set_gray_1_2_4_to_8");
 
638
 
 
639
   if (png_ptr == NULL)
 
640
      return;
 
641
 
 
642
   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 
643
}
 
644
#endif
 
645
 
 
646
 
 
647
/* Expand tRNS chunks to alpha channels. */
 
648
void PNGAPI
 
649
png_set_tRNS_to_alpha(png_structp png_ptr)
 
650
{
 
651
   png_debug(1, "in png_set_tRNS_to_alpha");
 
652
 
 
653
   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
 
654
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 
655
}
 
656
#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
 
657
 
 
658
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
 
659
void PNGAPI
 
660
png_set_gray_to_rgb(png_structp png_ptr)
 
661
{
 
662
   png_debug(1, "in png_set_gray_to_rgb");
 
663
 
 
664
   png_ptr->transformations |= PNG_GRAY_TO_RGB;
 
665
   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 
666
}
 
667
#endif
 
668
 
 
669
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
 
670
#ifdef PNG_FLOATING_POINT_SUPPORTED
 
671
/* Convert a RGB image to a grayscale of the same width.  This allows us,
 
672
 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
 
673
 */
 
674
 
 
675
void PNGAPI
 
676
png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
 
677
   double green)
 
678
{
 
679
   int red_fixed, green_fixed;
 
680
   if (png_ptr == NULL)
 
681
      return;
 
682
   if (red > 21474.83647 || red < -21474.83648 ||
 
683
       green > 21474.83647 || green < -21474.83648)
 
684
   {
 
685
      png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
 
686
      red_fixed = -1;
 
687
      green_fixed = -1;
 
688
   }
 
689
   else
 
690
   {
 
691
      red_fixed = (int)((float)red*100000.0 + 0.5);
 
692
      green_fixed = (int)((float)green*100000.0 + 0.5);
 
693
   }
 
694
   png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
 
695
}
 
696
#endif
 
697
 
 
698
void PNGAPI
 
699
png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
 
700
   png_fixed_point red, png_fixed_point green)
 
701
{
 
702
   png_debug(1, "in png_set_rgb_to_gray");
 
703
 
 
704
   if (png_ptr == NULL)
 
705
      return;
 
706
 
 
707
   switch(error_action)
 
708
   {
 
709
      case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
 
710
              break;
 
711
 
 
712
      case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
 
713
              break;
 
714
 
 
715
      case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
 
716
   }
 
717
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 
718
#ifdef PNG_READ_EXPAND_SUPPORTED
 
719
      png_ptr->transformations |= PNG_EXPAND;
 
720
#else
 
721
   {
 
722
      png_warning(png_ptr,
 
723
        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
 
724
      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
 
725
   }
 
726
#endif
 
727
   {
 
728
      png_uint_16 red_int, green_int;
 
729
      if (red < 0 || green < 0)
 
730
      {
 
731
         red_int   =  6968; /* .212671 * 32768 + .5 */
 
732
         green_int = 23434; /* .715160 * 32768 + .5 */
 
733
      }
 
734
      else if (red + green < 100000L)
 
735
      {
 
736
         red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
 
737
         green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
 
738
      }
 
739
      else
 
740
      {
 
741
         png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
 
742
         red_int   =  6968;
 
743
         green_int = 23434;
 
744
      }
 
745
      png_ptr->rgb_to_gray_red_coeff   = red_int;
 
746
      png_ptr->rgb_to_gray_green_coeff = green_int;
 
747
      png_ptr->rgb_to_gray_blue_coeff  =
 
748
         (png_uint_16)(32768 - red_int - green_int);
 
749
   }
 
750
}
 
751
#endif
 
752
 
 
753
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
 
754
    defined(PNG_LEGACY_SUPPORTED) || \
 
755
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
 
756
void PNGAPI
 
757
png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
 
758
   read_user_transform_fn)
 
759
{
 
760
   png_debug(1, "in png_set_read_user_transform_fn");
 
761
 
 
762
   if (png_ptr == NULL)
 
763
      return;
 
764
 
 
765
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
 
766
   png_ptr->transformations |= PNG_USER_TRANSFORM;
 
767
   png_ptr->read_user_transform_fn = read_user_transform_fn;
 
768
#endif
 
769
#ifdef PNG_LEGACY_SUPPORTED
 
770
   if (read_user_transform_fn)
 
771
      png_warning(png_ptr,
 
772
        "This version of libpng does not support user transforms");
 
773
#endif
 
774
}
 
775
#endif
 
776
 
 
777
/* Initialize everything needed for the read.  This includes modifying
 
778
 * the palette.
 
779
 */
 
780
void /* PRIVATE */
 
781
png_init_read_transformations(png_structp png_ptr)
 
782
{
 
783
   png_debug(1, "in png_init_read_transformations");
 
784
 
 
785
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
786
  if (png_ptr != NULL)
 
787
#endif
 
788
  {
 
789
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
 
790
    defined(PNG_READ_SHIFT_SUPPORTED) || \
 
791
    defined(PNG_READ_GAMMA_SUPPORTED)
 
792
   int color_type = png_ptr->color_type;
 
793
#endif
 
794
 
 
795
#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
 
796
 
 
797
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
 
798
   /* Detect gray background and attempt to enable optimization
 
799
    * for gray --> RGB case
 
800
    *
 
801
    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
 
802
    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
 
803
    * background color might actually be gray yet not be flagged as such.
 
804
    * This is not a problem for the current code, which uses
 
805
    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
 
806
    * png_do_gray_to_rgb() transformation.
 
807
    */
 
808
   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
 
809
       !(color_type & PNG_COLOR_MASK_COLOR))
 
810
   {
 
811
          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
 
812
   } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
 
813
              !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
 
814
              (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
 
815
              png_ptr->background.red == png_ptr->background.green &&
 
816
              png_ptr->background.red == png_ptr->background.blue)
 
817
   {
 
818
          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
 
819
          png_ptr->background.gray = png_ptr->background.red;
 
820
   }
 
821
#endif
 
822
 
 
823
   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
 
824
       (png_ptr->transformations & PNG_EXPAND))
 
825
   {
 
826
      if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
 
827
      {
 
828
         /* Expand background and tRNS chunks */
 
829
         switch (png_ptr->bit_depth)
 
830
         {
 
831
            case 1:
 
832
               png_ptr->background.gray *= (png_uint_16)0xff;
 
833
               png_ptr->background.red = png_ptr->background.green
 
834
                 =  png_ptr->background.blue = png_ptr->background.gray;
 
835
               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
 
836
               {
 
837
                 png_ptr->trans_values.gray *= (png_uint_16)0xff;
 
838
                 png_ptr->trans_values.red = png_ptr->trans_values.green
 
839
                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
 
840
               }
 
841
               break;
 
842
 
 
843
            case 2:
 
844
               png_ptr->background.gray *= (png_uint_16)0x55;
 
845
               png_ptr->background.red = png_ptr->background.green
 
846
                 = png_ptr->background.blue = png_ptr->background.gray;
 
847
               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
 
848
               {
 
849
                 png_ptr->trans_values.gray *= (png_uint_16)0x55;
 
850
                 png_ptr->trans_values.red = png_ptr->trans_values.green
 
851
                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
 
852
               }
 
853
               break;
 
854
 
 
855
            case 4:
 
856
               png_ptr->background.gray *= (png_uint_16)0x11;
 
857
               png_ptr->background.red = png_ptr->background.green
 
858
                 = png_ptr->background.blue = png_ptr->background.gray;
 
859
               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
 
860
               {
 
861
                 png_ptr->trans_values.gray *= (png_uint_16)0x11;
 
862
                 png_ptr->trans_values.red = png_ptr->trans_values.green
 
863
                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
 
864
               }
 
865
               break;
 
866
 
 
867
            case 8:
 
868
 
 
869
            case 16:
 
870
               png_ptr->background.red = png_ptr->background.green
 
871
                 = png_ptr->background.blue = png_ptr->background.gray;
 
872
               break;
 
873
         }
 
874
      }
 
875
      else if (color_type == PNG_COLOR_TYPE_PALETTE)
 
876
      {
 
877
         png_ptr->background.red   =
 
878
            png_ptr->palette[png_ptr->background.index].red;
 
879
         png_ptr->background.green =
 
880
            png_ptr->palette[png_ptr->background.index].green;
 
881
         png_ptr->background.blue  =
 
882
            png_ptr->palette[png_ptr->background.index].blue;
 
883
 
 
884
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
 
885
        if (png_ptr->transformations & PNG_INVERT_ALPHA)
 
886
        {
 
887
#ifdef PNG_READ_EXPAND_SUPPORTED
 
888
           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
 
889
#endif
 
890
           {
 
891
           /* Invert the alpha channel (in tRNS) unless the pixels are
 
892
            * going to be expanded, in which case leave it for later
 
893
            */
 
894
              int i, istop;
 
895
              istop=(int)png_ptr->num_trans;
 
896
              for (i=0; i<istop; i++)
 
897
                 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
 
898
           }
 
899
        }
 
900
#endif
 
901
 
 
902
      }
 
903
   }
 
904
#endif
 
905
 
 
906
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
 
907
   png_ptr->background_1 = png_ptr->background;
 
908
#endif
 
909
#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
 
910
 
 
911
   if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
 
912
       && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
 
913
         < PNG_GAMMA_THRESHOLD))
 
914
   {
 
915
    int i, k;
 
916
    k=0;
 
917
    for (i=0; i<png_ptr->num_trans; i++)
 
918
    {
 
919
      if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
 
920
        k=1; /* Partial transparency is present */
 
921
    }
 
922
    if (k == 0)
 
923
      png_ptr->transformations &= ~PNG_GAMMA;
 
924
   }
 
925
 
 
926
   if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
 
927
        png_ptr->gamma != 0.0)
 
928
   {
 
929
      png_build_gamma_table(png_ptr);
 
930
 
 
931
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
932
      if (png_ptr->transformations & PNG_BACKGROUND)
 
933
      {
 
934
         if (color_type == PNG_COLOR_TYPE_PALETTE)
 
935
         {
 
936
           /* Could skip if no transparency */
 
937
            png_color back, back_1;
 
938
            png_colorp palette = png_ptr->palette;
 
939
            int num_palette = png_ptr->num_palette;
 
940
            int i;
 
941
            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
 
942
            {
 
943
               back.red = png_ptr->gamma_table[png_ptr->background.red];
 
944
               back.green = png_ptr->gamma_table[png_ptr->background.green];
 
945
               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
 
946
 
 
947
               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
 
948
               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
 
949
               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
 
950
            }
 
951
            else
 
952
            {
 
953
               double g, gs;
 
954
 
 
955
               switch (png_ptr->background_gamma_type)
 
956
               {
 
957
                  case PNG_BACKGROUND_GAMMA_SCREEN:
 
958
                     g = (png_ptr->screen_gamma);
 
959
                     gs = 1.0;
 
960
                     break;
 
961
 
 
962
                  case PNG_BACKGROUND_GAMMA_FILE:
 
963
                     g = 1.0 / (png_ptr->gamma);
 
964
                     gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
 
965
                     break;
 
966
 
 
967
                  case PNG_BACKGROUND_GAMMA_UNIQUE:
 
968
                     g = 1.0 / (png_ptr->background_gamma);
 
969
                     gs = 1.0 / (png_ptr->background_gamma *
 
970
                                 png_ptr->screen_gamma);
 
971
                     break;
 
972
                  default:
 
973
                     g = 1.0;    /* back_1 */
 
974
                     gs = 1.0;   /* back */
 
975
               }
 
976
 
 
977
               if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
 
978
               {
 
979
                  back.red   = (png_byte)png_ptr->background.red;
 
980
                  back.green = (png_byte)png_ptr->background.green;
 
981
                  back.blue  = (png_byte)png_ptr->background.blue;
 
982
               }
 
983
               else
 
984
               {
 
985
                  back.red = (png_byte)(pow(
 
986
                     (double)png_ptr->background.red/255, gs) * 255.0 + .5);
 
987
                  back.green = (png_byte)(pow(
 
988
                     (double)png_ptr->background.green/255, gs) * 255.0
 
989
                         + .5);
 
990
                  back.blue = (png_byte)(pow(
 
991
                     (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
 
992
               }
 
993
 
 
994
               back_1.red = (png_byte)(pow(
 
995
                  (double)png_ptr->background.red/255, g) * 255.0 + .5);
 
996
               back_1.green = (png_byte)(pow(
 
997
                  (double)png_ptr->background.green/255, g) * 255.0 + .5);
 
998
               back_1.blue = (png_byte)(pow(
 
999
                  (double)png_ptr->background.blue/255, g) * 255.0 + .5);
 
1000
            }
 
1001
            for (i = 0; i < num_palette; i++)
 
1002
            {
 
1003
               if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
 
1004
               {
 
1005
                  if (png_ptr->trans[i] == 0)
 
1006
                  {
 
1007
                     palette[i] = back;
 
1008
                  }
 
1009
                  else /* if (png_ptr->trans[i] != 0xff) */
 
1010
                  {
 
1011
                     png_byte v, w;
 
1012
 
 
1013
                     v = png_ptr->gamma_to_1[palette[i].red];
 
1014
                     png_composite(w, v, png_ptr->trans[i], back_1.red);
 
1015
                     palette[i].red = png_ptr->gamma_from_1[w];
 
1016
 
 
1017
                     v = png_ptr->gamma_to_1[palette[i].green];
 
1018
                     png_composite(w, v, png_ptr->trans[i], back_1.green);
 
1019
                     palette[i].green = png_ptr->gamma_from_1[w];
 
1020
 
 
1021
                     v = png_ptr->gamma_to_1[palette[i].blue];
 
1022
                     png_composite(w, v, png_ptr->trans[i], back_1.blue);
 
1023
                     palette[i].blue = png_ptr->gamma_from_1[w];
 
1024
                  }
 
1025
               }
 
1026
               else
 
1027
               {
 
1028
                  palette[i].red = png_ptr->gamma_table[palette[i].red];
 
1029
                  palette[i].green = png_ptr->gamma_table[palette[i].green];
 
1030
                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
 
1031
               }
 
1032
            }
 
1033
            /* Prevent the transformations being done again, and make sure
 
1034
             * that the now spurious alpha channel is stripped - the code
 
1035
             * has just reduced background composition and gamma correction
 
1036
             * to a simple alpha channel strip.
 
1037
             */
 
1038
            png_ptr->transformations &= ~PNG_BACKGROUND;
 
1039
            png_ptr->transformations &= ~PNG_GAMMA;
 
1040
            png_ptr->transformations |= PNG_STRIP_ALPHA;
 
1041
         }
 
1042
         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
 
1043
         else
 
1044
         /* color_type != PNG_COLOR_TYPE_PALETTE */
 
1045
         {
 
1046
            double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
 
1047
            double g = 1.0;
 
1048
            double gs = 1.0;
 
1049
 
 
1050
            switch (png_ptr->background_gamma_type)
 
1051
            {
 
1052
               case PNG_BACKGROUND_GAMMA_SCREEN:
 
1053
                  g = (png_ptr->screen_gamma);
 
1054
                  gs = 1.0;
 
1055
                  break;
 
1056
 
 
1057
               case PNG_BACKGROUND_GAMMA_FILE:
 
1058
                  g = 1.0 / (png_ptr->gamma);
 
1059
                  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
 
1060
                  break;
 
1061
 
 
1062
               case PNG_BACKGROUND_GAMMA_UNIQUE:
 
1063
                  g = 1.0 / (png_ptr->background_gamma);
 
1064
                  gs = 1.0 / (png_ptr->background_gamma *
 
1065
                     png_ptr->screen_gamma);
 
1066
                  break;
 
1067
            }
 
1068
 
 
1069
            png_ptr->background_1.gray = (png_uint_16)(pow(
 
1070
               (double)png_ptr->background.gray / m, g) * m + .5);
 
1071
            png_ptr->background.gray = (png_uint_16)(pow(
 
1072
               (double)png_ptr->background.gray / m, gs) * m + .5);
 
1073
 
 
1074
            if ((png_ptr->background.red != png_ptr->background.green) ||
 
1075
                (png_ptr->background.red != png_ptr->background.blue) ||
 
1076
                (png_ptr->background.red != png_ptr->background.gray))
 
1077
            {
 
1078
               /* RGB or RGBA with color background */
 
1079
               png_ptr->background_1.red = (png_uint_16)(pow(
 
1080
                  (double)png_ptr->background.red / m, g) * m + .5);
 
1081
               png_ptr->background_1.green = (png_uint_16)(pow(
 
1082
                  (double)png_ptr->background.green / m, g) * m + .5);
 
1083
               png_ptr->background_1.blue = (png_uint_16)(pow(
 
1084
                  (double)png_ptr->background.blue / m, g) * m + .5);
 
1085
               png_ptr->background.red = (png_uint_16)(pow(
 
1086
                  (double)png_ptr->background.red / m, gs) * m + .5);
 
1087
               png_ptr->background.green = (png_uint_16)(pow(
 
1088
                  (double)png_ptr->background.green / m, gs) * m + .5);
 
1089
               png_ptr->background.blue = (png_uint_16)(pow(
 
1090
                  (double)png_ptr->background.blue / m, gs) * m + .5);
 
1091
            }
 
1092
            else
 
1093
            {
 
1094
               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
 
1095
               png_ptr->background_1.red = png_ptr->background_1.green
 
1096
                 = png_ptr->background_1.blue = png_ptr->background_1.gray;
 
1097
               png_ptr->background.red = png_ptr->background.green
 
1098
                 = png_ptr->background.blue = png_ptr->background.gray;
 
1099
            }
 
1100
         }
 
1101
      }
 
1102
      else
 
1103
      /* Transformation does not include PNG_BACKGROUND */
 
1104
#endif /* PNG_READ_BACKGROUND_SUPPORTED */
 
1105
      if (color_type == PNG_COLOR_TYPE_PALETTE)
 
1106
      {
 
1107
         png_colorp palette = png_ptr->palette;
 
1108
         int num_palette = png_ptr->num_palette;
 
1109
         int i;
 
1110
 
 
1111
         for (i = 0; i < num_palette; i++)
 
1112
         {
 
1113
            palette[i].red = png_ptr->gamma_table[palette[i].red];
 
1114
            palette[i].green = png_ptr->gamma_table[palette[i].green];
 
1115
            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
 
1116
         }
 
1117
 
 
1118
         /* Done the gamma correction. */
 
1119
         png_ptr->transformations &= ~PNG_GAMMA;
 
1120
      }
 
1121
   }
 
1122
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
1123
   else
 
1124
#endif
 
1125
#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
 
1126
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
1127
   /* No GAMMA transformation */
 
1128
   if ((png_ptr->transformations & PNG_BACKGROUND) &&
 
1129
       (color_type == PNG_COLOR_TYPE_PALETTE))
 
1130
   {
 
1131
      int i;
 
1132
      int istop = (int)png_ptr->num_trans;
 
1133
      png_color back;
 
1134
      png_colorp palette = png_ptr->palette;
 
1135
 
 
1136
      back.red   = (png_byte)png_ptr->background.red;
 
1137
      back.green = (png_byte)png_ptr->background.green;
 
1138
      back.blue  = (png_byte)png_ptr->background.blue;
 
1139
 
 
1140
      for (i = 0; i < istop; i++)
 
1141
      {
 
1142
         if (png_ptr->trans[i] == 0)
 
1143
         {
 
1144
            palette[i] = back;
 
1145
         }
 
1146
         else if (png_ptr->trans[i] != 0xff)
 
1147
         {
 
1148
            /* The png_composite() macro is defined in png.h */
 
1149
            png_composite(palette[i].red, palette[i].red,
 
1150
               png_ptr->trans[i], back.red);
 
1151
            png_composite(palette[i].green, palette[i].green,
 
1152
               png_ptr->trans[i], back.green);
 
1153
            png_composite(palette[i].blue, palette[i].blue,
 
1154
               png_ptr->trans[i], back.blue);
 
1155
         }
 
1156
      }
 
1157
 
 
1158
      /* Handled alpha, still need to strip the channel. */
 
1159
      png_ptr->transformations &= ~PNG_BACKGROUND;
 
1160
      png_ptr->transformations |= PNG_STRIP_ALPHA;
 
1161
   }
 
1162
#endif /* PNG_READ_BACKGROUND_SUPPORTED */
 
1163
 
 
1164
#ifdef PNG_READ_SHIFT_SUPPORTED
 
1165
   if ((png_ptr->transformations & PNG_SHIFT) &&
 
1166
      (color_type == PNG_COLOR_TYPE_PALETTE))
 
1167
   {
 
1168
      png_uint_16 i;
 
1169
      png_uint_16 istop = png_ptr->num_palette;
 
1170
      int sr = 8 - png_ptr->sig_bit.red;
 
1171
      int sg = 8 - png_ptr->sig_bit.green;
 
1172
      int sb = 8 - png_ptr->sig_bit.blue;
 
1173
 
 
1174
      if (sr < 0 || sr > 8)
 
1175
         sr = 0;
 
1176
      if (sg < 0 || sg > 8)
 
1177
         sg = 0;
 
1178
      if (sb < 0 || sb > 8)
 
1179
         sb = 0;
 
1180
      for (i = 0; i < istop; i++)
 
1181
      {
 
1182
         png_ptr->palette[i].red >>= sr;
 
1183
         png_ptr->palette[i].green >>= sg;
 
1184
         png_ptr->palette[i].blue >>= sb;
 
1185
      }
 
1186
   }
 
1187
#endif  /* PNG_READ_SHIFT_SUPPORTED */
 
1188
 }
 
1189
#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
 
1190
 && !defined(PNG_READ_BACKGROUND_SUPPORTED)
 
1191
   if (png_ptr)
 
1192
      return;
 
1193
#endif
 
1194
}
 
1195
 
 
1196
/* Modify the info structure to reflect the transformations.  The
 
1197
 * info should be updated so a PNG file could be written with it,
 
1198
 * assuming the transformations result in valid PNG data.
 
1199
 */
 
1200
void /* PRIVATE */
 
1201
png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
 
1202
{
 
1203
   png_debug(1, "in png_read_transform_info");
 
1204
 
 
1205
#ifdef PNG_READ_EXPAND_SUPPORTED
 
1206
   if (png_ptr->transformations & PNG_EXPAND)
 
1207
   {
 
1208
      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 
1209
      {
 
1210
         if (png_ptr->num_trans)
 
1211
            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
 
1212
         else
 
1213
            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
 
1214
         info_ptr->bit_depth = 8;
 
1215
         info_ptr->num_trans = 0;
 
1216
      }
 
1217
      else
 
1218
      {
 
1219
         if (png_ptr->num_trans)
 
1220
         {
 
1221
            if (png_ptr->transformations & PNG_EXPAND_tRNS)
 
1222
              info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
 
1223
         }
 
1224
         if (info_ptr->bit_depth < 8)
 
1225
            info_ptr->bit_depth = 8;
 
1226
         info_ptr->num_trans = 0;
 
1227
      }
 
1228
   }
 
1229
#endif
 
1230
 
 
1231
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
1232
   if (png_ptr->transformations & PNG_BACKGROUND)
 
1233
   {
 
1234
      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
 
1235
      info_ptr->num_trans = 0;
 
1236
      info_ptr->background = png_ptr->background;
 
1237
   }
 
1238
#endif
 
1239
 
 
1240
#ifdef PNG_READ_GAMMA_SUPPORTED
 
1241
   if (png_ptr->transformations & PNG_GAMMA)
 
1242
   {
 
1243
#ifdef PNG_FLOATING_POINT_SUPPORTED
 
1244
      info_ptr->gamma = png_ptr->gamma;
 
1245
#endif
 
1246
#ifdef PNG_FIXED_POINT_SUPPORTED
 
1247
      info_ptr->int_gamma = png_ptr->int_gamma;
 
1248
#endif
 
1249
   }
 
1250
#endif
 
1251
 
 
1252
#ifdef PNG_READ_16_TO_8_SUPPORTED
 
1253
   if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
 
1254
      info_ptr->bit_depth = 8;
 
1255
#endif
 
1256
 
 
1257
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
 
1258
   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
 
1259
      info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
 
1260
#endif
 
1261
 
 
1262
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
 
1263
   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
 
1264
      info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
 
1265
#endif
 
1266
 
 
1267
#ifdef PNG_READ_DITHER_SUPPORTED
 
1268
   if (png_ptr->transformations & PNG_DITHER)
 
1269
   {
 
1270
      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
 
1271
          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
 
1272
          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
 
1273
      {
 
1274
         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
 
1275
      }
 
1276
   }
 
1277
#endif
 
1278
 
 
1279
#ifdef PNG_READ_PACK_SUPPORTED
 
1280
   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
 
1281
      info_ptr->bit_depth = 8;
 
1282
#endif
 
1283
 
 
1284
   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 
1285
      info_ptr->channels = 1;
 
1286
   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
 
1287
      info_ptr->channels = 3;
 
1288
   else
 
1289
      info_ptr->channels = 1;
 
1290
 
 
1291
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
 
1292
   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
 
1293
      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
 
1294
#endif
 
1295
 
 
1296
   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
 
1297
      info_ptr->channels++;
 
1298
 
 
1299
#ifdef PNG_READ_FILLER_SUPPORTED
 
1300
   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
 
1301
   if ((png_ptr->transformations & PNG_FILLER) &&
 
1302
       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
 
1303
       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
 
1304
   {
 
1305
      info_ptr->channels++;
 
1306
      /* If adding a true alpha channel not just filler */
 
1307
#ifndef PNG_1_0_X
 
1308
      if (png_ptr->transformations & PNG_ADD_ALPHA)
 
1309
        info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
 
1310
#endif
 
1311
   }
 
1312
#endif
 
1313
 
 
1314
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
 
1315
defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
 
1316
   if (png_ptr->transformations & PNG_USER_TRANSFORM)
 
1317
     {
 
1318
       if (info_ptr->bit_depth < png_ptr->user_transform_depth)
 
1319
         info_ptr->bit_depth = png_ptr->user_transform_depth;
 
1320
       if (info_ptr->channels < png_ptr->user_transform_channels)
 
1321
         info_ptr->channels = png_ptr->user_transform_channels;
 
1322
     }
 
1323
#endif
 
1324
 
 
1325
   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
 
1326
      info_ptr->bit_depth);
 
1327
 
 
1328
   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
 
1329
 
 
1330
#ifndef PNG_READ_EXPAND_SUPPORTED
 
1331
   if (png_ptr)
 
1332
      return;
 
1333
#endif
 
1334
}
 
1335
 
 
1336
/* Transform the row.  The order of transformations is significant,
 
1337
 * and is very touchy.  If you add a transformation, take care to
 
1338
 * decide how it fits in with the other transformations here.
 
1339
 */
 
1340
void /* PRIVATE */
 
1341
png_do_read_transformations(png_structp png_ptr)
 
1342
{
 
1343
   png_debug(1, "in png_do_read_transformations");
 
1344
 
 
1345
   if (png_ptr->row_buf == NULL)
 
1346
   {
 
1347
#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
 
1348
      char msg[50];
 
1349
 
 
1350
      png_snprintf2(msg, 50,
 
1351
         "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
 
1352
         png_ptr->pass);
 
1353
      png_error(png_ptr, msg);
 
1354
#else
 
1355
      png_error(png_ptr, "NULL row buffer");
 
1356
#endif
 
1357
   }
 
1358
#ifdef PNG_WARN_UNINITIALIZED_ROW
 
1359
   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
 
1360
      /* Application has failed to call either png_read_start_image()
 
1361
       * or png_read_update_info() after setting transforms that expand
 
1362
       * pixels.  This check added to libpng-1.2.19
 
1363
       */
 
1364
#if (PNG_WARN_UNINITIALIZED_ROW==1)
 
1365
      png_error(png_ptr, "Uninitialized row");
 
1366
#else
 
1367
      png_warning(png_ptr, "Uninitialized row");
 
1368
#endif
 
1369
#endif
 
1370
 
 
1371
#ifdef PNG_READ_EXPAND_SUPPORTED
 
1372
   if (png_ptr->transformations & PNG_EXPAND)
 
1373
   {
 
1374
      if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
 
1375
      {
 
1376
         png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1377
            png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
 
1378
      }
 
1379
      else
 
1380
      {
 
1381
         if (png_ptr->num_trans &&
 
1382
             (png_ptr->transformations & PNG_EXPAND_tRNS))
 
1383
            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1384
               &(png_ptr->trans_values));
 
1385
         else
 
1386
            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1387
               NULL);
 
1388
      }
 
1389
   }
 
1390
#endif
 
1391
 
 
1392
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
 
1393
   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
 
1394
      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1395
         PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
 
1396
#endif
 
1397
 
 
1398
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
 
1399
   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
 
1400
   {
 
1401
      int rgb_error =
 
1402
         png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info),
 
1403
             png_ptr->row_buf + 1);
 
1404
      if (rgb_error)
 
1405
      {
 
1406
         png_ptr->rgb_to_gray_status=1;
 
1407
         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
 
1408
             PNG_RGB_TO_GRAY_WARN)
 
1409
            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
 
1410
         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
 
1411
             PNG_RGB_TO_GRAY_ERR)
 
1412
            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
 
1413
      }
 
1414
   }
 
1415
#endif
 
1416
 
 
1417
/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
 
1418
 *
 
1419
 *   In most cases, the "simple transparency" should be done prior to doing
 
1420
 *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
 
1421
 *   pixel is transparent.  You would also need to make sure that the
 
1422
 *   transparency information is upgraded to RGB.
 
1423
 *
 
1424
 *   To summarize, the current flow is:
 
1425
 *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
 
1426
 *                                   with background "in place" if transparent,
 
1427
 *                                   convert to RGB if necessary
 
1428
 *   - Gray + alpha -> composite with gray background and remove alpha bytes,
 
1429
 *                                   convert to RGB if necessary
 
1430
 *
 
1431
 *   To support RGB backgrounds for gray images we need:
 
1432
 *   - Gray + simple transparency -> convert to RGB + simple transparency,
 
1433
 *                                   compare 3 or 6 bytes and composite with
 
1434
 *                                   background "in place" if transparent
 
1435
 *                                   (3x compare/pixel compared to doing
 
1436
 *                                   composite with gray bkgrnd)
 
1437
 *   - Gray + alpha -> convert to RGB + alpha, composite with background and
 
1438
 *                                   remove alpha bytes (3x float
 
1439
 *                                   operations/pixel compared with composite
 
1440
 *                                   on gray background)
 
1441
 *
 
1442
 *  Greg's change will do this.  The reason it wasn't done before is for
 
1443
 *  performance, as this increases the per-pixel operations.  If we would check
 
1444
 *  in advance if the background was gray or RGB, and position the gray-to-RGB
 
1445
 *  transform appropriately, then it would save a lot of work/time.
 
1446
 */
 
1447
 
 
1448
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
 
1449
   /* If gray -> RGB, do so now only if background is non-gray; else do later
 
1450
    * for performance reasons
 
1451
    */
 
1452
   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
 
1453
       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
 
1454
      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1455
#endif
 
1456
 
 
1457
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
1458
   if ((png_ptr->transformations & PNG_BACKGROUND) &&
 
1459
      ((png_ptr->num_trans != 0 ) ||
 
1460
      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
 
1461
      png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1462
         &(png_ptr->trans_values), &(png_ptr->background)
 
1463
#ifdef PNG_READ_GAMMA_SUPPORTED
 
1464
         , &(png_ptr->background_1),
 
1465
         png_ptr->gamma_table, png_ptr->gamma_from_1,
 
1466
         png_ptr->gamma_to_1, png_ptr->gamma_16_table,
 
1467
         png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
 
1468
         png_ptr->gamma_shift
 
1469
#endif
 
1470
);
 
1471
#endif
 
1472
 
 
1473
#ifdef PNG_READ_GAMMA_SUPPORTED
 
1474
   if ((png_ptr->transformations & PNG_GAMMA) &&
 
1475
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
1476
       !((png_ptr->transformations & PNG_BACKGROUND) &&
 
1477
       ((png_ptr->num_trans != 0) ||
 
1478
       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
 
1479
#endif
 
1480
       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
 
1481
      png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1482
          png_ptr->gamma_table, png_ptr->gamma_16_table,
 
1483
          png_ptr->gamma_shift);
 
1484
#endif
 
1485
 
 
1486
#ifdef PNG_READ_16_TO_8_SUPPORTED
 
1487
   if (png_ptr->transformations & PNG_16_TO_8)
 
1488
      png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1489
#endif
 
1490
 
 
1491
#ifdef PNG_READ_DITHER_SUPPORTED
 
1492
   if (png_ptr->transformations & PNG_DITHER)
 
1493
   {
 
1494
      png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1495
         png_ptr->palette_lookup, png_ptr->dither_index);
 
1496
      if (png_ptr->row_info.rowbytes == (png_uint_32)0)
 
1497
         png_error(png_ptr, "png_do_dither returned rowbytes=0");
 
1498
   }
 
1499
#endif
 
1500
 
 
1501
#ifdef PNG_READ_INVERT_SUPPORTED
 
1502
   if (png_ptr->transformations & PNG_INVERT_MONO)
 
1503
      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1504
#endif
 
1505
 
 
1506
#ifdef PNG_READ_SHIFT_SUPPORTED
 
1507
   if (png_ptr->transformations & PNG_SHIFT)
 
1508
      png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1509
         &(png_ptr->shift));
 
1510
#endif
 
1511
 
 
1512
#ifdef PNG_READ_PACK_SUPPORTED
 
1513
   if (png_ptr->transformations & PNG_PACK)
 
1514
      png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1515
#endif
 
1516
 
 
1517
#ifdef PNG_READ_BGR_SUPPORTED
 
1518
   if (png_ptr->transformations & PNG_BGR)
 
1519
      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1520
#endif
 
1521
 
 
1522
#ifdef PNG_READ_PACKSWAP_SUPPORTED
 
1523
   if (png_ptr->transformations & PNG_PACKSWAP)
 
1524
      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1525
#endif
 
1526
 
 
1527
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
 
1528
   /* If gray -> RGB, do so now only if we did not do so above */
 
1529
   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
 
1530
       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
 
1531
      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1532
#endif
 
1533
 
 
1534
#ifdef PNG_READ_FILLER_SUPPORTED
 
1535
   if (png_ptr->transformations & PNG_FILLER)
 
1536
      png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
 
1537
         (png_uint_32)png_ptr->filler, png_ptr->flags);
 
1538
#endif
 
1539
 
 
1540
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
 
1541
   if (png_ptr->transformations & PNG_INVERT_ALPHA)
 
1542
      png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1543
#endif
 
1544
 
 
1545
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
 
1546
   if (png_ptr->transformations & PNG_SWAP_ALPHA)
 
1547
      png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1548
#endif
 
1549
 
 
1550
#ifdef PNG_READ_SWAP_SUPPORTED
 
1551
   if (png_ptr->transformations & PNG_SWAP_BYTES)
 
1552
      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
 
1553
#endif
 
1554
 
 
1555
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
 
1556
   if (png_ptr->transformations & PNG_USER_TRANSFORM)
 
1557
    {
 
1558
      if (png_ptr->read_user_transform_fn != NULL)
 
1559
         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
 
1560
            (png_ptr,                    /* png_ptr */
 
1561
               &(png_ptr->row_info),     /* row_info: */
 
1562
               /*  png_uint_32 width;       width of row */
 
1563
               /*  png_uint_32 rowbytes;    number of bytes in row */
 
1564
               /*  png_byte color_type;     color type of pixels */
 
1565
               /*  png_byte bit_depth;      bit depth of samples */
 
1566
               /*  png_byte channels;       number of channels (1-4) */
 
1567
               /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
 
1568
               png_ptr->row_buf + 1);    /* start of pixel data for row */
 
1569
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
 
1570
      if (png_ptr->user_transform_depth)
 
1571
         png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
 
1572
      if (png_ptr->user_transform_channels)
 
1573
         png_ptr->row_info.channels = png_ptr->user_transform_channels;
 
1574
#endif
 
1575
      png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
 
1576
         png_ptr->row_info.channels);
 
1577
      png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
 
1578
         png_ptr->row_info.width);
 
1579
   }
 
1580
#endif
 
1581
 
 
1582
}
 
1583
 
 
1584
#ifdef PNG_READ_PACK_SUPPORTED
 
1585
/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
 
1586
 * without changing the actual values.  Thus, if you had a row with
 
1587
 * a bit depth of 1, you would end up with bytes that only contained
 
1588
 * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
 
1589
 * png_do_shift() after this.
 
1590
 */
 
1591
void /* PRIVATE */
 
1592
png_do_unpack(png_row_infop row_info, png_bytep row)
 
1593
{
 
1594
   png_debug(1, "in png_do_unpack");
 
1595
 
 
1596
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
1597
   if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
 
1598
#else
 
1599
   if (row_info->bit_depth < 8)
 
1600
#endif
 
1601
   {
 
1602
      png_uint_32 i;
 
1603
      png_uint_32 row_width=row_info->width;
 
1604
 
 
1605
      switch (row_info->bit_depth)
 
1606
      {
 
1607
         case 1:
 
1608
         {
 
1609
            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
 
1610
            png_bytep dp = row + (png_size_t)row_width - 1;
 
1611
            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
 
1612
            for (i = 0; i < row_width; i++)
 
1613
            {
 
1614
               *dp = (png_byte)((*sp >> shift) & 0x01);
 
1615
               if (shift == 7)
 
1616
               {
 
1617
                  shift = 0;
 
1618
                  sp--;
 
1619
               }
 
1620
               else
 
1621
                  shift++;
 
1622
 
 
1623
               dp--;
 
1624
            }
 
1625
            break;
 
1626
         }
 
1627
 
 
1628
         case 2:
 
1629
         {
 
1630
 
 
1631
            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
 
1632
            png_bytep dp = row + (png_size_t)row_width - 1;
 
1633
            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
 
1634
            for (i = 0; i < row_width; i++)
 
1635
            {
 
1636
               *dp = (png_byte)((*sp >> shift) & 0x03);
 
1637
               if (shift == 6)
 
1638
               {
 
1639
                  shift = 0;
 
1640
                  sp--;
 
1641
               }
 
1642
               else
 
1643
                  shift += 2;
 
1644
 
 
1645
               dp--;
 
1646
            }
 
1647
            break;
 
1648
         }
 
1649
 
 
1650
         case 4:
 
1651
         {
 
1652
            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
 
1653
            png_bytep dp = row + (png_size_t)row_width - 1;
 
1654
            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
 
1655
            for (i = 0; i < row_width; i++)
 
1656
            {
 
1657
               *dp = (png_byte)((*sp >> shift) & 0x0f);
 
1658
               if (shift == 4)
 
1659
               {
 
1660
                  shift = 0;
 
1661
                  sp--;
 
1662
               }
 
1663
               else
 
1664
                  shift = 4;
 
1665
 
 
1666
               dp--;
 
1667
            }
 
1668
            break;
 
1669
         }
 
1670
      }
 
1671
      row_info->bit_depth = 8;
 
1672
      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
 
1673
      row_info->rowbytes = row_width * row_info->channels;
 
1674
   }
 
1675
}
 
1676
#endif
 
1677
 
 
1678
#ifdef PNG_READ_SHIFT_SUPPORTED
 
1679
/* Reverse the effects of png_do_shift.  This routine merely shifts the
 
1680
 * pixels back to their significant bits values.  Thus, if you have
 
1681
 * a row of bit depth 8, but only 5 are significant, this will shift
 
1682
 * the values back to 0 through 31.
 
1683
 */
 
1684
void /* PRIVATE */
 
1685
png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
 
1686
{
 
1687
   png_debug(1, "in png_do_unshift");
 
1688
 
 
1689
   if (
 
1690
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
1691
       row != NULL && row_info != NULL && sig_bits != NULL &&
 
1692
#endif
 
1693
       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
 
1694
   {
 
1695
      int shift[4];
 
1696
      int channels = 0;
 
1697
      int c;
 
1698
      png_uint_16 value = 0;
 
1699
      png_uint_32 row_width = row_info->width;
 
1700
 
 
1701
      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
 
1702
      {
 
1703
         shift[channels++] = row_info->bit_depth - sig_bits->red;
 
1704
         shift[channels++] = row_info->bit_depth - sig_bits->green;
 
1705
         shift[channels++] = row_info->bit_depth - sig_bits->blue;
 
1706
      }
 
1707
      else
 
1708
      {
 
1709
         shift[channels++] = row_info->bit_depth - sig_bits->gray;
 
1710
      }
 
1711
      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
 
1712
      {
 
1713
         shift[channels++] = row_info->bit_depth - sig_bits->alpha;
 
1714
      }
 
1715
 
 
1716
      for (c = 0; c < channels; c++)
 
1717
      {
 
1718
         if (shift[c] <= 0)
 
1719
            shift[c] = 0;
 
1720
         else
 
1721
            value = 1;
 
1722
      }
 
1723
 
 
1724
      if (!value)
 
1725
         return;
 
1726
 
 
1727
      switch (row_info->bit_depth)
 
1728
      {
 
1729
         case 2:
 
1730
         {
 
1731
            png_bytep bp;
 
1732
            png_uint_32 i;
 
1733
            png_uint_32 istop = row_info->rowbytes;
 
1734
 
 
1735
            for (bp = row, i = 0; i < istop; i++)
 
1736
            {
 
1737
               *bp >>= 1;
 
1738
               *bp++ &= 0x55;
 
1739
            }
 
1740
            break;
 
1741
         }
 
1742
 
 
1743
         case 4:
 
1744
         {
 
1745
            png_bytep bp = row;
 
1746
            png_uint_32 i;
 
1747
            png_uint_32 istop = row_info->rowbytes;
 
1748
            png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
 
1749
               (png_byte)((int)0xf >> shift[0]));
 
1750
 
 
1751
            for (i = 0; i < istop; i++)
 
1752
            {
 
1753
               *bp >>= shift[0];
 
1754
               *bp++ &= mask;
 
1755
            }
 
1756
            break;
 
1757
         }
 
1758
 
 
1759
         case 8:
 
1760
         {
 
1761
            png_bytep bp = row;
 
1762
            png_uint_32 i;
 
1763
            png_uint_32 istop = row_width * channels;
 
1764
 
 
1765
            for (i = 0; i < istop; i++)
 
1766
            {
 
1767
               *bp++ >>= shift[i%channels];
 
1768
            }
 
1769
            break;
 
1770
         }
 
1771
 
 
1772
         case 16:
 
1773
         {
 
1774
            png_bytep bp = row;
 
1775
            png_uint_32 i;
 
1776
            png_uint_32 istop = channels * row_width;
 
1777
 
 
1778
            for (i = 0; i < istop; i++)
 
1779
            {
 
1780
               value = (png_uint_16)((*bp << 8) + *(bp + 1));
 
1781
               value >>= shift[i%channels];
 
1782
               *bp++ = (png_byte)(value >> 8);
 
1783
               *bp++ = (png_byte)(value & 0xff);
 
1784
            }
 
1785
            break;
 
1786
         }
 
1787
      }
 
1788
   }
 
1789
}
 
1790
#endif
 
1791
 
 
1792
#ifdef PNG_READ_16_TO_8_SUPPORTED
 
1793
/* Chop rows of bit depth 16 down to 8 */
 
1794
void /* PRIVATE */
 
1795
png_do_chop(png_row_infop row_info, png_bytep row)
 
1796
{
 
1797
   png_debug(1, "in png_do_chop");
 
1798
 
 
1799
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
1800
   if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
 
1801
#else
 
1802
   if (row_info->bit_depth == 16)
 
1803
#endif
 
1804
   {
 
1805
      png_bytep sp = row;
 
1806
      png_bytep dp = row;
 
1807
      png_uint_32 i;
 
1808
      png_uint_32 istop = row_info->width * row_info->channels;
 
1809
 
 
1810
      for (i = 0; i<istop; i++, sp += 2, dp++)
 
1811
      {
 
1812
#ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
 
1813
      /* This does a more accurate scaling of the 16-bit color
 
1814
       * value, rather than a simple low-byte truncation.
 
1815
       *
 
1816
       * What the ideal calculation should be:
 
1817
       *   *dp = (((((png_uint_32)(*sp) << 8) |
 
1818
       *          (png_uint_32)(*(sp + 1))) * 255 + 127)
 
1819
       *          / (png_uint_32)65535L;
 
1820
       *
 
1821
       * GRR: no, I think this is what it really should be:
 
1822
       *   *dp = (((((png_uint_32)(*sp) << 8) |
 
1823
       *           (png_uint_32)(*(sp + 1))) + 128L)
 
1824
       *           / (png_uint_32)257L;
 
1825
       *
 
1826
       * GRR: here's the exact calculation with shifts:
 
1827
       *   temp = (((png_uint_32)(*sp) << 8) |
 
1828
       *           (png_uint_32)(*(sp + 1))) + 128L;
 
1829
       *   *dp = (temp - (temp >> 8)) >> 8;
 
1830
       *
 
1831
       * Approximate calculation with shift/add instead of multiply/divide:
 
1832
       *   *dp = ((((png_uint_32)(*sp) << 8) |
 
1833
       *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
 
1834
       *
 
1835
       * What we actually do to avoid extra shifting and conversion:
 
1836
       */
 
1837
 
 
1838
         *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
 
1839
#else
 
1840
       /* Simply discard the low order byte */
 
1841
         *dp = *sp;
 
1842
#endif
 
1843
      }
 
1844
      row_info->bit_depth = 8;
 
1845
      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
 
1846
      row_info->rowbytes = row_info->width * row_info->channels;
 
1847
   }
 
1848
}
 
1849
#endif
 
1850
 
 
1851
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
 
1852
void /* PRIVATE */
 
1853
png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
 
1854
{
 
1855
   png_debug(1, "in png_do_read_swap_alpha");
 
1856
 
 
1857
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
1858
   if (row != NULL && row_info != NULL)
 
1859
#endif
 
1860
   {
 
1861
      png_uint_32 row_width = row_info->width;
 
1862
      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 
1863
      {
 
1864
         /* This converts from RGBA to ARGB */
 
1865
         if (row_info->bit_depth == 8)
 
1866
         {
 
1867
            png_bytep sp = row + row_info->rowbytes;
 
1868
            png_bytep dp = sp;
 
1869
            png_byte save;
 
1870
            png_uint_32 i;
 
1871
 
 
1872
            for (i = 0; i < row_width; i++)
 
1873
            {
 
1874
               save = *(--sp);
 
1875
               *(--dp) = *(--sp);
 
1876
               *(--dp) = *(--sp);
 
1877
               *(--dp) = *(--sp);
 
1878
               *(--dp) = save;
 
1879
            }
 
1880
         }
 
1881
         /* This converts from RRGGBBAA to AARRGGBB */
 
1882
         else
 
1883
         {
 
1884
            png_bytep sp = row + row_info->rowbytes;
 
1885
            png_bytep dp = sp;
 
1886
            png_byte save[2];
 
1887
            png_uint_32 i;
 
1888
 
 
1889
            for (i = 0; i < row_width; i++)
 
1890
            {
 
1891
               save[0] = *(--sp);
 
1892
               save[1] = *(--sp);
 
1893
               *(--dp) = *(--sp);
 
1894
               *(--dp) = *(--sp);
 
1895
               *(--dp) = *(--sp);
 
1896
               *(--dp) = *(--sp);
 
1897
               *(--dp) = *(--sp);
 
1898
               *(--dp) = *(--sp);
 
1899
               *(--dp) = save[0];
 
1900
               *(--dp) = save[1];
 
1901
            }
 
1902
         }
 
1903
      }
 
1904
      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 
1905
      {
 
1906
         /* This converts from GA to AG */
 
1907
         if (row_info->bit_depth == 8)
 
1908
         {
 
1909
            png_bytep sp = row + row_info->rowbytes;
 
1910
            png_bytep dp = sp;
 
1911
            png_byte save;
 
1912
            png_uint_32 i;
 
1913
 
 
1914
            for (i = 0; i < row_width; i++)
 
1915
            {
 
1916
               save = *(--sp);
 
1917
               *(--dp) = *(--sp);
 
1918
               *(--dp) = save;
 
1919
            }
 
1920
         }
 
1921
         /* This converts from GGAA to AAGG */
 
1922
         else
 
1923
         {
 
1924
            png_bytep sp = row + row_info->rowbytes;
 
1925
            png_bytep dp = sp;
 
1926
            png_byte save[2];
 
1927
            png_uint_32 i;
 
1928
 
 
1929
            for (i = 0; i < row_width; i++)
 
1930
            {
 
1931
               save[0] = *(--sp);
 
1932
               save[1] = *(--sp);
 
1933
               *(--dp) = *(--sp);
 
1934
               *(--dp) = *(--sp);
 
1935
               *(--dp) = save[0];
 
1936
               *(--dp) = save[1];
 
1937
            }
 
1938
         }
 
1939
      }
 
1940
   }
 
1941
}
 
1942
#endif
 
1943
 
 
1944
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
 
1945
void /* PRIVATE */
 
1946
png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
 
1947
{
 
1948
   png_debug(1, "in png_do_read_invert_alpha");
 
1949
 
 
1950
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
1951
   if (row != NULL && row_info != NULL)
 
1952
#endif
 
1953
   {
 
1954
      png_uint_32 row_width = row_info->width;
 
1955
      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 
1956
      {
 
1957
         /* This inverts the alpha channel in RGBA */
 
1958
         if (row_info->bit_depth == 8)
 
1959
         {
 
1960
            png_bytep sp = row + row_info->rowbytes;
 
1961
            png_bytep dp = sp;
 
1962
            png_uint_32 i;
 
1963
 
 
1964
            for (i = 0; i < row_width; i++)
 
1965
            {
 
1966
               *(--dp) = (png_byte)(255 - *(--sp));
 
1967
 
 
1968
/*             This does nothing:
 
1969
               *(--dp) = *(--sp);
 
1970
               *(--dp) = *(--sp);
 
1971
               *(--dp) = *(--sp);
 
1972
               We can replace it with:
 
1973
*/
 
1974
               sp-=3;
 
1975
               dp=sp;
 
1976
            }
 
1977
         }
 
1978
         /* This inverts the alpha channel in RRGGBBAA */
 
1979
         else
 
1980
         {
 
1981
            png_bytep sp = row + row_info->rowbytes;
 
1982
            png_bytep dp = sp;
 
1983
            png_uint_32 i;
 
1984
 
 
1985
            for (i = 0; i < row_width; i++)
 
1986
            {
 
1987
               *(--dp) = (png_byte)(255 - *(--sp));
 
1988
               *(--dp) = (png_byte)(255 - *(--sp));
 
1989
 
 
1990
/*             This does nothing:
 
1991
               *(--dp) = *(--sp);
 
1992
               *(--dp) = *(--sp);
 
1993
               *(--dp) = *(--sp);
 
1994
               *(--dp) = *(--sp);
 
1995
               *(--dp) = *(--sp);
 
1996
               *(--dp) = *(--sp);
 
1997
               We can replace it with:
 
1998
*/
 
1999
               sp-=6;
 
2000
               dp=sp;
 
2001
            }
 
2002
         }
 
2003
      }
 
2004
      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 
2005
      {
 
2006
         /* This inverts the alpha channel in GA */
 
2007
         if (row_info->bit_depth == 8)
 
2008
         {
 
2009
            png_bytep sp = row + row_info->rowbytes;
 
2010
            png_bytep dp = sp;
 
2011
            png_uint_32 i;
 
2012
 
 
2013
            for (i = 0; i < row_width; i++)
 
2014
            {
 
2015
               *(--dp) = (png_byte)(255 - *(--sp));
 
2016
               *(--dp) = *(--sp);
 
2017
            }
 
2018
         }
 
2019
         /* This inverts the alpha channel in GGAA */
 
2020
         else
 
2021
         {
 
2022
            png_bytep sp  = row + row_info->rowbytes;
 
2023
            png_bytep dp = sp;
 
2024
            png_uint_32 i;
 
2025
 
 
2026
            for (i = 0; i < row_width; i++)
 
2027
            {
 
2028
               *(--dp) = (png_byte)(255 - *(--sp));
 
2029
               *(--dp) = (png_byte)(255 - *(--sp));
 
2030
/*
 
2031
               *(--dp) = *(--sp);
 
2032
               *(--dp) = *(--sp);
 
2033
*/
 
2034
               sp-=2;
 
2035
               dp=sp;
 
2036
            }
 
2037
         }
 
2038
      }
 
2039
   }
 
2040
}
 
2041
#endif
 
2042
 
 
2043
#ifdef PNG_READ_FILLER_SUPPORTED
 
2044
/* Add filler channel if we have RGB color */
 
2045
void /* PRIVATE */
 
2046
png_do_read_filler(png_row_infop row_info, png_bytep row,
 
2047
   png_uint_32 filler, png_uint_32 flags)
 
2048
{
 
2049
   png_uint_32 i;
 
2050
   png_uint_32 row_width = row_info->width;
 
2051
 
 
2052
   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
 
2053
   png_byte lo_filler = (png_byte)(filler & 0xff);
 
2054
 
 
2055
   png_debug(1, "in png_do_read_filler");
 
2056
 
 
2057
   if (
 
2058
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
2059
       row != NULL  && row_info != NULL &&
 
2060
#endif
 
2061
       row_info->color_type == PNG_COLOR_TYPE_GRAY)
 
2062
   {
 
2063
      if (row_info->bit_depth == 8)
 
2064
      {
 
2065
         /* This changes the data from G to GX */
 
2066
         if (flags & PNG_FLAG_FILLER_AFTER)
 
2067
         {
 
2068
            png_bytep sp = row + (png_size_t)row_width;
 
2069
            png_bytep dp =  sp + (png_size_t)row_width;
 
2070
            for (i = 1; i < row_width; i++)
 
2071
            {
 
2072
               *(--dp) = lo_filler;
 
2073
               *(--dp) = *(--sp);
 
2074
            }
 
2075
            *(--dp) = lo_filler;
 
2076
            row_info->channels = 2;
 
2077
            row_info->pixel_depth = 16;
 
2078
            row_info->rowbytes = row_width * 2;
 
2079
         }
 
2080
      /* This changes the data from G to XG */
 
2081
         else
 
2082
         {
 
2083
            png_bytep sp = row + (png_size_t)row_width;
 
2084
            png_bytep dp = sp  + (png_size_t)row_width;
 
2085
            for (i = 0; i < row_width; i++)
 
2086
            {
 
2087
               *(--dp) = *(--sp);
 
2088
               *(--dp) = lo_filler;
 
2089
            }
 
2090
            row_info->channels = 2;
 
2091
            row_info->pixel_depth = 16;
 
2092
            row_info->rowbytes = row_width * 2;
 
2093
         }
 
2094
      }
 
2095
      else if (row_info->bit_depth == 16)
 
2096
      {
 
2097
         /* This changes the data from GG to GGXX */
 
2098
         if (flags & PNG_FLAG_FILLER_AFTER)
 
2099
         {
 
2100
            png_bytep sp = row + (png_size_t)row_width * 2;
 
2101
            png_bytep dp = sp  + (png_size_t)row_width * 2;
 
2102
            for (i = 1; i < row_width; i++)
 
2103
            {
 
2104
               *(--dp) = hi_filler;
 
2105
               *(--dp) = lo_filler;
 
2106
               *(--dp) = *(--sp);
 
2107
               *(--dp) = *(--sp);
 
2108
            }
 
2109
            *(--dp) = hi_filler;
 
2110
            *(--dp) = lo_filler;
 
2111
            row_info->channels = 2;
 
2112
            row_info->pixel_depth = 32;
 
2113
            row_info->rowbytes = row_width * 4;
 
2114
         }
 
2115
         /* This changes the data from GG to XXGG */
 
2116
         else
 
2117
         {
 
2118
            png_bytep sp = row + (png_size_t)row_width * 2;
 
2119
            png_bytep dp = sp  + (png_size_t)row_width * 2;
 
2120
            for (i = 0; i < row_width; i++)
 
2121
            {
 
2122
               *(--dp) = *(--sp);
 
2123
               *(--dp) = *(--sp);
 
2124
               *(--dp) = hi_filler;
 
2125
               *(--dp) = lo_filler;
 
2126
            }
 
2127
            row_info->channels = 2;
 
2128
            row_info->pixel_depth = 32;
 
2129
            row_info->rowbytes = row_width * 4;
 
2130
         }
 
2131
      }
 
2132
   } /* COLOR_TYPE == GRAY */
 
2133
   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 
2134
   {
 
2135
      if (row_info->bit_depth == 8)
 
2136
      {
 
2137
         /* This changes the data from RGB to RGBX */
 
2138
         if (flags & PNG_FLAG_FILLER_AFTER)
 
2139
         {
 
2140
            png_bytep sp = row + (png_size_t)row_width * 3;
 
2141
            png_bytep dp = sp  + (png_size_t)row_width;
 
2142
            for (i = 1; i < row_width; i++)
 
2143
            {
 
2144
               *(--dp) = lo_filler;
 
2145
               *(--dp) = *(--sp);
 
2146
               *(--dp) = *(--sp);
 
2147
               *(--dp) = *(--sp);
 
2148
            }
 
2149
            *(--dp) = lo_filler;
 
2150
            row_info->channels = 4;
 
2151
            row_info->pixel_depth = 32;
 
2152
            row_info->rowbytes = row_width * 4;
 
2153
         }
 
2154
      /* This changes the data from RGB to XRGB */
 
2155
         else
 
2156
         {
 
2157
            png_bytep sp = row + (png_size_t)row_width * 3;
 
2158
            png_bytep dp = sp + (png_size_t)row_width;
 
2159
            for (i = 0; i < row_width; i++)
 
2160
            {
 
2161
               *(--dp) = *(--sp);
 
2162
               *(--dp) = *(--sp);
 
2163
               *(--dp) = *(--sp);
 
2164
               *(--dp) = lo_filler;
 
2165
            }
 
2166
            row_info->channels = 4;
 
2167
            row_info->pixel_depth = 32;
 
2168
            row_info->rowbytes = row_width * 4;
 
2169
         }
 
2170
      }
 
2171
      else if (row_info->bit_depth == 16)
 
2172
      {
 
2173
         /* This changes the data from RRGGBB to RRGGBBXX */
 
2174
         if (flags & PNG_FLAG_FILLER_AFTER)
 
2175
         {
 
2176
            png_bytep sp = row + (png_size_t)row_width * 6;
 
2177
            png_bytep dp = sp  + (png_size_t)row_width * 2;
 
2178
            for (i = 1; i < row_width; i++)
 
2179
            {
 
2180
               *(--dp) = hi_filler;
 
2181
               *(--dp) = lo_filler;
 
2182
               *(--dp) = *(--sp);
 
2183
               *(--dp) = *(--sp);
 
2184
               *(--dp) = *(--sp);
 
2185
               *(--dp) = *(--sp);
 
2186
               *(--dp) = *(--sp);
 
2187
               *(--dp) = *(--sp);
 
2188
            }
 
2189
            *(--dp) = hi_filler;
 
2190
            *(--dp) = lo_filler;
 
2191
            row_info->channels = 4;
 
2192
            row_info->pixel_depth = 64;
 
2193
            row_info->rowbytes = row_width * 8;
 
2194
         }
 
2195
         /* This changes the data from RRGGBB to XXRRGGBB */
 
2196
         else
 
2197
         {
 
2198
            png_bytep sp = row + (png_size_t)row_width * 6;
 
2199
            png_bytep dp = sp  + (png_size_t)row_width * 2;
 
2200
            for (i = 0; i < row_width; i++)
 
2201
            {
 
2202
               *(--dp) = *(--sp);
 
2203
               *(--dp) = *(--sp);
 
2204
               *(--dp) = *(--sp);
 
2205
               *(--dp) = *(--sp);
 
2206
               *(--dp) = *(--sp);
 
2207
               *(--dp) = *(--sp);
 
2208
               *(--dp) = hi_filler;
 
2209
               *(--dp) = lo_filler;
 
2210
            }
 
2211
            row_info->channels = 4;
 
2212
            row_info->pixel_depth = 64;
 
2213
            row_info->rowbytes = row_width * 8;
 
2214
         }
 
2215
      }
 
2216
   } /* COLOR_TYPE == RGB */
 
2217
}
 
2218
#endif
 
2219
 
 
2220
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
 
2221
/* Expand grayscale files to RGB, with or without alpha */
 
2222
void /* PRIVATE */
 
2223
png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
 
2224
{
 
2225
   png_uint_32 i;
 
2226
   png_uint_32 row_width = row_info->width;
 
2227
 
 
2228
   png_debug(1, "in png_do_gray_to_rgb");
 
2229
 
 
2230
   if (row_info->bit_depth >= 8 &&
 
2231
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
2232
       row != NULL && row_info != NULL &&
 
2233
#endif
 
2234
      !(row_info->color_type & PNG_COLOR_MASK_COLOR))
 
2235
   {
 
2236
      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
 
2237
      {
 
2238
         if (row_info->bit_depth == 8)
 
2239
         {
 
2240
            png_bytep sp = row + (png_size_t)row_width - 1;
 
2241
            png_bytep dp = sp  + (png_size_t)row_width * 2;
 
2242
            for (i = 0; i < row_width; i++)
 
2243
            {
 
2244
               *(dp--) = *sp;
 
2245
               *(dp--) = *sp;
 
2246
               *(dp--) = *(sp--);
 
2247
            }
 
2248
         }
 
2249
         else
 
2250
         {
 
2251
            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
 
2252
            png_bytep dp = sp  + (png_size_t)row_width * 4;
 
2253
            for (i = 0; i < row_width; i++)
 
2254
            {
 
2255
               *(dp--) = *sp;
 
2256
               *(dp--) = *(sp - 1);
 
2257
               *(dp--) = *sp;
 
2258
               *(dp--) = *(sp - 1);
 
2259
               *(dp--) = *(sp--);
 
2260
               *(dp--) = *(sp--);
 
2261
            }
 
2262
         }
 
2263
      }
 
2264
      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 
2265
      {
 
2266
         if (row_info->bit_depth == 8)
 
2267
         {
 
2268
            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
 
2269
            png_bytep dp = sp  + (png_size_t)row_width * 2;
 
2270
            for (i = 0; i < row_width; i++)
 
2271
            {
 
2272
               *(dp--) = *(sp--);
 
2273
               *(dp--) = *sp;
 
2274
               *(dp--) = *sp;
 
2275
               *(dp--) = *(sp--);
 
2276
            }
 
2277
         }
 
2278
         else
 
2279
         {
 
2280
            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
 
2281
            png_bytep dp = sp  + (png_size_t)row_width * 4;
 
2282
            for (i = 0; i < row_width; i++)
 
2283
            {
 
2284
               *(dp--) = *(sp--);
 
2285
               *(dp--) = *(sp--);
 
2286
               *(dp--) = *sp;
 
2287
               *(dp--) = *(sp - 1);
 
2288
               *(dp--) = *sp;
 
2289
               *(dp--) = *(sp - 1);
 
2290
               *(dp--) = *(sp--);
 
2291
               *(dp--) = *(sp--);
 
2292
            }
 
2293
         }
 
2294
      }
 
2295
      row_info->channels += (png_byte)2;
 
2296
      row_info->color_type |= PNG_COLOR_MASK_COLOR;
 
2297
      row_info->pixel_depth = (png_byte)(row_info->channels *
 
2298
         row_info->bit_depth);
 
2299
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
 
2300
   }
 
2301
}
 
2302
#endif
 
2303
 
 
2304
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
 
2305
/* Reduce RGB files to grayscale, with or without alpha
 
2306
 * using the equation given in Poynton's ColorFAQ at
 
2307
 * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008)
 
2308
 * New link:
 
2309
 * <http://www.poynton.com/notes/colour_and_gamma/>
 
2310
 * Charles Poynton poynton at poynton.com
 
2311
 *
 
2312
 *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
 
2313
 *
 
2314
 *  We approximate this with
 
2315
 *
 
2316
 *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
 
2317
 *
 
2318
 *  which can be expressed with integers as
 
2319
 *
 
2320
 *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
 
2321
 *
 
2322
 *  The calculation is to be done in a linear colorspace.
 
2323
 *
 
2324
 *  Other integer coefficents can be used via png_set_rgb_to_gray().
 
2325
 */
 
2326
int /* PRIVATE */
 
2327
png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
 
2328
 
 
2329
{
 
2330
   png_uint_32 i;
 
2331
 
 
2332
   png_uint_32 row_width = row_info->width;
 
2333
   int rgb_error = 0;
 
2334
 
 
2335
   png_debug(1, "in png_do_rgb_to_gray");
 
2336
 
 
2337
   if (
 
2338
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
2339
       row != NULL && row_info != NULL &&
 
2340
#endif
 
2341
      (row_info->color_type & PNG_COLOR_MASK_COLOR))
 
2342
   {
 
2343
      png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
 
2344
      png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
 
2345
      png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
 
2346
 
 
2347
      if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 
2348
      {
 
2349
         if (row_info->bit_depth == 8)
 
2350
         {
 
2351
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
 
2352
            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
 
2353
            {
 
2354
               png_bytep sp = row;
 
2355
               png_bytep dp = row;
 
2356
 
 
2357
               for (i = 0; i < row_width; i++)
 
2358
               {
 
2359
                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
 
2360
                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
 
2361
                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
 
2362
                  if (red != green || red != blue)
 
2363
                  {
 
2364
                     rgb_error |= 1;
 
2365
                     *(dp++) = png_ptr->gamma_from_1[
 
2366
                       (rc*red + gc*green + bc*blue)>>15];
 
2367
                  }
 
2368
                  else
 
2369
                     *(dp++) = *(sp - 1);
 
2370
               }
 
2371
            }
 
2372
            else
 
2373
#endif
 
2374
            {
 
2375
               png_bytep sp = row;
 
2376
               png_bytep dp = row;
 
2377
               for (i = 0; i < row_width; i++)
 
2378
               {
 
2379
                  png_byte red   = *(sp++);
 
2380
                  png_byte green = *(sp++);
 
2381
                  png_byte blue  = *(sp++);
 
2382
                  if (red != green || red != blue)
 
2383
                  {
 
2384
                     rgb_error |= 1;
 
2385
                     *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
 
2386
                  }
 
2387
                  else
 
2388
                     *(dp++) = *(sp - 1);
 
2389
               }
 
2390
            }
 
2391
         }
 
2392
 
 
2393
         else /* RGB bit_depth == 16 */
 
2394
         {
 
2395
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
 
2396
            if (png_ptr->gamma_16_to_1 != NULL &&
 
2397
                png_ptr->gamma_16_from_1 != NULL)
 
2398
            {
 
2399
               png_bytep sp = row;
 
2400
               png_bytep dp = row;
 
2401
               for (i = 0; i < row_width; i++)
 
2402
               {
 
2403
                  png_uint_16 red, green, blue, w;
 
2404
 
 
2405
                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2406
                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2407
                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2408
 
 
2409
                  if (red == green && red == blue)
 
2410
                     w = red;
 
2411
                  else
 
2412
                  {
 
2413
                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
 
2414
                                  png_ptr->gamma_shift][red>>8];
 
2415
                     png_uint_16 green_1 =
 
2416
                         png_ptr->gamma_16_to_1[(green&0xff) >>
 
2417
                                  png_ptr->gamma_shift][green>>8];
 
2418
                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
 
2419
                                  png_ptr->gamma_shift][blue>>8];
 
2420
                     png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
 
2421
                                  + bc*blue_1)>>15);
 
2422
                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
 
2423
                         png_ptr->gamma_shift][gray16 >> 8];
 
2424
                     rgb_error |= 1;
 
2425
                  }
 
2426
 
 
2427
                  *(dp++) = (png_byte)((w>>8) & 0xff);
 
2428
                  *(dp++) = (png_byte)(w & 0xff);
 
2429
               }
 
2430
            }
 
2431
            else
 
2432
#endif
 
2433
            {
 
2434
               png_bytep sp = row;
 
2435
               png_bytep dp = row;
 
2436
               for (i = 0; i < row_width; i++)
 
2437
               {
 
2438
                  png_uint_16 red, green, blue, gray16;
 
2439
 
 
2440
                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2441
                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2442
                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2443
 
 
2444
                  if (red != green || red != blue)
 
2445
                     rgb_error |= 1;
 
2446
                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
 
2447
                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
 
2448
                  *(dp++) = (png_byte)(gray16 & 0xff);
 
2449
               }
 
2450
            }
 
2451
         }
 
2452
      }
 
2453
      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 
2454
      {
 
2455
         if (row_info->bit_depth == 8)
 
2456
         {
 
2457
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
 
2458
            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
 
2459
            {
 
2460
               png_bytep sp = row;
 
2461
               png_bytep dp = row;
 
2462
               for (i = 0; i < row_width; i++)
 
2463
               {
 
2464
                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
 
2465
                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
 
2466
                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
 
2467
                  if (red != green || red != blue)
 
2468
                     rgb_error |= 1;
 
2469
                  *(dp++) =  png_ptr->gamma_from_1
 
2470
                             [(rc*red + gc*green + bc*blue)>>15];
 
2471
                  *(dp++) = *(sp++);  /* alpha */
 
2472
               }
 
2473
            }
 
2474
            else
 
2475
#endif
 
2476
            {
 
2477
               png_bytep sp = row;
 
2478
               png_bytep dp = row;
 
2479
               for (i = 0; i < row_width; i++)
 
2480
               {
 
2481
                  png_byte red   = *(sp++);
 
2482
                  png_byte green = *(sp++);
 
2483
                  png_byte blue  = *(sp++);
 
2484
                  if (red != green || red != blue)
 
2485
                     rgb_error |= 1;
 
2486
                  *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
 
2487
                  *(dp++) = *(sp++);  /* alpha */
 
2488
               }
 
2489
            }
 
2490
         }
 
2491
         else /* RGBA bit_depth == 16 */
 
2492
         {
 
2493
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
 
2494
            if (png_ptr->gamma_16_to_1 != NULL &&
 
2495
                png_ptr->gamma_16_from_1 != NULL)
 
2496
            {
 
2497
               png_bytep sp = row;
 
2498
               png_bytep dp = row;
 
2499
               for (i = 0; i < row_width; i++)
 
2500
               {
 
2501
                  png_uint_16 red, green, blue, w;
 
2502
 
 
2503
                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2504
                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2505
                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
 
2506
 
 
2507
                  if (red == green && red == blue)
 
2508
                     w = red;
 
2509
                  else
 
2510
                  {
 
2511
                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
 
2512
                         png_ptr->gamma_shift][red>>8];
 
2513
                     png_uint_16 green_1 =
 
2514
                         png_ptr->gamma_16_to_1[(green&0xff) >>
 
2515
                         png_ptr->gamma_shift][green>>8];
 
2516
                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
 
2517
                         png_ptr->gamma_shift][blue>>8];
 
2518
                     png_uint_16 gray16  = (png_uint_16)((rc * red_1
 
2519
                         + gc * green_1 + bc * blue_1)>>15);
 
2520
                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
 
2521
                         png_ptr->gamma_shift][gray16 >> 8];
 
2522
                     rgb_error |= 1;
 
2523
                  }
 
2524
 
 
2525
                  *(dp++) = (png_byte)((w>>8) & 0xff);
 
2526
                  *(dp++) = (png_byte)(w & 0xff);
 
2527
                  *(dp++) = *(sp++);  /* alpha */
 
2528
                  *(dp++) = *(sp++);
 
2529
               }
 
2530
            }
 
2531
            else
 
2532
#endif
 
2533
            {
 
2534
               png_bytep sp = row;
 
2535
               png_bytep dp = row;
 
2536
               for (i = 0; i < row_width; i++)
 
2537
               {
 
2538
                  png_uint_16 red, green, blue, gray16;
 
2539
                  red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
 
2540
                  green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
 
2541
                  blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
 
2542
                  if (red != green || red != blue)
 
2543
                     rgb_error |= 1;
 
2544
                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
 
2545
                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
 
2546
                  *(dp++) = (png_byte)(gray16 & 0xff);
 
2547
                  *(dp++) = *(sp++);  /* alpha */
 
2548
                  *(dp++) = *(sp++);
 
2549
               }
 
2550
            }
 
2551
         }
 
2552
      }
 
2553
   row_info->channels -= (png_byte)2;
 
2554
      row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
 
2555
      row_info->pixel_depth = (png_byte)(row_info->channels *
 
2556
         row_info->bit_depth);
 
2557
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
 
2558
   }
 
2559
   return rgb_error;
 
2560
}
 
2561
#endif
 
2562
 
 
2563
/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
 
2564
 * large of png_color.  This lets grayscale images be treated as
 
2565
 * paletted.  Most useful for gamma correction and simplification
 
2566
 * of code.
 
2567
 */
 
2568
void PNGAPI
 
2569
png_build_grayscale_palette(int bit_depth, png_colorp palette)
 
2570
{
 
2571
   int num_palette;
 
2572
   int color_inc;
 
2573
   int i;
 
2574
   int v;
 
2575
 
 
2576
   png_debug(1, "in png_do_build_grayscale_palette");
 
2577
 
 
2578
   if (palette == NULL)
 
2579
      return;
 
2580
 
 
2581
   switch (bit_depth)
 
2582
   {
 
2583
      case 1:
 
2584
         num_palette = 2;
 
2585
         color_inc = 0xff;
 
2586
         break;
 
2587
 
 
2588
      case 2:
 
2589
         num_palette = 4;
 
2590
         color_inc = 0x55;
 
2591
         break;
 
2592
 
 
2593
      case 4:
 
2594
         num_palette = 16;
 
2595
         color_inc = 0x11;
 
2596
         break;
 
2597
 
 
2598
      case 8:
 
2599
         num_palette = 256;
 
2600
         color_inc = 1;
 
2601
         break;
 
2602
 
 
2603
      default:
 
2604
         num_palette = 0;
 
2605
         color_inc = 0;
 
2606
         break;
 
2607
   }
 
2608
 
 
2609
   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
 
2610
   {
 
2611
      palette[i].red = (png_byte)v;
 
2612
      palette[i].green = (png_byte)v;
 
2613
      palette[i].blue = (png_byte)v;
 
2614
   }
 
2615
}
 
2616
 
 
2617
/* This function is currently unused.  Do we really need it? */
 
2618
#if defined(PNG_READ_DITHER_SUPPORTED) && \
 
2619
  defined(PNG_CORRECT_PALETTE_SUPPORTED)
 
2620
void /* PRIVATE */
 
2621
png_correct_palette(png_structp png_ptr, png_colorp palette,
 
2622
   int num_palette)
 
2623
{
 
2624
   png_debug(1, "in png_correct_palette");
 
2625
 
 
2626
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
 
2627
    defined(PNG_READ_GAMMA_SUPPORTED) && \
 
2628
  defined(PNG_FLOATING_POINT_SUPPORTED)
 
2629
   if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
 
2630
   {
 
2631
      png_color back, back_1;
 
2632
 
 
2633
      if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
 
2634
      {
 
2635
         back.red = png_ptr->gamma_table[png_ptr->background.red];
 
2636
         back.green = png_ptr->gamma_table[png_ptr->background.green];
 
2637
         back.blue = png_ptr->gamma_table[png_ptr->background.blue];
 
2638
 
 
2639
         back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
 
2640
         back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
 
2641
         back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
 
2642
      }
 
2643
      else
 
2644
      {
 
2645
         double g;
 
2646
 
 
2647
         g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
 
2648
 
 
2649
         if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN
 
2650
             || fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
 
2651
         {
 
2652
            back.red = png_ptr->background.red;
 
2653
            back.green = png_ptr->background.green;
 
2654
            back.blue = png_ptr->background.blue;
 
2655
         }
 
2656
         else
 
2657
         {
 
2658
            back.red =
 
2659
               (png_byte)(pow((double)png_ptr->background.red/255, g) *
 
2660
                255.0 + 0.5);
 
2661
            back.green =
 
2662
               (png_byte)(pow((double)png_ptr->background.green/255, g) *
 
2663
                255.0 + 0.5);
 
2664
            back.blue =
 
2665
               (png_byte)(pow((double)png_ptr->background.blue/255, g) *
 
2666
                255.0 + 0.5);
 
2667
         }
 
2668
 
 
2669
         g = 1.0 / png_ptr->background_gamma;
 
2670
 
 
2671
         back_1.red =
 
2672
            (png_byte)(pow((double)png_ptr->background.red/255, g) *
 
2673
             255.0 + 0.5);
 
2674
         back_1.green =
 
2675
            (png_byte)(pow((double)png_ptr->background.green/255, g) *
 
2676
             255.0 + 0.5);
 
2677
         back_1.blue =
 
2678
            (png_byte)(pow((double)png_ptr->background.blue/255, g) *
 
2679
             255.0 + 0.5);
 
2680
      }
 
2681
 
 
2682
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 
2683
      {
 
2684
         png_uint_32 i;
 
2685
 
 
2686
         for (i = 0; i < (png_uint_32)num_palette; i++)
 
2687
         {
 
2688
            if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
 
2689
            {
 
2690
               palette[i] = back;
 
2691
            }
 
2692
            else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
 
2693
            {
 
2694
               png_byte v, w;
 
2695
 
 
2696
               v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
 
2697
               png_composite(w, v, png_ptr->trans[i], back_1.red);
 
2698
               palette[i].red = png_ptr->gamma_from_1[w];
 
2699
 
 
2700
               v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
 
2701
               png_composite(w, v, png_ptr->trans[i], back_1.green);
 
2702
               palette[i].green = png_ptr->gamma_from_1[w];
 
2703
 
 
2704
               v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
 
2705
               png_composite(w, v, png_ptr->trans[i], back_1.blue);
 
2706
               palette[i].blue = png_ptr->gamma_from_1[w];
 
2707
            }
 
2708
            else
 
2709
            {
 
2710
               palette[i].red = png_ptr->gamma_table[palette[i].red];
 
2711
               palette[i].green = png_ptr->gamma_table[palette[i].green];
 
2712
               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
 
2713
            }
 
2714
         }
 
2715
      }
 
2716
      else
 
2717
      {
 
2718
         int i;
 
2719
 
 
2720
         for (i = 0; i < num_palette; i++)
 
2721
         {
 
2722
            if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
 
2723
            {
 
2724
               palette[i] = back;
 
2725
            }
 
2726
            else
 
2727
            {
 
2728
               palette[i].red = png_ptr->gamma_table[palette[i].red];
 
2729
               palette[i].green = png_ptr->gamma_table[palette[i].green];
 
2730
               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
 
2731
            }
 
2732
         }
 
2733
      }
 
2734
   }
 
2735
   else
 
2736
#endif
 
2737
#ifdef PNG_READ_GAMMA_SUPPORTED
 
2738
   if (png_ptr->transformations & PNG_GAMMA)
 
2739
   {
 
2740
      int i;
 
2741
 
 
2742
      for (i = 0; i < num_palette; i++)
 
2743
      {
 
2744
         palette[i].red = png_ptr->gamma_table[palette[i].red];
 
2745
         palette[i].green = png_ptr->gamma_table[palette[i].green];
 
2746
         palette[i].blue = png_ptr->gamma_table[palette[i].blue];
 
2747
      }
 
2748
   }
 
2749
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
2750
   else
 
2751
#endif
 
2752
#endif
 
2753
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
2754
   if (png_ptr->transformations & PNG_BACKGROUND)
 
2755
   {
 
2756
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 
2757
      {
 
2758
         png_color back;
 
2759
 
 
2760
         back.red   = (png_byte)png_ptr->background.red;
 
2761
         back.green = (png_byte)png_ptr->background.green;
 
2762
         back.blue  = (png_byte)png_ptr->background.blue;
 
2763
 
 
2764
         for (i = 0; i < (int)png_ptr->num_trans; i++)
 
2765
         {
 
2766
            if (png_ptr->trans[i] == 0)
 
2767
            {
 
2768
               palette[i].red = back.red;
 
2769
               palette[i].green = back.green;
 
2770
               palette[i].blue = back.blue;
 
2771
            }
 
2772
            else if (png_ptr->trans[i] != 0xff)
 
2773
            {
 
2774
               png_composite(palette[i].red, png_ptr->palette[i].red,
 
2775
                  png_ptr->trans[i], back.red);
 
2776
               png_composite(palette[i].green, png_ptr->palette[i].green,
 
2777
                  png_ptr->trans[i], back.green);
 
2778
               png_composite(palette[i].blue, png_ptr->palette[i].blue,
 
2779
                  png_ptr->trans[i], back.blue);
 
2780
            }
 
2781
         }
 
2782
      }
 
2783
      else /* Assume grayscale palette (what else could it be?) */
 
2784
      {
 
2785
         int i;
 
2786
 
 
2787
         for (i = 0; i < num_palette; i++)
 
2788
         {
 
2789
            if (i == (png_byte)png_ptr->trans_values.gray)
 
2790
            {
 
2791
               palette[i].red = (png_byte)png_ptr->background.red;
 
2792
               palette[i].green = (png_byte)png_ptr->background.green;
 
2793
               palette[i].blue = (png_byte)png_ptr->background.blue;
 
2794
            }
 
2795
         }
 
2796
      }
 
2797
   }
 
2798
#endif
 
2799
}
 
2800
#endif
 
2801
 
 
2802
#ifdef PNG_READ_BACKGROUND_SUPPORTED
 
2803
/* Replace any alpha or transparency with the supplied background color.
 
2804
 * "background" is already in the screen gamma, while "background_1" is
 
2805
 * at a gamma of 1.0.  Paletted files have already been taken care of.
 
2806
 */
 
2807
void /* PRIVATE */
 
2808
png_do_background(png_row_infop row_info, png_bytep row,
 
2809
   png_color_16p trans_values, png_color_16p background
 
2810
#ifdef PNG_READ_GAMMA_SUPPORTED
 
2811
   , png_color_16p background_1,
 
2812
   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
 
2813
   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
 
2814
   png_uint_16pp gamma_16_to_1, int gamma_shift
 
2815
#endif
 
2816
   )
 
2817
{
 
2818
   png_bytep sp, dp;
 
2819
   png_uint_32 i;
 
2820
   png_uint_32 row_width=row_info->width;
 
2821
   int shift;
 
2822
 
 
2823
   png_debug(1, "in png_do_background");
 
2824
 
 
2825
   if (background != NULL &&
 
2826
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
2827
       row != NULL && row_info != NULL &&
 
2828
#endif
 
2829
      (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
 
2830
      (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
 
2831
   {
 
2832
      switch (row_info->color_type)
 
2833
      {
 
2834
         case PNG_COLOR_TYPE_GRAY:
 
2835
         {
 
2836
            switch (row_info->bit_depth)
 
2837
            {
 
2838
               case 1:
 
2839
               {
 
2840
                  sp = row;
 
2841
                  shift = 7;
 
2842
                  for (i = 0; i < row_width; i++)
 
2843
                  {
 
2844
                     if ((png_uint_16)((*sp >> shift) & 0x01)
 
2845
                        == trans_values->gray)
 
2846
                     {
 
2847
                        *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
 
2848
                        *sp |= (png_byte)(background->gray << shift);
 
2849
                     }
 
2850
                     if (!shift)
 
2851
                     {
 
2852
                        shift = 7;
 
2853
                        sp++;
 
2854
                     }
 
2855
                     else
 
2856
                        shift--;
 
2857
                  }
 
2858
                  break;
 
2859
               }
 
2860
 
 
2861
               case 2:
 
2862
               {
 
2863
#ifdef PNG_READ_GAMMA_SUPPORTED
 
2864
                  if (gamma_table != NULL)
 
2865
                  {
 
2866
                     sp = row;
 
2867
                     shift = 6;
 
2868
                     for (i = 0; i < row_width; i++)
 
2869
                     {
 
2870
                        if ((png_uint_16)((*sp >> shift) & 0x03)
 
2871
                            == trans_values->gray)
 
2872
                        {
 
2873
                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
 
2874
                           *sp |= (png_byte)(background->gray << shift);
 
2875
                        }
 
2876
                        else
 
2877
                        {
 
2878
                           png_byte p = (png_byte)((*sp >> shift) & 0x03);
 
2879
                           png_byte g = (png_byte)((gamma_table [p | (p << 2) |
 
2880
                               (p << 4) | (p << 6)] >> 6) & 0x03);
 
2881
                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
 
2882
                           *sp |= (png_byte)(g << shift);
 
2883
                        }
 
2884
                        if (!shift)
 
2885
                        {
 
2886
                           shift = 6;
 
2887
                           sp++;
 
2888
                        }
 
2889
                        else
 
2890
                           shift -= 2;
 
2891
                     }
 
2892
                  }
 
2893
                  else
 
2894
#endif
 
2895
                  {
 
2896
                     sp = row;
 
2897
                     shift = 6;
 
2898
                     for (i = 0; i < row_width; i++)
 
2899
                     {
 
2900
                        if ((png_uint_16)((*sp >> shift) & 0x03)
 
2901
                            == trans_values->gray)
 
2902
                        {
 
2903
                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
 
2904
                           *sp |= (png_byte)(background->gray << shift);
 
2905
                        }
 
2906
                        if (!shift)
 
2907
                        {
 
2908
                           shift = 6;
 
2909
                           sp++;
 
2910
                        }
 
2911
                        else
 
2912
                           shift -= 2;
 
2913
                     }
 
2914
                  }
 
2915
                  break;
 
2916
               }
 
2917
 
 
2918
               case 4:
 
2919
               {
 
2920
#ifdef PNG_READ_GAMMA_SUPPORTED
 
2921
                  if (gamma_table != NULL)
 
2922
                  {
 
2923
                     sp = row;
 
2924
                     shift = 4;
 
2925
                     for (i = 0; i < row_width; i++)
 
2926
                     {
 
2927
                        if ((png_uint_16)((*sp >> shift) & 0x0f)
 
2928
                            == trans_values->gray)
 
2929
                        {
 
2930
                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
 
2931
                           *sp |= (png_byte)(background->gray << shift);
 
2932
                        }
 
2933
                        else
 
2934
                        {
 
2935
                           png_byte p = (png_byte)((*sp >> shift) & 0x0f);
 
2936
                           png_byte g = (png_byte)((gamma_table[p |
 
2937
                             (p << 4)] >> 4) & 0x0f);
 
2938
                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
 
2939
                           *sp |= (png_byte)(g << shift);
 
2940
                        }
 
2941
                        if (!shift)
 
2942
                        {
 
2943
                           shift = 4;
 
2944
                           sp++;
 
2945
                        }
 
2946
                        else
 
2947
                           shift -= 4;
 
2948
                     }
 
2949
                  }
 
2950
                  else
 
2951
#endif
 
2952
                  {
 
2953
                     sp = row;
 
2954
                     shift = 4;
 
2955
                     for (i = 0; i < row_width; i++)
 
2956
                     {
 
2957
                        if ((png_uint_16)((*sp >> shift) & 0x0f)
 
2958
                            == trans_values->gray)
 
2959
                        {
 
2960
                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
 
2961
                           *sp |= (png_byte)(background->gray << shift);
 
2962
                        }
 
2963
                        if (!shift)
 
2964
                        {
 
2965
                           shift = 4;
 
2966
                           sp++;
 
2967
                        }
 
2968
                        else
 
2969
                           shift -= 4;
 
2970
                     }
 
2971
                  }
 
2972
                  break;
 
2973
               }
 
2974
 
 
2975
               case 8:
 
2976
               {
 
2977
#ifdef PNG_READ_GAMMA_SUPPORTED
 
2978
                  if (gamma_table != NULL)
 
2979
                  {
 
2980
                     sp = row;
 
2981
                     for (i = 0; i < row_width; i++, sp++)
 
2982
                     {
 
2983
                        if (*sp == trans_values->gray)
 
2984
                        {
 
2985
                           *sp = (png_byte)background->gray;
 
2986
                        }
 
2987
                        else
 
2988
                        {
 
2989
                           *sp = gamma_table[*sp];
 
2990
                        }
 
2991
                     }
 
2992
                  }
 
2993
                  else
 
2994
#endif
 
2995
                  {
 
2996
                     sp = row;
 
2997
                     for (i = 0; i < row_width; i++, sp++)
 
2998
                     {
 
2999
                        if (*sp == trans_values->gray)
 
3000
                        {
 
3001
                           *sp = (png_byte)background->gray;
 
3002
                        }
 
3003
                     }
 
3004
                  }
 
3005
                  break;
 
3006
               }
 
3007
 
 
3008
               case 16:
 
3009
               {
 
3010
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3011
                  if (gamma_16 != NULL)
 
3012
                  {
 
3013
                     sp = row;
 
3014
                     for (i = 0; i < row_width; i++, sp += 2)
 
3015
                     {
 
3016
                        png_uint_16 v;
 
3017
 
 
3018
                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
3019
                        if (v == trans_values->gray)
 
3020
                        {
 
3021
                           /* Background is already in screen gamma */
 
3022
                           *sp = (png_byte)((background->gray >> 8) & 0xff);
 
3023
                           *(sp + 1) = (png_byte)(background->gray & 0xff);
 
3024
                        }
 
3025
                        else
 
3026
                        {
 
3027
                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
 
3028
                           *sp = (png_byte)((v >> 8) & 0xff);
 
3029
                           *(sp + 1) = (png_byte)(v & 0xff);
 
3030
                        }
 
3031
                     }
 
3032
                  }
 
3033
                  else
 
3034
#endif
 
3035
                  {
 
3036
                     sp = row;
 
3037
                     for (i = 0; i < row_width; i++, sp += 2)
 
3038
                     {
 
3039
                        png_uint_16 v;
 
3040
 
 
3041
                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
3042
                        if (v == trans_values->gray)
 
3043
                        {
 
3044
                           *sp = (png_byte)((background->gray >> 8) & 0xff);
 
3045
                           *(sp + 1) = (png_byte)(background->gray & 0xff);
 
3046
                        }
 
3047
                     }
 
3048
                  }
 
3049
                  break;
 
3050
               }
 
3051
            }
 
3052
            break;
 
3053
         }
 
3054
 
 
3055
         case PNG_COLOR_TYPE_RGB:
 
3056
         {
 
3057
            if (row_info->bit_depth == 8)
 
3058
            {
 
3059
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3060
               if (gamma_table != NULL)
 
3061
               {
 
3062
                  sp = row;
 
3063
                  for (i = 0; i < row_width; i++, sp += 3)
 
3064
                  {
 
3065
                     if (*sp == trans_values->red &&
 
3066
                        *(sp + 1) == trans_values->green &&
 
3067
                        *(sp + 2) == trans_values->blue)
 
3068
                     {
 
3069
                        *sp = (png_byte)background->red;
 
3070
                        *(sp + 1) = (png_byte)background->green;
 
3071
                        *(sp + 2) = (png_byte)background->blue;
 
3072
                     }
 
3073
                     else
 
3074
                     {
 
3075
                        *sp = gamma_table[*sp];
 
3076
                        *(sp + 1) = gamma_table[*(sp + 1)];
 
3077
                        *(sp + 2) = gamma_table[*(sp + 2)];
 
3078
                     }
 
3079
                  }
 
3080
               }
 
3081
               else
 
3082
#endif
 
3083
               {
 
3084
                  sp = row;
 
3085
                  for (i = 0; i < row_width; i++, sp += 3)
 
3086
                  {
 
3087
                     if (*sp == trans_values->red &&
 
3088
                        *(sp + 1) == trans_values->green &&
 
3089
                        *(sp + 2) == trans_values->blue)
 
3090
                     {
 
3091
                        *sp = (png_byte)background->red;
 
3092
                        *(sp + 1) = (png_byte)background->green;
 
3093
                        *(sp + 2) = (png_byte)background->blue;
 
3094
                     }
 
3095
                  }
 
3096
               }
 
3097
            }
 
3098
            else /* if (row_info->bit_depth == 16) */
 
3099
            {
 
3100
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3101
               if (gamma_16 != NULL)
 
3102
               {
 
3103
                  sp = row;
 
3104
                  for (i = 0; i < row_width; i++, sp += 6)
 
3105
                  {
 
3106
                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
3107
                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
 
3108
                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
 
3109
                     if (r == trans_values->red && g == trans_values->green &&
 
3110
                        b == trans_values->blue)
 
3111
                     {
 
3112
                        /* Background is already in screen gamma */
 
3113
                        *sp = (png_byte)((background->red >> 8) & 0xff);
 
3114
                        *(sp + 1) = (png_byte)(background->red & 0xff);
 
3115
                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
 
3116
                        *(sp + 3) = (png_byte)(background->green & 0xff);
 
3117
                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
 
3118
                        *(sp + 5) = (png_byte)(background->blue & 0xff);
 
3119
                     }
 
3120
                     else
 
3121
                     {
 
3122
                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
 
3123
                        *sp = (png_byte)((v >> 8) & 0xff);
 
3124
                        *(sp + 1) = (png_byte)(v & 0xff);
 
3125
                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
 
3126
                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
 
3127
                        *(sp + 3) = (png_byte)(v & 0xff);
 
3128
                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
 
3129
                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
 
3130
                        *(sp + 5) = (png_byte)(v & 0xff);
 
3131
                     }
 
3132
                  }
 
3133
               }
 
3134
               else
 
3135
#endif
 
3136
               {
 
3137
                  sp = row;
 
3138
                  for (i = 0; i < row_width; i++, sp += 6)
 
3139
                  {
 
3140
                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
 
3141
                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
 
3142
                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
 
3143
 
 
3144
                     if (r == trans_values->red && g == trans_values->green &&
 
3145
                        b == trans_values->blue)
 
3146
                     {
 
3147
                        *sp = (png_byte)((background->red >> 8) & 0xff);
 
3148
                        *(sp + 1) = (png_byte)(background->red & 0xff);
 
3149
                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
 
3150
                        *(sp + 3) = (png_byte)(background->green & 0xff);
 
3151
                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
 
3152
                        *(sp + 5) = (png_byte)(background->blue & 0xff);
 
3153
                     }
 
3154
                  }
 
3155
               }
 
3156
            }
 
3157
            break;
 
3158
         }
 
3159
 
 
3160
         case PNG_COLOR_TYPE_GRAY_ALPHA:
 
3161
         {
 
3162
            if (row_info->bit_depth == 8)
 
3163
            {
 
3164
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3165
               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
 
3166
                   gamma_table != NULL)
 
3167
               {
 
3168
                  sp = row;
 
3169
                  dp = row;
 
3170
                  for (i = 0; i < row_width; i++, sp += 2, dp++)
 
3171
                  {
 
3172
                     png_uint_16 a = *(sp + 1);
 
3173
 
 
3174
                     if (a == 0xff)
 
3175
                     {
 
3176
                        *dp = gamma_table[*sp];
 
3177
                     }
 
3178
                     else if (a == 0)
 
3179
                     {
 
3180
                        /* Background is already in screen gamma */
 
3181
                        *dp = (png_byte)background->gray;
 
3182
                     }
 
3183
                     else
 
3184
                     {
 
3185
                        png_byte v, w;
 
3186
 
 
3187
                        v = gamma_to_1[*sp];
 
3188
                        png_composite(w, v, a, background_1->gray);
 
3189
                        *dp = gamma_from_1[w];
 
3190
                     }
 
3191
                  }
 
3192
               }
 
3193
               else
 
3194
#endif
 
3195
               {
 
3196
                  sp = row;
 
3197
                  dp = row;
 
3198
                  for (i = 0; i < row_width; i++, sp += 2, dp++)
 
3199
                  {
 
3200
                     png_byte a = *(sp + 1);
 
3201
 
 
3202
                     if (a == 0xff)
 
3203
                     {
 
3204
                        *dp = *sp;
 
3205
                     }
 
3206
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3207
                     else if (a == 0)
 
3208
                     {
 
3209
                        *dp = (png_byte)background->gray;
 
3210
                     }
 
3211
                     else
 
3212
                     {
 
3213
                        png_composite(*dp, *sp, a, background_1->gray);
 
3214
                     }
 
3215
#else
 
3216
                     *dp = (png_byte)background->gray;
 
3217
#endif
 
3218
                  }
 
3219
               }
 
3220
            }
 
3221
            else /* if (png_ptr->bit_depth == 16) */
 
3222
            {
 
3223
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3224
               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
 
3225
                   gamma_16_to_1 != NULL)
 
3226
               {
 
3227
                  sp = row;
 
3228
                  dp = row;
 
3229
                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
 
3230
                  {
 
3231
                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
 
3232
 
 
3233
                     if (a == (png_uint_16)0xffff)
 
3234
                     {
 
3235
                        png_uint_16 v;
 
3236
 
 
3237
                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
 
3238
                        *dp = (png_byte)((v >> 8) & 0xff);
 
3239
                        *(dp + 1) = (png_byte)(v & 0xff);
 
3240
                     }
 
3241
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3242
                     else if (a == 0)
 
3243
#else
 
3244
                     else
 
3245
#endif
 
3246
                     {
 
3247
                        /* Background is already in screen gamma */
 
3248
                        *dp = (png_byte)((background->gray >> 8) & 0xff);
 
3249
                        *(dp + 1) = (png_byte)(background->gray & 0xff);
 
3250
                     }
 
3251
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3252
                     else
 
3253
                     {
 
3254
                        png_uint_16 g, v, w;
 
3255
 
 
3256
                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
 
3257
                        png_composite_16(v, g, a, background_1->gray);
 
3258
                        w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
 
3259
                        *dp = (png_byte)((w >> 8) & 0xff);
 
3260
                        *(dp + 1) = (png_byte)(w & 0xff);
 
3261
                     }
 
3262
#endif
 
3263
                  }
 
3264
               }
 
3265
               else
 
3266
#endif
 
3267
               {
 
3268
                  sp = row;
 
3269
                  dp = row;
 
3270
                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
 
3271
                  {
 
3272
                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
 
3273
                     if (a == (png_uint_16)0xffff)
 
3274
                     {
 
3275
                        png_memcpy(dp, sp, 2);
 
3276
                     }
 
3277
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3278
                     else if (a == 0)
 
3279
#else
 
3280
                     else
 
3281
#endif
 
3282
                     {
 
3283
                        *dp = (png_byte)((background->gray >> 8) & 0xff);
 
3284
                        *(dp + 1) = (png_byte)(background->gray & 0xff);
 
3285
                     }
 
3286
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3287
                     else
 
3288
                     {
 
3289
                        png_uint_16 g, v;
 
3290
 
 
3291
                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
3292
                        png_composite_16(v, g, a, background_1->gray);
 
3293
                        *dp = (png_byte)((v >> 8) & 0xff);
 
3294
                        *(dp + 1) = (png_byte)(v & 0xff);
 
3295
                     }
 
3296
#endif
 
3297
                  }
 
3298
               }
 
3299
            }
 
3300
            break;
 
3301
         }
 
3302
 
 
3303
         case PNG_COLOR_TYPE_RGB_ALPHA:
 
3304
         {
 
3305
            if (row_info->bit_depth == 8)
 
3306
            {
 
3307
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3308
               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
 
3309
                   gamma_table != NULL)
 
3310
               {
 
3311
                  sp = row;
 
3312
                  dp = row;
 
3313
                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
 
3314
                  {
 
3315
                     png_byte a = *(sp + 3);
 
3316
 
 
3317
                     if (a == 0xff)
 
3318
                     {
 
3319
                        *dp = gamma_table[*sp];
 
3320
                        *(dp + 1) = gamma_table[*(sp + 1)];
 
3321
                        *(dp + 2) = gamma_table[*(sp + 2)];
 
3322
                     }
 
3323
                     else if (a == 0)
 
3324
                     {
 
3325
                        /* Background is already in screen gamma */
 
3326
                        *dp = (png_byte)background->red;
 
3327
                        *(dp + 1) = (png_byte)background->green;
 
3328
                        *(dp + 2) = (png_byte)background->blue;
 
3329
                     }
 
3330
                     else
 
3331
                     {
 
3332
                        png_byte v, w;
 
3333
 
 
3334
                        v = gamma_to_1[*sp];
 
3335
                        png_composite(w, v, a, background_1->red);
 
3336
                        *dp = gamma_from_1[w];
 
3337
                        v = gamma_to_1[*(sp + 1)];
 
3338
                        png_composite(w, v, a, background_1->green);
 
3339
                        *(dp + 1) = gamma_from_1[w];
 
3340
                        v = gamma_to_1[*(sp + 2)];
 
3341
                        png_composite(w, v, a, background_1->blue);
 
3342
                        *(dp + 2) = gamma_from_1[w];
 
3343
                     }
 
3344
                  }
 
3345
               }
 
3346
               else
 
3347
#endif
 
3348
               {
 
3349
                  sp = row;
 
3350
                  dp = row;
 
3351
                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
 
3352
                  {
 
3353
                     png_byte a = *(sp + 3);
 
3354
 
 
3355
                     if (a == 0xff)
 
3356
                     {
 
3357
                        *dp = *sp;
 
3358
                        *(dp + 1) = *(sp + 1);
 
3359
                        *(dp + 2) = *(sp + 2);
 
3360
                     }
 
3361
                     else if (a == 0)
 
3362
                     {
 
3363
                        *dp = (png_byte)background->red;
 
3364
                        *(dp + 1) = (png_byte)background->green;
 
3365
                        *(dp + 2) = (png_byte)background->blue;
 
3366
                     }
 
3367
                     else
 
3368
                     {
 
3369
                        png_composite(*dp, *sp, a, background->red);
 
3370
                        png_composite(*(dp + 1), *(sp + 1), a,
 
3371
                           background->green);
 
3372
                        png_composite(*(dp + 2), *(sp + 2), a,
 
3373
                           background->blue);
 
3374
                     }
 
3375
                  }
 
3376
               }
 
3377
            }
 
3378
            else /* if (row_info->bit_depth == 16) */
 
3379
            {
 
3380
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3381
               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
 
3382
                   gamma_16_to_1 != NULL)
 
3383
               {
 
3384
                  sp = row;
 
3385
                  dp = row;
 
3386
                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
 
3387
                  {
 
3388
                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
 
3389
                         << 8) + (png_uint_16)(*(sp + 7)));
 
3390
                     if (a == (png_uint_16)0xffff)
 
3391
                     {
 
3392
                        png_uint_16 v;
 
3393
 
 
3394
                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
 
3395
                        *dp = (png_byte)((v >> 8) & 0xff);
 
3396
                        *(dp + 1) = (png_byte)(v & 0xff);
 
3397
                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
 
3398
                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
 
3399
                        *(dp + 3) = (png_byte)(v & 0xff);
 
3400
                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
 
3401
                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
 
3402
                        *(dp + 5) = (png_byte)(v & 0xff);
 
3403
                     }
 
3404
                     else if (a == 0)
 
3405
                     {
 
3406
                        /* Background is already in screen gamma */
 
3407
                        *dp = (png_byte)((background->red >> 8) & 0xff);
 
3408
                        *(dp + 1) = (png_byte)(background->red & 0xff);
 
3409
                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
 
3410
                        *(dp + 3) = (png_byte)(background->green & 0xff);
 
3411
                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
 
3412
                        *(dp + 5) = (png_byte)(background->blue & 0xff);
 
3413
                     }
 
3414
                     else
 
3415
                     {
 
3416
                        png_uint_16 v, w, x;
 
3417
 
 
3418
                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
 
3419
                        png_composite_16(w, v, a, background_1->red);
 
3420
                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
 
3421
                        *dp = (png_byte)((x >> 8) & 0xff);
 
3422
                        *(dp + 1) = (png_byte)(x & 0xff);
 
3423
                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
 
3424
                        png_composite_16(w, v, a, background_1->green);
 
3425
                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
 
3426
                        *(dp + 2) = (png_byte)((x >> 8) & 0xff);
 
3427
                        *(dp + 3) = (png_byte)(x & 0xff);
 
3428
                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
 
3429
                        png_composite_16(w, v, a, background_1->blue);
 
3430
                        x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
 
3431
                        *(dp + 4) = (png_byte)((x >> 8) & 0xff);
 
3432
                        *(dp + 5) = (png_byte)(x & 0xff);
 
3433
                     }
 
3434
                  }
 
3435
               }
 
3436
               else
 
3437
#endif
 
3438
               {
 
3439
                  sp = row;
 
3440
                  dp = row;
 
3441
                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
 
3442
                  {
 
3443
                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
 
3444
                        << 8) + (png_uint_16)(*(sp + 7)));
 
3445
                     if (a == (png_uint_16)0xffff)
 
3446
                     {
 
3447
                        png_memcpy(dp, sp, 6);
 
3448
                     }
 
3449
                     else if (a == 0)
 
3450
                     {
 
3451
                        *dp = (png_byte)((background->red >> 8) & 0xff);
 
3452
                        *(dp + 1) = (png_byte)(background->red & 0xff);
 
3453
                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
 
3454
                        *(dp + 3) = (png_byte)(background->green & 0xff);
 
3455
                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
 
3456
                        *(dp + 5) = (png_byte)(background->blue & 0xff);
 
3457
                     }
 
3458
                     else
 
3459
                     {
 
3460
                        png_uint_16 v;
 
3461
 
 
3462
                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
 
3463
                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
 
3464
                            + *(sp + 3));
 
3465
                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
 
3466
                            + *(sp + 5));
 
3467
 
 
3468
                        png_composite_16(v, r, a, background->red);
 
3469
                        *dp = (png_byte)((v >> 8) & 0xff);
 
3470
                        *(dp + 1) = (png_byte)(v & 0xff);
 
3471
                        png_composite_16(v, g, a, background->green);
 
3472
                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
 
3473
                        *(dp + 3) = (png_byte)(v & 0xff);
 
3474
                        png_composite_16(v, b, a, background->blue);
 
3475
                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
 
3476
                        *(dp + 5) = (png_byte)(v & 0xff);
 
3477
                     }
 
3478
                  }
 
3479
               }
 
3480
            }
 
3481
            break;
 
3482
         }
 
3483
      }
 
3484
 
 
3485
      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
 
3486
      {
 
3487
         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
 
3488
         row_info->channels--;
 
3489
         row_info->pixel_depth = (png_byte)(row_info->channels *
 
3490
            row_info->bit_depth);
 
3491
         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
 
3492
      }
 
3493
   }
 
3494
}
 
3495
#endif
 
3496
 
 
3497
#ifdef PNG_READ_GAMMA_SUPPORTED
 
3498
/* Gamma correct the image, avoiding the alpha channel.  Make sure
 
3499
 * you do this after you deal with the transparency issue on grayscale
 
3500
 * or RGB images. If your bit depth is 8, use gamma_table, if it
 
3501
 * is 16, use gamma_16_table and gamma_shift.  Build these with
 
3502
 * build_gamma_table().
 
3503
 */
 
3504
void /* PRIVATE */
 
3505
png_do_gamma(png_row_infop row_info, png_bytep row,
 
3506
   png_bytep gamma_table, png_uint_16pp gamma_16_table,
 
3507
   int gamma_shift)
 
3508
{
 
3509
   png_bytep sp;
 
3510
   png_uint_32 i;
 
3511
   png_uint_32 row_width=row_info->width;
 
3512
 
 
3513
   png_debug(1, "in png_do_gamma");
 
3514
 
 
3515
   if (
 
3516
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
3517
       row != NULL && row_info != NULL &&
 
3518
#endif
 
3519
       ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
 
3520
        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
 
3521
   {
 
3522
      switch (row_info->color_type)
 
3523
      {
 
3524
         case PNG_COLOR_TYPE_RGB:
 
3525
         {
 
3526
            if (row_info->bit_depth == 8)
 
3527
            {
 
3528
               sp = row;
 
3529
               for (i = 0; i < row_width; i++)
 
3530
               {
 
3531
                  *sp = gamma_table[*sp];
 
3532
                  sp++;
 
3533
                  *sp = gamma_table[*sp];
 
3534
                  sp++;
 
3535
                  *sp = gamma_table[*sp];
 
3536
                  sp++;
 
3537
               }
 
3538
            }
 
3539
            else /* if (row_info->bit_depth == 16) */
 
3540
            {
 
3541
               sp = row;
 
3542
               for (i = 0; i < row_width; i++)
 
3543
               {
 
3544
                  png_uint_16 v;
 
3545
 
 
3546
                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
 
3547
                  *sp = (png_byte)((v >> 8) & 0xff);
 
3548
                  *(sp + 1) = (png_byte)(v & 0xff);
 
3549
                  sp += 2;
 
3550
                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
 
3551
                  *sp = (png_byte)((v >> 8) & 0xff);
 
3552
                  *(sp + 1) = (png_byte)(v & 0xff);
 
3553
                  sp += 2;
 
3554
                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
 
3555
                  *sp = (png_byte)((v >> 8) & 0xff);
 
3556
                  *(sp + 1) = (png_byte)(v & 0xff);
 
3557
                  sp += 2;
 
3558
               }
 
3559
            }
 
3560
            break;
 
3561
         }
 
3562
 
 
3563
         case PNG_COLOR_TYPE_RGB_ALPHA:
 
3564
         {
 
3565
            if (row_info->bit_depth == 8)
 
3566
            {
 
3567
               sp = row;
 
3568
               for (i = 0; i < row_width; i++)
 
3569
               {
 
3570
                  *sp = gamma_table[*sp];
 
3571
                  sp++;
 
3572
                  *sp = gamma_table[*sp];
 
3573
                  sp++;
 
3574
                  *sp = gamma_table[*sp];
 
3575
                  sp++;
 
3576
                  sp++;
 
3577
               }
 
3578
            }
 
3579
            else /* if (row_info->bit_depth == 16) */
 
3580
            {
 
3581
               sp = row;
 
3582
               for (i = 0; i < row_width; i++)
 
3583
               {
 
3584
                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
 
3585
                  *sp = (png_byte)((v >> 8) & 0xff);
 
3586
                  *(sp + 1) = (png_byte)(v & 0xff);
 
3587
                  sp += 2;
 
3588
                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
 
3589
                  *sp = (png_byte)((v >> 8) & 0xff);
 
3590
                  *(sp + 1) = (png_byte)(v & 0xff);
 
3591
                  sp += 2;
 
3592
                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
 
3593
                  *sp = (png_byte)((v >> 8) & 0xff);
 
3594
                  *(sp + 1) = (png_byte)(v & 0xff);
 
3595
                  sp += 4;
 
3596
               }
 
3597
            }
 
3598
            break;
 
3599
         }
 
3600
 
 
3601
         case PNG_COLOR_TYPE_GRAY_ALPHA:
 
3602
         {
 
3603
            if (row_info->bit_depth == 8)
 
3604
            {
 
3605
               sp = row;
 
3606
               for (i = 0; i < row_width; i++)
 
3607
               {
 
3608
                  *sp = gamma_table[*sp];
 
3609
                  sp += 2;
 
3610
               }
 
3611
            }
 
3612
            else /* if (row_info->bit_depth == 16) */
 
3613
            {
 
3614
               sp = row;
 
3615
               for (i = 0; i < row_width; i++)
 
3616
               {
 
3617
                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
 
3618
                  *sp = (png_byte)((v >> 8) & 0xff);
 
3619
                  *(sp + 1) = (png_byte)(v & 0xff);
 
3620
                  sp += 4;
 
3621
               }
 
3622
            }
 
3623
            break;
 
3624
         }
 
3625
 
 
3626
         case PNG_COLOR_TYPE_GRAY:
 
3627
         {
 
3628
            if (row_info->bit_depth == 2)
 
3629
            {
 
3630
               sp = row;
 
3631
               for (i = 0; i < row_width; i += 4)
 
3632
               {
 
3633
                  int a = *sp & 0xc0;
 
3634
                  int b = *sp & 0x30;
 
3635
                  int c = *sp & 0x0c;
 
3636
                  int d = *sp & 0x03;
 
3637
 
 
3638
                  *sp = (png_byte)(
 
3639
                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
 
3640
                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
 
3641
                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
 
3642
                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
 
3643
                  sp++;
 
3644
               }
 
3645
            }
 
3646
 
 
3647
            if (row_info->bit_depth == 4)
 
3648
            {
 
3649
               sp = row;
 
3650
               for (i = 0; i < row_width; i += 2)
 
3651
               {
 
3652
                  int msb = *sp & 0xf0;
 
3653
                  int lsb = *sp & 0x0f;
 
3654
 
 
3655
                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
 
3656
                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
 
3657
                  sp++;
 
3658
               }
 
3659
            }
 
3660
 
 
3661
            else if (row_info->bit_depth == 8)
 
3662
            {
 
3663
               sp = row;
 
3664
               for (i = 0; i < row_width; i++)
 
3665
               {
 
3666
                  *sp = gamma_table[*sp];
 
3667
                  sp++;
 
3668
               }
 
3669
            }
 
3670
 
 
3671
            else if (row_info->bit_depth == 16)
 
3672
            {
 
3673
               sp = row;
 
3674
               for (i = 0; i < row_width; i++)
 
3675
               {
 
3676
                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
 
3677
                  *sp = (png_byte)((v >> 8) & 0xff);
 
3678
                  *(sp + 1) = (png_byte)(v & 0xff);
 
3679
                  sp += 2;
 
3680
               }
 
3681
            }
 
3682
            break;
 
3683
         }
 
3684
      }
 
3685
   }
 
3686
}
 
3687
#endif
 
3688
 
 
3689
#ifdef PNG_READ_EXPAND_SUPPORTED
 
3690
/* Expands a palette row to an RGB or RGBA row depending
 
3691
 * upon whether you supply trans and num_trans.
 
3692
 */
 
3693
void /* PRIVATE */
 
3694
png_do_expand_palette(png_row_infop row_info, png_bytep row,
 
3695
   png_colorp palette, png_bytep trans, int num_trans)
 
3696
{
 
3697
   int shift, value;
 
3698
   png_bytep sp, dp;
 
3699
   png_uint_32 i;
 
3700
   png_uint_32 row_width=row_info->width;
 
3701
 
 
3702
   png_debug(1, "in png_do_expand_palette");
 
3703
 
 
3704
   if (
 
3705
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
3706
       row != NULL && row_info != NULL &&
 
3707
#endif
 
3708
       row_info->color_type == PNG_COLOR_TYPE_PALETTE)
 
3709
   {
 
3710
      if (row_info->bit_depth < 8)
 
3711
      {
 
3712
         switch (row_info->bit_depth)
 
3713
         {
 
3714
            case 1:
 
3715
            {
 
3716
               sp = row + (png_size_t)((row_width - 1) >> 3);
 
3717
               dp = row + (png_size_t)row_width - 1;
 
3718
               shift = 7 - (int)((row_width + 7) & 0x07);
 
3719
               for (i = 0; i < row_width; i++)
 
3720
               {
 
3721
                  if ((*sp >> shift) & 0x01)
 
3722
                     *dp = 1;
 
3723
                  else
 
3724
                     *dp = 0;
 
3725
                  if (shift == 7)
 
3726
                  {
 
3727
                     shift = 0;
 
3728
                     sp--;
 
3729
                  }
 
3730
                  else
 
3731
                     shift++;
 
3732
 
 
3733
                  dp--;
 
3734
               }
 
3735
               break;
 
3736
            }
 
3737
 
 
3738
            case 2:
 
3739
            {
 
3740
               sp = row + (png_size_t)((row_width - 1) >> 2);
 
3741
               dp = row + (png_size_t)row_width - 1;
 
3742
               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
 
3743
               for (i = 0; i < row_width; i++)
 
3744
               {
 
3745
                  value = (*sp >> shift) & 0x03;
 
3746
                  *dp = (png_byte)value;
 
3747
                  if (shift == 6)
 
3748
                  {
 
3749
                     shift = 0;
 
3750
                     sp--;
 
3751
                  }
 
3752
                  else
 
3753
                     shift += 2;
 
3754
 
 
3755
                  dp--;
 
3756
               }
 
3757
               break;
 
3758
            }
 
3759
 
 
3760
            case 4:
 
3761
            {
 
3762
               sp = row + (png_size_t)((row_width - 1) >> 1);
 
3763
               dp = row + (png_size_t)row_width - 1;
 
3764
               shift = (int)((row_width & 0x01) << 2);
 
3765
               for (i = 0; i < row_width; i++)
 
3766
               {
 
3767
                  value = (*sp >> shift) & 0x0f;
 
3768
                  *dp = (png_byte)value;
 
3769
                  if (shift == 4)
 
3770
                  {
 
3771
                     shift = 0;
 
3772
                     sp--;
 
3773
                  }
 
3774
                  else
 
3775
                     shift += 4;
 
3776
 
 
3777
                  dp--;
 
3778
               }
 
3779
               break;
 
3780
            }
 
3781
         }
 
3782
         row_info->bit_depth = 8;
 
3783
         row_info->pixel_depth = 8;
 
3784
         row_info->rowbytes = row_width;
 
3785
      }
 
3786
      switch (row_info->bit_depth)
 
3787
      {
 
3788
         case 8:
 
3789
         {
 
3790
            if (trans != NULL)
 
3791
            {
 
3792
               sp = row + (png_size_t)row_width - 1;
 
3793
               dp = row + (png_size_t)(row_width << 2) - 1;
 
3794
 
 
3795
               for (i = 0; i < row_width; i++)
 
3796
               {
 
3797
                  if ((int)(*sp) >= num_trans)
 
3798
                     *dp-- = 0xff;
 
3799
                  else
 
3800
                     *dp-- = trans[*sp];
 
3801
                  *dp-- = palette[*sp].blue;
 
3802
                  *dp-- = palette[*sp].green;
 
3803
                  *dp-- = palette[*sp].red;
 
3804
                  sp--;
 
3805
               }
 
3806
               row_info->bit_depth = 8;
 
3807
               row_info->pixel_depth = 32;
 
3808
               row_info->rowbytes = row_width * 4;
 
3809
               row_info->color_type = 6;
 
3810
               row_info->channels = 4;
 
3811
            }
 
3812
            else
 
3813
            {
 
3814
               sp = row + (png_size_t)row_width - 1;
 
3815
               dp = row + (png_size_t)(row_width * 3) - 1;
 
3816
 
 
3817
               for (i = 0; i < row_width; i++)
 
3818
               {
 
3819
                  *dp-- = palette[*sp].blue;
 
3820
                  *dp-- = palette[*sp].green;
 
3821
                  *dp-- = palette[*sp].red;
 
3822
                  sp--;
 
3823
               }
 
3824
 
 
3825
               row_info->bit_depth = 8;
 
3826
               row_info->pixel_depth = 24;
 
3827
               row_info->rowbytes = row_width * 3;
 
3828
               row_info->color_type = 2;
 
3829
               row_info->channels = 3;
 
3830
            }
 
3831
            break;
 
3832
         }
 
3833
      }
 
3834
   }
 
3835
}
 
3836
 
 
3837
/* If the bit depth < 8, it is expanded to 8.  Also, if the already
 
3838
 * expanded transparency value is supplied, an alpha channel is built.
 
3839
 */
 
3840
void /* PRIVATE */
 
3841
png_do_expand(png_row_infop row_info, png_bytep row,
 
3842
   png_color_16p trans_value)
 
3843
{
 
3844
   int shift, value;
 
3845
   png_bytep sp, dp;
 
3846
   png_uint_32 i;
 
3847
   png_uint_32 row_width=row_info->width;
 
3848
 
 
3849
   png_debug(1, "in png_do_expand");
 
3850
 
 
3851
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
3852
   if (row != NULL && row_info != NULL)
 
3853
#endif
 
3854
   {
 
3855
      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
 
3856
      {
 
3857
         png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
 
3858
 
 
3859
         if (row_info->bit_depth < 8)
 
3860
         {
 
3861
            switch (row_info->bit_depth)
 
3862
            {
 
3863
               case 1:
 
3864
               {
 
3865
                  gray = (png_uint_16)((gray&0x01)*0xff);
 
3866
                  sp = row + (png_size_t)((row_width - 1) >> 3);
 
3867
                  dp = row + (png_size_t)row_width - 1;
 
3868
                  shift = 7 - (int)((row_width + 7) & 0x07);
 
3869
                  for (i = 0; i < row_width; i++)
 
3870
                  {
 
3871
                     if ((*sp >> shift) & 0x01)
 
3872
                        *dp = 0xff;
 
3873
                     else
 
3874
                        *dp = 0;
 
3875
                     if (shift == 7)
 
3876
                     {
 
3877
                        shift = 0;
 
3878
                        sp--;
 
3879
                     }
 
3880
                     else
 
3881
                        shift++;
 
3882
 
 
3883
                     dp--;
 
3884
                  }
 
3885
                  break;
 
3886
               }
 
3887
 
 
3888
               case 2:
 
3889
               {
 
3890
                  gray = (png_uint_16)((gray&0x03)*0x55);
 
3891
                  sp = row + (png_size_t)((row_width - 1) >> 2);
 
3892
                  dp = row + (png_size_t)row_width - 1;
 
3893
                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
 
3894
                  for (i = 0; i < row_width; i++)
 
3895
                  {
 
3896
                     value = (*sp >> shift) & 0x03;
 
3897
                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
 
3898
                        (value << 6));
 
3899
                     if (shift == 6)
 
3900
                     {
 
3901
                        shift = 0;
 
3902
                        sp--;
 
3903
                     }
 
3904
                     else
 
3905
                        shift += 2;
 
3906
 
 
3907
                     dp--;
 
3908
                  }
 
3909
                  break;
 
3910
               }
 
3911
 
 
3912
               case 4:
 
3913
               {
 
3914
                  gray = (png_uint_16)((gray&0x0f)*0x11);
 
3915
                  sp = row + (png_size_t)((row_width - 1) >> 1);
 
3916
                  dp = row + (png_size_t)row_width - 1;
 
3917
                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
 
3918
                  for (i = 0; i < row_width; i++)
 
3919
                  {
 
3920
                     value = (*sp >> shift) & 0x0f;
 
3921
                     *dp = (png_byte)(value | (value << 4));
 
3922
                     if (shift == 4)
 
3923
                     {
 
3924
                        shift = 0;
 
3925
                        sp--;
 
3926
                     }
 
3927
                     else
 
3928
                        shift = 4;
 
3929
 
 
3930
                     dp--;
 
3931
                  }
 
3932
                  break;
 
3933
               }
 
3934
            }
 
3935
 
 
3936
            row_info->bit_depth = 8;
 
3937
            row_info->pixel_depth = 8;
 
3938
            row_info->rowbytes = row_width;
 
3939
         }
 
3940
 
 
3941
         if (trans_value != NULL)
 
3942
         {
 
3943
            if (row_info->bit_depth == 8)
 
3944
            {
 
3945
               gray = gray & 0xff;
 
3946
               sp = row + (png_size_t)row_width - 1;
 
3947
               dp = row + (png_size_t)(row_width << 1) - 1;
 
3948
               for (i = 0; i < row_width; i++)
 
3949
               {
 
3950
                  if (*sp == gray)
 
3951
                     *dp-- = 0;
 
3952
                  else
 
3953
                     *dp-- = 0xff;
 
3954
                  *dp-- = *sp--;
 
3955
               }
 
3956
            }
 
3957
 
 
3958
            else if (row_info->bit_depth == 16)
 
3959
            {
 
3960
               png_byte gray_high = (gray >> 8) & 0xff;
 
3961
               png_byte gray_low = gray & 0xff;
 
3962
               sp = row + row_info->rowbytes - 1;
 
3963
               dp = row + (row_info->rowbytes << 1) - 1;
 
3964
               for (i = 0; i < row_width; i++)
 
3965
               {
 
3966
                  if (*(sp - 1) == gray_high && *(sp) == gray_low)
 
3967
                  {
 
3968
                     *dp-- = 0;
 
3969
                     *dp-- = 0;
 
3970
                  }
 
3971
                  else
 
3972
                  {
 
3973
                     *dp-- = 0xff;
 
3974
                     *dp-- = 0xff;
 
3975
                  }
 
3976
                  *dp-- = *sp--;
 
3977
                  *dp-- = *sp--;
 
3978
               }
 
3979
            }
 
3980
 
 
3981
            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
 
3982
            row_info->channels = 2;
 
3983
            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
 
3984
            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
 
3985
               row_width);
 
3986
         }
 
3987
      }
 
3988
      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
 
3989
      {
 
3990
         if (row_info->bit_depth == 8)
 
3991
         {
 
3992
            png_byte red = trans_value->red & 0xff;
 
3993
            png_byte green = trans_value->green & 0xff;
 
3994
            png_byte blue = trans_value->blue & 0xff;
 
3995
            sp = row + (png_size_t)row_info->rowbytes - 1;
 
3996
            dp = row + (png_size_t)(row_width << 2) - 1;
 
3997
            for (i = 0; i < row_width; i++)
 
3998
            {
 
3999
               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
 
4000
                  *dp-- = 0;
 
4001
               else
 
4002
                  *dp-- = 0xff;
 
4003
               *dp-- = *sp--;
 
4004
               *dp-- = *sp--;
 
4005
               *dp-- = *sp--;
 
4006
            }
 
4007
         }
 
4008
         else if (row_info->bit_depth == 16)
 
4009
         {
 
4010
            png_byte red_high = (trans_value->red >> 8) & 0xff;
 
4011
            png_byte green_high = (trans_value->green >> 8) & 0xff;
 
4012
            png_byte blue_high = (trans_value->blue >> 8) & 0xff;
 
4013
            png_byte red_low = trans_value->red & 0xff;
 
4014
            png_byte green_low = trans_value->green & 0xff;
 
4015
            png_byte blue_low = trans_value->blue & 0xff;
 
4016
            sp = row + row_info->rowbytes - 1;
 
4017
            dp = row + (png_size_t)(row_width << 3) - 1;
 
4018
            for (i = 0; i < row_width; i++)
 
4019
            {
 
4020
               if (*(sp - 5) == red_high &&
 
4021
                  *(sp - 4) == red_low &&
 
4022
                  *(sp - 3) == green_high &&
 
4023
                  *(sp - 2) == green_low &&
 
4024
                  *(sp - 1) == blue_high &&
 
4025
                  *(sp    ) == blue_low)
 
4026
               {
 
4027
                  *dp-- = 0;
 
4028
                  *dp-- = 0;
 
4029
               }
 
4030
               else
 
4031
               {
 
4032
                  *dp-- = 0xff;
 
4033
                  *dp-- = 0xff;
 
4034
               }
 
4035
               *dp-- = *sp--;
 
4036
               *dp-- = *sp--;
 
4037
               *dp-- = *sp--;
 
4038
               *dp-- = *sp--;
 
4039
               *dp-- = *sp--;
 
4040
               *dp-- = *sp--;
 
4041
            }
 
4042
         }
 
4043
         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
 
4044
         row_info->channels = 4;
 
4045
         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
 
4046
         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
 
4047
      }
 
4048
   }
 
4049
}
 
4050
#endif
 
4051
 
 
4052
#ifdef PNG_READ_DITHER_SUPPORTED
 
4053
void /* PRIVATE */
 
4054
png_do_dither(png_row_infop row_info, png_bytep row,
 
4055
    png_bytep palette_lookup, png_bytep dither_lookup)
 
4056
{
 
4057
   png_bytep sp, dp;
 
4058
   png_uint_32 i;
 
4059
   png_uint_32 row_width=row_info->width;
 
4060
 
 
4061
   png_debug(1, "in png_do_dither");
 
4062
 
 
4063
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
4064
   if (row != NULL && row_info != NULL)
 
4065
#endif
 
4066
   {
 
4067
      if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
 
4068
         palette_lookup && row_info->bit_depth == 8)
 
4069
      {
 
4070
         int r, g, b, p;
 
4071
         sp = row;
 
4072
         dp = row;
 
4073
         for (i = 0; i < row_width; i++)
 
4074
         {
 
4075
            r = *sp++;
 
4076
            g = *sp++;
 
4077
            b = *sp++;
 
4078
 
 
4079
            /* This looks real messy, but the compiler will reduce
 
4080
             * it down to a reasonable formula.  For example, with
 
4081
             * 5 bits per color, we get:
 
4082
             * p = (((r >> 3) & 0x1f) << 10) |
 
4083
             *    (((g >> 3) & 0x1f) << 5) |
 
4084
             *    ((b >> 3) & 0x1f);
 
4085
             */
 
4086
            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
 
4087
               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
 
4088
               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
 
4089
               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
 
4090
               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
 
4091
               (PNG_DITHER_BLUE_BITS)) |
 
4092
               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
 
4093
               ((1 << PNG_DITHER_BLUE_BITS) - 1));
 
4094
 
 
4095
            *dp++ = palette_lookup[p];
 
4096
         }
 
4097
         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
 
4098
         row_info->channels = 1;
 
4099
         row_info->pixel_depth = row_info->bit_depth;
 
4100
         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
 
4101
      }
 
4102
      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
 
4103
         palette_lookup != NULL && row_info->bit_depth == 8)
 
4104
      {
 
4105
         int r, g, b, p;
 
4106
         sp = row;
 
4107
         dp = row;
 
4108
         for (i = 0; i < row_width; i++)
 
4109
         {
 
4110
            r = *sp++;
 
4111
            g = *sp++;
 
4112
            b = *sp++;
 
4113
            sp++;
 
4114
 
 
4115
            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
 
4116
               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
 
4117
               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
 
4118
               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
 
4119
               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
 
4120
               (PNG_DITHER_BLUE_BITS)) |
 
4121
               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
 
4122
               ((1 << PNG_DITHER_BLUE_BITS) - 1));
 
4123
 
 
4124
            *dp++ = palette_lookup[p];
 
4125
         }
 
4126
         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
 
4127
         row_info->channels = 1;
 
4128
         row_info->pixel_depth = row_info->bit_depth;
 
4129
         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
 
4130
      }
 
4131
      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
 
4132
         dither_lookup && row_info->bit_depth == 8)
 
4133
      {
 
4134
         sp = row;
 
4135
         for (i = 0; i < row_width; i++, sp++)
 
4136
         {
 
4137
            *sp = dither_lookup[*sp];
 
4138
         }
 
4139
      }
 
4140
   }
 
4141
}
 
4142
#endif
 
4143
 
 
4144
#ifdef PNG_FLOATING_POINT_SUPPORTED
 
4145
#ifdef PNG_READ_GAMMA_SUPPORTED
 
4146
static PNG_CONST int png_gamma_shift[] =
 
4147
   {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
 
4148
 
 
4149
/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
 
4150
 * tables, we don't make a full table if we are reducing to 8-bit in
 
4151
 * the future.  Note also how the gamma_16 tables are segmented so that
 
4152
 * we don't need to allocate > 64K chunks for a full 16-bit table.
 
4153
 *
 
4154
 * See the PNG extensions document for an integer algorithm for creating
 
4155
 * the gamma tables.  Maybe we will implement that here someday.
 
4156
 *
 
4157
 * We should only reach this point if
 
4158
 *
 
4159
 *      the file_gamma is known (i.e., the gAMA or sRGB chunk is present,
 
4160
 *      or the application has provided a file_gamma)
 
4161
 *
 
4162
 *   AND
 
4163
 *      {
 
4164
 *         the screen_gamma is known
 
4165
 *      OR
 
4166
 *
 
4167
 *         RGB_to_gray transformation is being performed
 
4168
 *      }
 
4169
 *
 
4170
 *   AND
 
4171
 *      {
 
4172
 *         the screen_gamma is different from the reciprocal of the
 
4173
 *         file_gamma by more than the specified threshold
 
4174
 *
 
4175
 *      OR
 
4176
 *
 
4177
 *         a background color has been specified and the file_gamma
 
4178
 *         and screen_gamma are not 1.0, within the specified threshold.
 
4179
 *      }
 
4180
 */
 
4181
 
 
4182
void /* PRIVATE */
 
4183
png_build_gamma_table(png_structp png_ptr)
 
4184
{
 
4185
  png_debug(1, "in png_build_gamma_table");
 
4186
 
 
4187
  if (png_ptr->bit_depth <= 8)
 
4188
  {
 
4189
     int i;
 
4190
     double g;
 
4191
 
 
4192
     if (png_ptr->screen_gamma > .000001)
 
4193
        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
 
4194
 
 
4195
     else
 
4196
        g = 1.0;
 
4197
 
 
4198
     png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
 
4199
        (png_uint_32)256);
 
4200
 
 
4201
     for (i = 0; i < 256; i++)
 
4202
     {
 
4203
        png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
 
4204
           g) * 255.0 + .5);
 
4205
     }
 
4206
 
 
4207
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
 
4208
   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
 
4209
     if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
 
4210
     {
 
4211
 
 
4212
        g = 1.0 / (png_ptr->gamma);
 
4213
 
 
4214
        png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
 
4215
           (png_uint_32)256);
 
4216
 
 
4217
        for (i = 0; i < 256; i++)
 
4218
        {
 
4219
           png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
 
4220
              g) * 255.0 + .5);
 
4221
        }
 
4222
 
 
4223
 
 
4224
        png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
 
4225
           (png_uint_32)256);
 
4226
 
 
4227
        if (png_ptr->screen_gamma > 0.000001)
 
4228
           g = 1.0 / png_ptr->screen_gamma;
 
4229
 
 
4230
        else
 
4231
           g = png_ptr->gamma;   /* Probably doing rgb_to_gray */
 
4232
 
 
4233
        for (i = 0; i < 256; i++)
 
4234
        {
 
4235
           png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
 
4236
              g) * 255.0 + .5);
 
4237
 
 
4238
        }
 
4239
     }
 
4240
#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
 
4241
  }
 
4242
  else
 
4243
  {
 
4244
     double g;
 
4245
     int i, j, shift, num;
 
4246
     int sig_bit;
 
4247
     png_uint_32 ig;
 
4248
 
 
4249
     if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
 
4250
     {
 
4251
        sig_bit = (int)png_ptr->sig_bit.red;
 
4252
 
 
4253
        if ((int)png_ptr->sig_bit.green > sig_bit)
 
4254
           sig_bit = png_ptr->sig_bit.green;
 
4255
 
 
4256
        if ((int)png_ptr->sig_bit.blue > sig_bit)
 
4257
           sig_bit = png_ptr->sig_bit.blue;
 
4258
     }
 
4259
     else
 
4260
     {
 
4261
        sig_bit = (int)png_ptr->sig_bit.gray;
 
4262
     }
 
4263
 
 
4264
     if (sig_bit > 0)
 
4265
        shift = 16 - sig_bit;
 
4266
 
 
4267
     else
 
4268
        shift = 0;
 
4269
 
 
4270
     if (png_ptr->transformations & PNG_16_TO_8)
 
4271
     {
 
4272
        if (shift < (16 - PNG_MAX_GAMMA_8))
 
4273
           shift = (16 - PNG_MAX_GAMMA_8);
 
4274
     }
 
4275
 
 
4276
     if (shift > 8)
 
4277
        shift = 8;
 
4278
 
 
4279
     if (shift < 0)
 
4280
        shift = 0;
 
4281
 
 
4282
     png_ptr->gamma_shift = (png_byte)shift;
 
4283
 
 
4284
     num = (1 << (8 - shift));
 
4285
 
 
4286
     if (png_ptr->screen_gamma > .000001)
 
4287
        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
 
4288
     else
 
4289
        g = 1.0;
 
4290
 
 
4291
     png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr,
 
4292
        (png_uint_32)(num * png_sizeof(png_uint_16p)));
 
4293
 
 
4294
     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
 
4295
     {
 
4296
        double fin, fout;
 
4297
        png_uint_32 last, max;
 
4298
 
 
4299
        for (i = 0; i < num; i++)
 
4300
        {
 
4301
           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
 
4302
              (png_uint_32)(256 * png_sizeof(png_uint_16)));
 
4303
        }
 
4304
 
 
4305
        g = 1.0 / g;
 
4306
        last = 0;
 
4307
        for (i = 0; i < 256; i++)
 
4308
        {
 
4309
           fout = ((double)i + 0.5) / 256.0;
 
4310
           fin = pow(fout, g);
 
4311
           max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
 
4312
           while (last <= max)
 
4313
           {
 
4314
              png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
 
4315
                 [(int)(last >> (8 - shift))] = (png_uint_16)(
 
4316
                 (png_uint_16)i | ((png_uint_16)i << 8));
 
4317
              last++;
 
4318
           }
 
4319
        }
 
4320
        while (last < ((png_uint_32)num << 8))
 
4321
        {
 
4322
           png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
 
4323
              [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
 
4324
           last++;
 
4325
        }
 
4326
     }
 
4327
     else
 
4328
     {
 
4329
        for (i = 0; i < num; i++)
 
4330
        {
 
4331
           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
 
4332
              (png_uint_32)(256 * png_sizeof(png_uint_16)));
 
4333
 
 
4334
           ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
 
4335
 
 
4336
           for (j = 0; j < 256; j++)
 
4337
           {
 
4338
              png_ptr->gamma_16_table[i][j] =
 
4339
                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
 
4340
                    65535.0, g) * 65535.0 + .5);
 
4341
           }
 
4342
        }
 
4343
     }
 
4344
 
 
4345
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
 
4346
   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
 
4347
     if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
 
4348
     {
 
4349
 
 
4350
        g = 1.0 / (png_ptr->gamma);
 
4351
 
 
4352
        png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr,
 
4353
           (png_uint_32)(num * png_sizeof(png_uint_16p )));
 
4354
 
 
4355
        for (i = 0; i < num; i++)
 
4356
        {
 
4357
           png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
 
4358
              (png_uint_32)(256 * png_sizeof(png_uint_16)));
 
4359
 
 
4360
           ig = (((png_uint_32)i *
 
4361
              (png_uint_32)png_gamma_shift[shift]) >> 4);
 
4362
           for (j = 0; j < 256; j++)
 
4363
           {
 
4364
              png_ptr->gamma_16_to_1[i][j] =
 
4365
                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
 
4366
                    65535.0, g) * 65535.0 + .5);
 
4367
           }
 
4368
        }
 
4369
 
 
4370
        if (png_ptr->screen_gamma > 0.000001)
 
4371
           g = 1.0 / png_ptr->screen_gamma;
 
4372
 
 
4373
        else
 
4374
           g = png_ptr->gamma;   /* Probably doing rgb_to_gray */
 
4375
 
 
4376
        png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr,
 
4377
           (png_uint_32)(num * png_sizeof(png_uint_16p)));
 
4378
 
 
4379
        for (i = 0; i < num; i++)
 
4380
        {
 
4381
           png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
 
4382
              (png_uint_32)(256 * png_sizeof(png_uint_16)));
 
4383
 
 
4384
           ig = (((png_uint_32)i *
 
4385
              (png_uint_32)png_gamma_shift[shift]) >> 4);
 
4386
 
 
4387
           for (j = 0; j < 256; j++)
 
4388
           {
 
4389
              png_ptr->gamma_16_from_1[i][j] =
 
4390
                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
 
4391
                    65535.0, g) * 65535.0 + .5);
 
4392
           }
 
4393
        }
 
4394
     }
 
4395
#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
 
4396
  }
 
4397
}
 
4398
#endif
 
4399
/* To do: install integer version of png_build_gamma_table here */
 
4400
#endif
 
4401
 
 
4402
#ifdef PNG_MNG_FEATURES_SUPPORTED
 
4403
/* Undoes intrapixel differencing  */
 
4404
void /* PRIVATE */
 
4405
png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
 
4406
{
 
4407
   png_debug(1, "in png_do_read_intrapixel");
 
4408
 
 
4409
   if (
 
4410
#ifdef PNG_USELESS_TESTS_SUPPORTED
 
4411
       row != NULL && row_info != NULL &&
 
4412
#endif
 
4413
       (row_info->color_type & PNG_COLOR_MASK_COLOR))
 
4414
   {
 
4415
      int bytes_per_pixel;
 
4416
      png_uint_32 row_width = row_info->width;
 
4417
      if (row_info->bit_depth == 8)
 
4418
      {
 
4419
         png_bytep rp;
 
4420
         png_uint_32 i;
 
4421
 
 
4422
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 
4423
            bytes_per_pixel = 3;
 
4424
 
 
4425
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 
4426
            bytes_per_pixel = 4;
 
4427
 
 
4428
         else
 
4429
            return;
 
4430
 
 
4431
         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
 
4432
         {
 
4433
            *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
 
4434
            *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
 
4435
         }
 
4436
      }
 
4437
      else if (row_info->bit_depth == 16)
 
4438
      {
 
4439
         png_bytep rp;
 
4440
         png_uint_32 i;
 
4441
 
 
4442
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 
4443
            bytes_per_pixel = 6;
 
4444
 
 
4445
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 
4446
            bytes_per_pixel = 8;
 
4447
 
 
4448
         else
 
4449
            return;
 
4450
 
 
4451
         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
 
4452
         {
 
4453
            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
 
4454
            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
 
4455
            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
 
4456
            png_uint_32 red  = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
 
4457
            png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
 
4458
            *(rp  ) = (png_byte)((red >> 8) & 0xff);
 
4459
            *(rp+1) = (png_byte)(red & 0xff);
 
4460
            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
 
4461
            *(rp+5) = (png_byte)(blue & 0xff);
 
4462
         }
 
4463
      }
 
4464
   }
 
4465
}
 
4466
#endif /* PNG_MNG_FEATURES_SUPPORTED */
 
4467
#endif /* PNG_READ_SUPPORTED */