~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/libpng/pngrtran.c

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

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