~ubuntu-branches/ubuntu/maverick/ntop/maverick

« back to all changes in this revision

Viewing changes to gdchart0.94c/gd-1.8.3/libpng-1.0.8/pngrtran.c

  • Committer: Bazaar Package Importer
  • Author(s): Dennis Schoen
  • Date: 2002-04-12 11:38:47 UTC
  • Revision ID: james.westby@ubuntu.com-20020412113847-4k4yydw0pzybc6g8
Tags: upstream-2.0.0
ImportĀ upstreamĀ versionĀ 2.0.0

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