Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
 
2
 *
3
 * Last changed in libpng 1.6.4 [September 14, 2013]
4
 * Copyright (c) 1998-2013 Glenn Randers-Pehrson
5
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
6
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 * This file contains functions optionally called by an application
13
 * in order to tell libpng how to handle data when reading a PNG.
14
 * Transformations that are used in both reading and writing are
15
 * in pngtrans.c.
16
 */
17
18
 
19
20
 
21
22
 
23
void PNGAPI
24
png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
25
{
26
   png_debug(1, "in png_set_crc_action");
27
28
 
29
      return;
30
31
 
32
   switch (crit_action)
33
   {
34
      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
35
         break;
36
37
 
38
         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
39
         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
40
         break;
41
42
 
43
         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
44
         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
45
                           PNG_FLAG_CRC_CRITICAL_IGNORE;
46
         break;
47
48
 
49
         png_warning(png_ptr,
50
            "Can't discard critical data on CRC error");
51
      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
52
53
 
54
      default:
55
         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
56
         break;
57
   }
58
59
 
60
   switch (ancil_action)
61
   {
62
      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
63
         break;
64
65
 
66
         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
67
         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
68
         break;
69
70
 
71
         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
72
         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
73
                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
74
         break;
75
76
 
77
         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
78
         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
79
         break;
80
81
 
82
83
 
84
      default:
85
         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
86
         break;
87
   }
88
}
89
90
 
91
/* Is it OK to set a transformation now?  Only if png_start_read_image or
92
 * png_read_update_info have not been called.  It is not necessary for the IHDR
93
 * to have been read in all cases, the parameter allows for this check too.
94
 */
95
static int
96
png_rtran_ok(png_structrp png_ptr, int need_IHDR)
97
{
98
   if (png_ptr != NULL)
99
   {
100
      if (png_ptr->flags & PNG_FLAG_ROW_INIT)
101
         png_app_error(png_ptr,
102
            "invalid after png_start_read_image or png_read_update_info");
103
104
 
105
         png_app_error(png_ptr, "invalid before the PNG header has been read");
106
107
 
108
      {
109
         /* Turn on failure to initialize correctly for all transforms. */
110
         png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
111
112
 
113
      }
114
   }
115
116
 
117
}
118
#endif
119
120
 
121
/* Handle alpha and tRNS via a background color */
122
void PNGFAPI
123
png_set_background_fixed(png_structrp png_ptr,
124
    png_const_color_16p background_color, int background_gamma_code,
125
    int need_expand, png_fixed_point background_gamma)
126
{
127
   png_debug(1, "in png_set_background_fixed");
128
129
 
130
      return;
131
132
 
133
   {
134
      png_warning(png_ptr, "Application must supply a known background gamma");
135
      return;
136
   }
137
138
 
139
   png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
140
   png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
141
142
 
143
   png_ptr->background_gamma = background_gamma;
144
   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
145
   if (need_expand)
146
      png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
147
   else
148
      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
149
}
150
151
 
152
void PNGAPI
153
png_set_background(png_structrp png_ptr,
154
    png_const_color_16p background_color, int background_gamma_code,
155
    int need_expand, double background_gamma)
156
{
157
   png_set_background_fixed(png_ptr, background_color, background_gamma_code,
158
      need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
159
}
160
#  endif  /* FLOATING_POINT */
161
#endif /* READ_BACKGROUND */
162
163
 
164
 * one that pngrtran does first (scale) happens.  This is necessary to allow the
165
 * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
166
 */
167
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
168
void PNGAPI
169
png_set_scale_16(png_structrp png_ptr)
170
{
171
   png_debug(1, "in png_set_scale_16");
172
173
 
174
      return;
175
176
 
177
}
178
#endif
179
180
 
181
/* Chop 16-bit depth files to 8-bit depth */
182
void PNGAPI
183
png_set_strip_16(png_structrp png_ptr)
184
{
185
   png_debug(1, "in png_set_strip_16");
186
187
 
188
      return;
189
190
 
191
}
192
#endif
193
194
 
195
void PNGAPI
196
png_set_strip_alpha(png_structrp png_ptr)
197
{
198
   png_debug(1, "in png_set_strip_alpha");
199
200
 
201
      return;
202
203
 
204
}
205
#endif
206
207
 
208
static png_fixed_point
209
translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
210
   int is_screen)
211
{
212
   /* Check for flag values.  The main reason for having the old Mac value as a
213
    * flag is that it is pretty near impossible to work out what the correct
214
    * value is from Apple documentation - a working Mac system is needed to
215
    * discover the value!
216
    */
217
   if (output_gamma == PNG_DEFAULT_sRGB ||
218
      output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
219
   {
220
      /* If there is no sRGB support this just sets the gamma to the standard
221
       * sRGB value.  (This is a side effect of using this function!)
222
       */
223
#     ifdef PNG_READ_sRGB_SUPPORTED
224
         png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
225
#     else
226
         PNG_UNUSED(png_ptr)
227
#     endif
228
      if (is_screen)
229
         output_gamma = PNG_GAMMA_sRGB;
230
      else
231
         output_gamma = PNG_GAMMA_sRGB_INVERSE;
232
   }
233
234
 
235
      output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
236
   {
237
      if (is_screen)
238
         output_gamma = PNG_GAMMA_MAC_OLD;
239
      else
240
         output_gamma = PNG_GAMMA_MAC_INVERSE;
241
   }
242
243
 
244
}
245
246
 
247
static png_fixed_point
248
convert_gamma_value(png_structrp png_ptr, double output_gamma)
249
{
250
   /* The following silently ignores cases where fixed point (times 100,000)
251
    * gamma values are passed to the floating point API.  This is safe and it
252
    * means the fixed point constants work just fine with the floating point
253
    * API.  The alternative would just lead to undetected errors and spurious
254
    * bug reports.  Negative values fail inside the _fixed API unless they
255
    * correspond to the flag values.
256
    */
257
   if (output_gamma > 0 && output_gamma < 128)
258
      output_gamma *= PNG_FP_1;
259
260
 
261
   output_gamma = floor(output_gamma + .5);
262
263
 
264
      png_fixed_error(png_ptr, "gamma value");
265
266
 
267
}
268
#  endif
269
#endif /* READ_ALPHA_MODE || READ_GAMMA */
270
271
 
272
void PNGFAPI
273
png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
274
   png_fixed_point output_gamma)
275
{
276
   int compose = 0;
277
   png_fixed_point file_gamma;
278
279
 
280
281
 
282
      return;
283
284
 
285
286
 
287
    * is expected to be 1 or greater, but this range test allows for some
288
    * viewing correction values.  The intent is to weed out users of this API
289
    * who use the inverse of the gamma value accidentally!  Since some of these
290
    * values are reasonable this may have to be changed.
291
    */
292
   if (output_gamma < 70000 || output_gamma > 300000)
293
      png_error(png_ptr, "output gamma out of expected range");
294
295
 
296
    * gamma may be changed below so get the file value first:
297
    */
298
   file_gamma = png_reciprocal(output_gamma);
299
300
 
301
    * of:
302
    *
303
    *    premultiply the color channels
304
    *    do not encode non-opaque pixels
305
    *    encode the alpha as well as the color channels
306
    *
307
    * The differences disappear if the input/output ('screen') gamma is 1.0,
308
    * because then the encoding is a no-op and there is only the choice of
309
    * premultiplying the color channels or not.
310
    *
311
    * png_set_alpha_mode and png_set_background interact because both use
312
    * png_compose to do the work.  Calling both is only useful when
313
    * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
314
    * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.
315
    */
316
   switch (mode)
317
   {
318
      case PNG_ALPHA_PNG:        /* default: png standard */
319
         /* No compose, but it may be set by png_set_background! */
320
         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
321
         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
322
         break;
323
324
 
325
         compose = 1;
326
         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
327
         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
328
         /* The output is linear: */
329
         output_gamma = PNG_FP_1;
330
         break;
331
332
 
333
         compose = 1;
334
         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
335
         png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
336
         /* output_gamma records the encoding of opaque pixels! */
337
         break;
338
339
 
340
         compose = 1;
341
         png_ptr->transformations |= PNG_ENCODE_ALPHA;
342
         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
343
         break;
344
345
 
346
         png_error(png_ptr, "invalid alpha mode");
347
   }
348
349
 
350
    * the side effect that the gamma in a second call to png_set_alpha_mode will
351
    * be ignored.)
352
    */
353
   if (png_ptr->colorspace.gamma == 0)
354
   {
355
      png_ptr->colorspace.gamma = file_gamma;
356
      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
357
   }
358
359
 
360
   png_ptr->screen_gamma = output_gamma;
361
362
 
363
    * desired result.
364
    */
365
   if (compose)
366
   {
367
      /* And obtain alpha pre-multiplication by composing on black: */
368
      memset(&png_ptr->background, 0, (sizeof png_ptr->background));
369
      png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
370
      png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
371
      png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
372
373
 
374
         png_error(png_ptr,
375
            "conflicting calls to set alpha mode and background");
376
377
 
378
   }
379
}
380
381
 
382
void PNGAPI
383
png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
384
{
385
   png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
386
      output_gamma));
387
}
388
#  endif
389
#endif
390
391
 
392
/* Dither file to 8-bit.  Supply a palette, the current number
393
 * of elements in the palette, the maximum number of elements
394
 * allowed, and a histogram if possible.  If the current number
395
 * of colors is greater then the maximum number, the palette will be
396
 * modified to fit in the maximum number.  "full_quantize" indicates
397
 * whether we need a quantizing cube set up for RGB images, or if we
398
 * simply are reducing the number of colors in a paletted image.
399
 */
400
401
 
402
{
403
   struct png_dsort_struct * next;
404
   png_byte left;
405
   png_byte right;
406
} png_dsort;
407
typedef png_dsort *   png_dsortp;
408
typedef png_dsort * * png_dsortpp;
409
410
 
411
png_set_quantize(png_structrp png_ptr, png_colorp palette,
412
    int num_palette, int maximum_colors, png_const_uint_16p histogram,
413
    int full_quantize)
414
{
415
   png_debug(1, "in png_set_quantize");
416
417
 
418
      return;
419
420
 
421
422
 
423
   {
424
      int i;
425
426
 
427
          (png_uint_32)(num_palette * (sizeof (png_byte))));
428
      for (i = 0; i < num_palette; i++)
429
         png_ptr->quantize_index[i] = (png_byte)i;
430
   }
431
432
 
433
   {
434
      if (histogram != NULL)
435
      {
436
         /* This is easy enough, just throw out the least used colors.
437
          * Perhaps not the best solution, but good enough.
438
          */
439
440
 
441
442
 
443
         png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
444
             (png_uint_32)(num_palette * (sizeof (png_byte))));
445
446
 
447
         for (i = 0; i < num_palette; i++)
448
            png_ptr->quantize_sort[i] = (png_byte)i;
449
450
 
451
          * bubble sort, and running it until we have sorted
452
          * out enough colors.  Note that we don't care about
453
          * sorting all the colors, just finding which are
454
          * least used.
455
          */
456
457
 
458
         {
459
            int done; /* To stop early if the list is pre-sorted */
460
            int j;
461
462
 
463
            for (j = 0; j < i; j++)
464
            {
465
               if (histogram[png_ptr->quantize_sort[j]]
466
                   < histogram[png_ptr->quantize_sort[j + 1]])
467
               {
468
                  png_byte t;
469
470
 
471
                  png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
472
                  png_ptr->quantize_sort[j + 1] = t;
473
                  done = 0;
474
               }
475
            }
476
477
 
478
               break;
479
         }
480
481
 
482
         if (full_quantize)
483
         {
484
            int j = num_palette;
485
486
 
487
             * move the others.
488
             */
489
            for (i = 0; i < maximum_colors; i++)
490
            {
491
               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
492
               {
493
                  do
494
                     j--;
495
                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
496
497
 
498
               }
499
            }
500
         }
501
         else
502
         {
503
            int j = num_palette;
504
505
 
506
             * develop a translation table.
507
             */
508
            for (i = 0; i < maximum_colors; i++)
509
            {
510
               /* Only move the colors we need to */
511
               if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
512
               {
513
                  png_color tmp_color;
514
515
 
516
                     j--;
517
                  while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
518
519
 
520
                  palette[j] = palette[i];
521
                  palette[i] = tmp_color;
522
                  /* Indicate where the color went */
523
                  png_ptr->quantize_index[j] = (png_byte)i;
524
                  png_ptr->quantize_index[i] = (png_byte)j;
525
               }
526
            }
527
528
 
529
            for (i = 0; i < num_palette; i++)
530
            {
531
               if ((int)png_ptr->quantize_index[i] >= maximum_colors)
532
               {
533
                  int min_d, k, min_k, d_index;
534
535
 
536
                  d_index = png_ptr->quantize_index[i];
537
                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
538
                  for (k = 1, min_k = 0; k < maximum_colors; k++)
539
                  {
540
                     int d;
541
542
 
543
544
 
545
                     {
546
                        min_d = d;
547
                        min_k = k;
548
                     }
549
                  }
550
                  /* Point to closest color */
551
                  png_ptr->quantize_index[i] = (png_byte)min_k;
552
               }
553
            }
554
         }
555
         png_free(png_ptr, png_ptr->quantize_sort);
556
         png_ptr->quantize_sort = NULL;
557
      }
558
      else
559
      {
560
         /* This is much harder to do simply (and quickly).  Perhaps
561
          * we need to go through a median cut routine, but those
562
          * don't always behave themselves with only a few colors
563
          * as input.  So we will just find the closest two colors,
564
          * and throw out one of them (chosen somewhat randomly).
565
          * [We don't understand this at all, so if someone wants to
566
          *  work on improving it, be our guest - AED, GRP]
567
          */
568
         int i;
569
         int max_d;
570
         int num_new_palette;
571
         png_dsortp t;
572
         png_dsortpp hash;
573
574
 
575
576
 
577
         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
578
             (png_uint_32)(num_palette * (sizeof (png_byte))));
579
         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
580
             (png_uint_32)(num_palette * (sizeof (png_byte))));
581
582
 
583
         for (i = 0; i < num_palette; i++)
584
         {
585
            png_ptr->index_to_palette[i] = (png_byte)i;
586
            png_ptr->palette_to_index[i] = (png_byte)i;
587
         }
588
589
 
590
             (sizeof (png_dsortp))));
591
592
 
593
594
 
595
          * pair we will be eliminating will be.  Larger
596
          * numbers mean more areas will be allocated, Smaller
597
          * numbers run the risk of not saving enough data, and
598
          * having to do this all over again.
599
          *
600
          * I have not done extensive checking on this number.
601
          */
602
         max_d = 96;
603
604
 
605
         {
606
            for (i = 0; i < num_new_palette - 1; i++)
607
            {
608
               int j;
609
610
 
611
               {
612
                  int d;
613
614
 
615
616
 
617
                  {
618
619
 
620
                         (png_uint_32)(sizeof (png_dsort)));
621
622
 
623
                         break;
624
625
 
626
                     t->left = (png_byte)i;
627
                     t->right = (png_byte)j;
628
                     hash[d] = t;
629
                  }
630
               }
631
               if (t == NULL)
632
                  break;
633
            }
634
635
 
636
            for (i = 0; i <= max_d; i++)
637
            {
638
               if (hash[i] != NULL)
639
               {
640
                  png_dsortp p;
641
642
 
643
                  {
644
                     if ((int)png_ptr->index_to_palette[p->left]
645
                         < num_new_palette &&
646
                         (int)png_ptr->index_to_palette[p->right]
647
                         < num_new_palette)
648
                     {
649
                        int j, next_j;
650
651
 
652
                        {
653
                           j = p->left;
654
                           next_j = p->right;
655
                        }
656
                        else
657
                        {
658
                           j = p->right;
659
                           next_j = p->left;
660
                        }
661
662
 
663
                        palette[png_ptr->index_to_palette[j]]
664
                            = palette[num_new_palette];
665
                        if (!full_quantize)
666
                        {
667
                           int k;
668
669
 
670
                           {
671
                              if (png_ptr->quantize_index[k] ==
672
                                  png_ptr->index_to_palette[j])
673
                                 png_ptr->quantize_index[k] =
674
                                     png_ptr->index_to_palette[next_j];
675
676
 
677
                                  num_new_palette)
678
                                 png_ptr->quantize_index[k] =
679
                                     png_ptr->index_to_palette[j];
680
                           }
681
                        }
682
683
 
684
                            [num_new_palette]] = png_ptr->index_to_palette[j];
685
686
 
687
                            = png_ptr->palette_to_index[num_new_palette];
688
689
 
690
                            (png_byte)num_new_palette;
691
692
 
693
                            (png_byte)j;
694
                     }
695
                     if (num_new_palette <= maximum_colors)
696
                        break;
697
                  }
698
                  if (num_new_palette <= maximum_colors)
699
                     break;
700
               }
701
            }
702
703
 
704
            {
705
               if (hash[i] != NULL)
706
               {
707
                  png_dsortp p = hash[i];
708
                  while (p)
709
                  {
710
                     t = p->next;
711
                     png_free(png_ptr, p);
712
                     p = t;
713
                  }
714
               }
715
               hash[i] = 0;
716
            }
717
            max_d += 96;
718
         }
719
         png_free(png_ptr, hash);
720
         png_free(png_ptr, png_ptr->palette_to_index);
721
         png_free(png_ptr, png_ptr->index_to_palette);
722
         png_ptr->palette_to_index = NULL;
723
         png_ptr->index_to_palette = NULL;
724
      }
725
      num_palette = maximum_colors;
726
   }
727
   if (png_ptr->palette == NULL)
728
   {
729
      png_ptr->palette = palette;
730
   }
731
   png_ptr->num_palette = (png_uint_16)num_palette;
732
733
 
734
   {
735
      int i;
736
      png_bytep distance;
737
      int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
738
          PNG_QUANTIZE_BLUE_BITS;
739
      int num_red = (1 << PNG_QUANTIZE_RED_BITS);
740
      int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
741
      int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
742
      png_size_t num_entries = ((png_size_t)1 << total_bits);
743
744
 
745
          (png_uint_32)(num_entries * (sizeof (png_byte))));
746
747
 
748
          (sizeof (png_byte))));
749
750
 
751
752
 
753
      {
754
         int ir, ig, ib;
755
         int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
756
         int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
757
         int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
758
759
 
760
         {
761
            /* int dr = abs(ir - r); */
762
            int dr = ((ir > r) ? ir - r : r - ir);
763
            int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
764
                PNG_QUANTIZE_GREEN_BITS));
765
766
 
767
            {
768
               /* int dg = abs(ig - g); */
769
               int dg = ((ig > g) ? ig - g : g - ig);
770
               int dt = dr + dg;
771
               int dm = ((dr > dg) ? dr : dg);
772
               int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
773
774
 
775
               {
776
                  int d_index = index_g | ib;
777
                  /* int db = abs(ib - b); */
778
                  int db = ((ib > b) ? ib - b : b - ib);
779
                  int dmax = ((dm > db) ? dm : db);
780
                  int d = dmax + dt + db;
781
782
 
783
                  {
784
                     distance[d_index] = (png_byte)d;
785
                     png_ptr->palette_lookup[d_index] = (png_byte)i;
786
                  }
787
               }
788
            }
789
         }
790
      }
791
792
 
793
   }
794
}
795
#endif /* PNG_READ_QUANTIZE_SUPPORTED */
796
797
 
798
void PNGFAPI
799
png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
800
   png_fixed_point file_gamma)
801
{
802
   png_debug(1, "in png_set_gamma_fixed");
803
804
 
805
      return;
806
807
 
808
   scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
809
   file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
810
811
 
812
    * premultiplied alpha support; this actually hides an undocumented feature
813
    * of the previous implementation which allowed gamma processing to be
814
    * disabled in background handling.  There is no evidence (so far) that this
815
    * was being used; however, png_set_background itself accepted and must still
816
    * accept '0' for the gamma value it takes, because it isn't always used.
817
    *
818
    * Since this is an API change (albeit a very minor one that removes an
819
    * undocumented API feature) the following checks were only enabled in
820
    * libpng-1.6.0.
821
    */
822
   if (file_gamma <= 0)
823
      png_error(png_ptr, "invalid file gamma in png_set_gamma");
824
825
 
826
      png_error(png_ptr, "invalid screen gamma in png_set_gamma");
827
828
 
829
    * file if a gAMA chunk was present.  png_set_alpha_mode provides a
830
    * different, easier, way to default the file gamma.
831
    */
832
   png_ptr->colorspace.gamma = file_gamma;
833
   png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
834
   png_ptr->screen_gamma = scrn_gamma;
835
}
836
837
 
838
void PNGAPI
839
png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
840
{
841
   png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
842
      convert_gamma_value(png_ptr, file_gamma));
843
}
844
#  endif /* FLOATING_POINT_SUPPORTED */
845
#endif /* READ_GAMMA */
846
847
 
848
/* Expand paletted images to RGB, expand grayscale images of
849
 * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
850
 * to alpha channels.
851
 */
852
void PNGAPI
853
png_set_expand(png_structrp png_ptr)
854
{
855
   png_debug(1, "in png_set_expand");
856
857
 
858
      return;
859
860
 
861
}
862
863
 
864
 *  to png_set_expand().  However, it is entirely reasonable that someone
865
 *  might wish to expand an indexed image to RGB but *not* expand a single,
866
 *  fully transparent palette entry to a full alpha channel--perhaps instead
867
 *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
868
 *  the transparent color with a particular RGB value, or drop tRNS entirely.
869
 *  IOW, a future version of the library may make the transformations flag
870
 *  a bit more fine-grained, with separate bits for each of these three
871
 *  functions.
872
 *
873
 *  More to the point, these functions make it obvious what libpng will be
874
 *  doing, whereas "expand" can (and does) mean any number of things.
875
 *
876
 *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
877
 *  to expand only the sample depth but not to expand the tRNS to alpha
878
 *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
879
 */
880
881
 
882
void PNGAPI
883
png_set_palette_to_rgb(png_structrp png_ptr)
884
{
885
   png_debug(1, "in png_set_palette_to_rgb");
886
887
 
888
      return;
889
890
 
891
}
892
893
 
894
void PNGAPI
895
png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
896
{
897
   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
898
899
 
900
      return;
901
902
 
903
}
904
905
 
906
void PNGAPI
907
png_set_tRNS_to_alpha(png_structrp png_ptr)
908
{
909
   png_debug(1, "in png_set_tRNS_to_alpha");
910
911
 
912
      return;
913
914
 
915
}
916
#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
917
918
 
919
/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
920
 * it may not work correctly.)
921
 */
922
void PNGAPI
923
png_set_expand_16(png_structrp png_ptr)
924
{
925
   png_debug(1, "in png_set_expand_16");
926
927
 
928
      return;
929
930
 
931
}
932
#endif
933
934
 
935
void PNGAPI
936
png_set_gray_to_rgb(png_structrp png_ptr)
937
{
938
   png_debug(1, "in png_set_gray_to_rgb");
939
940
 
941
      return;
942
943
 
944
   png_set_expand_gray_1_2_4_to_8(png_ptr);
945
   png_ptr->transformations |= PNG_GRAY_TO_RGB;
946
}
947
#endif
948
949
 
950
void PNGFAPI
951
png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
952
    png_fixed_point red, png_fixed_point green)
953
{
954
   png_debug(1, "in png_set_rgb_to_gray");
955
956
 
957
   /* TODO: fix this */
958
   if (!png_rtran_ok(png_ptr, 1))
959
      return;
960
961
 
962
   {
963
      case PNG_ERROR_ACTION_NONE:
964
         png_ptr->transformations |= PNG_RGB_TO_GRAY;
965
         break;
966
967
 
968
         png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
969
         break;
970
971
 
972
         png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
973
         break;
974
975
 
976
         png_error(png_ptr, "invalid error action to rgb_to_gray");
977
         break;
978
   }
979
980
 
981
#ifdef PNG_READ_EXPAND_SUPPORTED
982
      png_ptr->transformations |= PNG_EXPAND;
983
#else
984
   {
985
      /* Make this an error in 1.6 because otherwise the application may assume
986
       * that it just worked and get a memory overwrite.
987
       */
988
      png_error(png_ptr,
989
        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
990
991
 
992
   }
993
#endif
994
   {
995
      if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
996
      {
997
         png_uint_16 red_int, green_int;
998
999
 
1000
          * for consistency, the inaccuracy is very small.  The code here always
1001
          * overwrites the coefficients, regardless of whether they have been
1002
          * defaulted or set already.
1003
          */
1004
         red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
1005
         green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
1006
1007
 
1008
         png_ptr->rgb_to_gray_green_coeff = green_int;
1009
         png_ptr->rgb_to_gray_coefficients_set = 1;
1010
      }
1011
1012
 
1013
      {
1014
         if (red >= 0 && green >= 0)
1015
            png_app_warning(png_ptr,
1016
               "ignoring out of range rgb_to_gray coefficients");
1017
1018
 
1019
          * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
1020
          * png_do_rgb_to_gray for more discussion of the values.  In this case
1021
          * the coefficients are not marked as 'set' and are not overwritten if
1022
          * something has already provided a default.
1023
          */
1024
         if (png_ptr->rgb_to_gray_red_coeff == 0 &&
1025
            png_ptr->rgb_to_gray_green_coeff == 0)
1026
         {
1027
            png_ptr->rgb_to_gray_red_coeff   = 6968;
1028
            png_ptr->rgb_to_gray_green_coeff = 23434;
1029
            /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
1030
         }
1031
      }
1032
   }
1033
}
1034
1035
 
1036
/* Convert a RGB image to a grayscale of the same width.  This allows us,
1037
 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
1038
 */
1039
1040
 
1041
png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
1042
   double green)
1043
{
1044
   png_set_rgb_to_gray_fixed(png_ptr, error_action,
1045
      png_fixed(png_ptr, red, "rgb to gray red coefficient"),
1046
      png_fixed(png_ptr, green, "rgb to gray green coefficient"));
1047
}
1048
#endif /* FLOATING POINT */
1049
1050
 
1051
1052
 
1053
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1054
void PNGAPI
1055
png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
1056
    read_user_transform_fn)
1057
{
1058
   png_debug(1, "in png_set_read_user_transform_fn");
1059
1060
 
1061
   png_ptr->transformations |= PNG_USER_TRANSFORM;
1062
   png_ptr->read_user_transform_fn = read_user_transform_fn;
1063
#endif
1064
}
1065
#endif
1066
1067
 
1068
#ifdef PNG_READ_GAMMA_SUPPORTED
1069
/* In the case of gamma transformations only do transformations on images where
1070
 * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
1071
 * slows things down slightly, and also needlessly introduces small errors.
1072
 */
1073
static int /* PRIVATE */
1074
png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
1075
{
1076
   /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
1077
    * correction as a difference of the overall transform from 1.0
1078
    *
1079
    * We want to compare the threshold with s*f - 1, if we get
1080
    * overflow here it is because of wacky gamma values so we
1081
    * turn on processing anyway.
1082
    */
1083
   png_fixed_point gtest;
1084
   return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) ||
1085
       png_gamma_significant(gtest);
1086
}
1087
#endif
1088
1089
 
1090
 * the palette.
1091
 */
1092
1093
 
1094
 * 'png_init_rgb_transformations' only do some flag canceling optimizations.
1095
 * The intent is that these two routines should have palette or rgb operations
1096
 * extracted from 'png_init_read_transformations'.
1097
 */
1098
static void /* PRIVATE */
1099
png_init_palette_transformations(png_structrp png_ptr)
1100
{
1101
   /* Called to handle the (input) palette case.  In png_do_read_transformations
1102
    * the first step is to expand the palette if requested, so this code must
1103
    * take care to only make changes that are invariant with respect to the
1104
    * palette expansion, or only do them if there is no expansion.
1105
    *
1106
    * STRIP_ALPHA has already been handled in the caller (by setting num_trans
1107
    * to 0.)
1108
    */
1109
   int input_has_alpha = 0;
1110
   int input_has_transparency = 0;
1111
1112
 
1113
   {
1114
      int i;
1115
1116
 
1117
      for (i=0; inum_trans; ++i)
1118
      {
1119
         if (png_ptr->trans_alpha[i] == 255)
1120
            continue;
1121
         else if (png_ptr->trans_alpha[i] == 0)
1122
            input_has_transparency = 1;
1123
         else
1124
         {
1125
            input_has_transparency = 1;
1126
            input_has_alpha = 1;
1127
            break;
1128
         }
1129
      }
1130
   }
1131
1132
 
1133
   if (!input_has_alpha)
1134
   {
1135
      /* Any alpha means background and associative alpha processing is
1136
       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
1137
       * and ENCODE_ALPHA are irrelevant.
1138
       */
1139
      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1140
      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1141
1142
 
1143
         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1144
   }
1145
1146
 
1147
   /* png_set_background handling - deals with the complexity of whether the
1148
    * background color is in the file format or the screen format in the case
1149
    * where an 'expand' will happen.
1150
    */
1151
1152
 
1153
    * because PNG_BACKGROUND_EXPAND is cancelled below.
1154
    */
1155
   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1156
       (png_ptr->transformations & PNG_EXPAND))
1157
   {
1158
      {
1159
         png_ptr->background.red   =
1160
             png_ptr->palette[png_ptr->background.index].red;
1161
         png_ptr->background.green =
1162
             png_ptr->palette[png_ptr->background.index].green;
1163
         png_ptr->background.blue  =
1164
             png_ptr->palette[png_ptr->background.index].blue;
1165
1166
 
1167
        if (png_ptr->transformations & PNG_INVERT_ALPHA)
1168
        {
1169
           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
1170
           {
1171
              /* Invert the alpha channel (in tRNS) unless the pixels are
1172
               * going to be expanded, in which case leave it for later
1173
               */
1174
              int i, istop = png_ptr->num_trans;
1175
1176
 
1177
                 png_ptr->trans_alpha[i] = (png_byte)(255 -
1178
                    png_ptr->trans_alpha[i]);
1179
           }
1180
        }
1181
#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
1182
      }
1183
   } /* background expand and (therefore) no alpha association. */
1184
#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
1185
}
1186
1187
 
1188
png_init_rgb_transformations(png_structrp png_ptr)
1189
{
1190
   /* Added to libpng-1.5.4: check the color type to determine whether there
1191
    * is any alpha or transparency in the image and simply cancel the
1192
    * background and alpha mode stuff if there isn't.
1193
    */
1194
   int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
1195
   int input_has_transparency = png_ptr->num_trans > 0;
1196
1197
 
1198
   if (!input_has_alpha)
1199
   {
1200
      /* Any alpha means background and associative alpha processing is
1201
       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
1202
       * and ENCODE_ALPHA are irrelevant.
1203
       */
1204
#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1205
         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1206
         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1207
#     endif
1208
1209
 
1210
         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1211
   }
1212
1213
 
1214
   /* png_set_background handling - deals with the complexity of whether the
1215
    * background color is in the file format or the screen format in the case
1216
    * where an 'expand' will happen.
1217
    */
1218
1219
 
1220
    * because PNG_BACKGROUND_EXPAND is cancelled below.
1221
    */
1222
   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1223
       (png_ptr->transformations & PNG_EXPAND) &&
1224
       !(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
1225
       /* i.e., GRAY or GRAY_ALPHA */
1226
   {
1227
      {
1228
         /* Expand background and tRNS chunks */
1229
         int gray = png_ptr->background.gray;
1230
         int trans_gray = png_ptr->trans_color.gray;
1231
1232
 
1233
         {
1234
            case 1:
1235
               gray *= 0xff;
1236
               trans_gray *= 0xff;
1237
               break;
1238
1239
 
1240
               gray *= 0x55;
1241
               trans_gray *= 0x55;
1242
               break;
1243
1244
 
1245
               gray *= 0x11;
1246
               trans_gray *= 0x11;
1247
               break;
1248
1249
 
1250
1251
 
1252
               /* FALL THROUGH (Already 8 bits) */
1253
1254
 
1255
               /* Already a full 16 bits */
1256
               break;
1257
         }
1258
1259
 
1260
            png_ptr->background.blue = (png_uint_16)gray;
1261
1262
 
1263
         {
1264
            png_ptr->trans_color.red = png_ptr->trans_color.green =
1265
               png_ptr->trans_color.blue = (png_uint_16)trans_gray;
1266
         }
1267
      }
1268
   } /* background expand and (therefore) no alpha association. */
1269
#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
1270
}
1271
1272
 
1273
png_init_read_transformations(png_structrp png_ptr)
1274
{
1275
   png_debug(1, "in png_init_read_transformations");
1276
1277
 
1278
    * and it is called before the 'rowbytes' calculation is done, so the code
1279
    * in here can change or update the transformations flags.
1280
    *
1281
    * First do updates that do not depend on the details of the PNG image data
1282
    * being processed.
1283
    */
1284
1285
 
1286
   /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
1287
    * png_set_alpha_mode and this is another source for a default file gamma so
1288
    * the test needs to be performed later - here.  In addition prior to 1.5.4
1289
    * the tests were repeated for the PALETTE color type here - this is no
1290
    * longer necessary (and doesn't seem to have been necessary before.)
1291
    */
1292
   {
1293
      /* The following temporary indicates if overall gamma correction is
1294
       * required.
1295
       */
1296
      int gamma_correction = 0;
1297
1298
 
1299
      {
1300
         if (png_ptr->screen_gamma != 0) /* screen set too */
1301
            gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
1302
               png_ptr->screen_gamma);
1303
1304
 
1305
            /* Assume the output matches the input; a long time default behavior
1306
             * of libpng, although the standard has nothing to say about this.
1307
             */
1308
            png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
1309
      }
1310
1311
 
1312
         /* The converse - assume the file matches the screen, note that this
1313
          * perhaps undesireable default can (from 1.5.4) be changed by calling
1314
          * png_set_alpha_mode (even if the alpha handling mode isn't required
1315
          * or isn't changed from the default.)
1316
          */
1317
         png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
1318
1319
 
1320
         /* Just in case the following prevents any processing - file and screen
1321
          * are both assumed to be linear and there is no way to introduce a
1322
          * third gamma value other than png_set_background with 'UNIQUE', and,
1323
          * prior to 1.5.4
1324
          */
1325
         png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
1326
1327
 
1328
      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
1329
1330
 
1331
       * that PNG_GAMMA just refers to the file->screen correction.  Alpha
1332
       * composition may independently cause gamma correction because it needs
1333
       * linear data (e.g. if the file has a gAMA chunk but the screen gamma
1334
       * hasn't been specified.)  In any case this flag may get turned off in
1335
       * the code immediately below if the transform can be handled outside the
1336
       * row loop.
1337
       */
1338
      if (gamma_correction)
1339
         png_ptr->transformations |= PNG_GAMMA;
1340
1341
 
1342
         png_ptr->transformations &= ~PNG_GAMMA;
1343
   }
1344
#endif
1345
1346
 
1347
    * transformations that happen afterward in png_do_read_transformations,
1348
    * resolve the interdependencies here.  From the code of
1349
    * png_do_read_transformations the order is:
1350
    *
1351
    *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
1352
    *  2) PNG_STRIP_ALPHA (if no compose)
1353
    *  3) PNG_RGB_TO_GRAY
1354
    *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
1355
    *  5) PNG_COMPOSE
1356
    *  6) PNG_GAMMA
1357
    *  7) PNG_STRIP_ALPHA (if compose)
1358
    *  8) PNG_ENCODE_ALPHA
1359
    *  9) PNG_SCALE_16_TO_8
1360
    * 10) PNG_16_TO_8
1361
    * 11) PNG_QUANTIZE (converts to palette)
1362
    * 12) PNG_EXPAND_16
1363
    * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
1364
    * 14) PNG_INVERT_MONO
1365
    * 15) PNG_SHIFT
1366
    * 16) PNG_PACK
1367
    * 17) PNG_BGR
1368
    * 18) PNG_PACKSWAP
1369
    * 19) PNG_FILLER (includes PNG_ADD_ALPHA)
1370
    * 20) PNG_INVERT_ALPHA
1371
    * 21) PNG_SWAP_ALPHA
1372
    * 22) PNG_SWAP_BYTES
1373
    * 23) PNG_USER_TRANSFORM [must be last]
1374
    */
1375
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1376
   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
1377
      !(png_ptr->transformations & PNG_COMPOSE))
1378
   {
1379
      /* Stripping the alpha channel happens immediately after the 'expand'
1380
       * transformations, before all other transformation, so it cancels out
1381
       * the alpha handling.  It has the side effect negating the effect of
1382
       * PNG_EXPAND_tRNS too:
1383
       */
1384
      png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
1385
         PNG_EXPAND_tRNS);
1386
      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1387
1388
 
1389
       * so transparency information would remain just so long as it wasn't
1390
       * expanded.  This produces unexpected API changes if the set of things
1391
       * that do PNG_EXPAND_tRNS changes (perfectly possible given the
1392
       * documentation - which says ask for what you want, accept what you
1393
       * get.)  This makes the behavior consistent from 1.5.4:
1394
       */
1395
      png_ptr->num_trans = 0;
1396
   }
1397
#endif /* STRIP_ALPHA supported, no COMPOSE */
1398
1399
 
1400
   /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
1401
    * settings will have no effect.
1402
    */
1403
   if (!png_gamma_significant(png_ptr->screen_gamma))
1404
   {
1405
      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1406
      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1407
   }
1408
#endif
1409
1410
 
1411
   /* Make sure the coefficients for the rgb to gray conversion are set
1412
    * appropriately.
1413
    */
1414
   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1415
      png_colorspace_set_rgb_coefficients(png_ptr);
1416
#endif
1417
1418
 
1419
#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1420
   /* Detect gray background and attempt to enable optimization for
1421
    * gray --> RGB case.
1422
    *
1423
    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
1424
    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
1425
    * background color might actually be gray yet not be flagged as such.
1426
    * This is not a problem for the current code, which uses
1427
    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
1428
    * png_do_gray_to_rgb() transformation.
1429
    *
1430
    * TODO: this code needs to be revised to avoid the complexity and
1431
    * interdependencies.  The color type of the background should be recorded in
1432
    * png_set_background, along with the bit depth, then the code has a record
1433
    * of exactly what color space the background is currently in.
1434
    */
1435
   if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
1436
   {
1437
      /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
1438
       * the file was grayscale the background value is gray.
1439
       */
1440
      if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
1441
         png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1442
   }
1443
1444
 
1445
   {
1446
      /* PNG_COMPOSE: png_set_background was called with need_expand false,
1447
       * so the color is in the color space of the output or png_set_alpha_mode
1448
       * was called and the color is black.  Ignore RGB_TO_GRAY because that
1449
       * happens before GRAY_TO_RGB.
1450
       */
1451
      if (png_ptr->transformations & PNG_GRAY_TO_RGB)
1452
      {
1453
         if (png_ptr->background.red == png_ptr->background.green &&
1454
             png_ptr->background.red == png_ptr->background.blue)
1455
         {
1456
            png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1457
            png_ptr->background.gray = png_ptr->background.red;
1458
         }
1459
      }
1460
   }
1461
#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
1462
#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
1463
1464
 
1465
    * can be performed directly on the palette, and some (such as rgb to gray)
1466
    * can be optimized inside the palette.  This is particularly true of the
1467
    * composite (background and alpha) stuff, which can be pretty much all done
1468
    * in the palette even if the result is expanded to RGB or gray afterward.
1469
    *
1470
    * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
1471
    * earlier and the palette stuff is actually handled on the first row.  This
1472
    * leads to the reported bug that the palette returned by png_get_PLTE is not
1473
    * updated.
1474
    */
1475
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1476
      png_init_palette_transformations(png_ptr);
1477
1478
 
1479
      png_init_rgb_transformations(png_ptr);
1480
1481
 
1482
   defined(PNG_READ_EXPAND_16_SUPPORTED)
1483
   if ((png_ptr->transformations & PNG_EXPAND_16) &&
1484
      (png_ptr->transformations & PNG_COMPOSE) &&
1485
      !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1486
      png_ptr->bit_depth != 16)
1487
   {
1488
      /* TODO: fix this.  Because the expand_16 operation is after the compose
1489
       * handling the background color must be 8, not 16, bits deep, but the
1490
       * application will supply a 16-bit value so reduce it here.
1491
       *
1492
       * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
1493
       * present, so that case is ok (until do_expand_16 is moved.)
1494
       *
1495
       * NOTE: this discards the low 16 bits of the user supplied background
1496
       * color, but until expand_16 works properly there is no choice!
1497
       */
1498
#     define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
1499
      CHOP(png_ptr->background.red);
1500
      CHOP(png_ptr->background.green);
1501
      CHOP(png_ptr->background.blue);
1502
      CHOP(png_ptr->background.gray);
1503
#     undef CHOP
1504
   }
1505
#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */
1506
1507
 
1508
   (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
1509
   defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
1510
   if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) &&
1511
      (png_ptr->transformations & PNG_COMPOSE) &&
1512
      !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1513
      png_ptr->bit_depth == 16)
1514
   {
1515
      /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
1516
       * component this will also happen after PNG_COMPOSE and so the background
1517
       * color must be pre-expanded here.
1518
       *
1519
       * TODO: fix this too.
1520
       */
1521
      png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
1522
      png_ptr->background.green =
1523
         (png_uint_16)(png_ptr->background.green * 257);
1524
      png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
1525
      png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
1526
   }
1527
#endif
1528
1529
 
1530
    * background support (see the comments in scripts/pnglibconf.dfa), this
1531
    * allows pre-multiplication of the alpha channel to be implemented as
1532
    * compositing on black.  This is probably sub-optimal and has been done in
1533
    * 1.5.4 betas simply to enable external critique and testing (i.e. to
1534
    * implement the new API quickly, without lots of internal changes.)
1535
    */
1536
1537
 
1538
#  ifdef PNG_READ_BACKGROUND_SUPPORTED
1539
      /* Includes ALPHA_MODE */
1540
      png_ptr->background_1 = png_ptr->background;
1541
#  endif
1542
1543
 
1544
    * built when it would be quicker to just calculate the correct value for
1545
    * each palette entry directly.  Also, the test is too tricky - why check
1546
    * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that
1547
    * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the
1548
    * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
1549
    * the gamma tables will not be built even if composition is required on a
1550
    * gamma encoded value.
1551
    *
1552
    * In 1.5.4 this is addressed below by an additional check on the individual
1553
    * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
1554
    * tables.
1555
    */
1556
   if ((png_ptr->transformations & PNG_GAMMA)
1557
      || ((png_ptr->transformations & PNG_RGB_TO_GRAY)
1558
         && (png_gamma_significant(png_ptr->colorspace.gamma) ||
1559
            png_gamma_significant(png_ptr->screen_gamma)))
1560
      || ((png_ptr->transformations & PNG_COMPOSE)
1561
         && (png_gamma_significant(png_ptr->colorspace.gamma)
1562
            || png_gamma_significant(png_ptr->screen_gamma)
1563
#  ifdef PNG_READ_BACKGROUND_SUPPORTED
1564
            || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE
1565
               && png_gamma_significant(png_ptr->background_gamma))
1566
#  endif
1567
      )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA)
1568
         && png_gamma_significant(png_ptr->screen_gamma))
1569
      )
1570
   {
1571
      png_build_gamma_table(png_ptr, png_ptr->bit_depth);
1572
1573
 
1574
      if (png_ptr->transformations & PNG_COMPOSE)
1575
      {
1576
         /* Issue a warning about this combination: because RGB_TO_GRAY is
1577
          * optimized to do the gamma transform if present yet do_background has
1578
          * to do the same thing if both options are set a
1579
          * double-gamma-correction happens.  This is true in all versions of
1580
          * libpng to date.
1581
          */
1582
         if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1583
            png_warning(png_ptr,
1584
               "libpng does not support gamma+background+rgb_to_gray");
1585
1586
 
1587
         {
1588
            /* We don't get to here unless there is a tRNS chunk with non-opaque
1589
             * entries - see the checking code at the start of this function.
1590
             */
1591
            png_color back, back_1;
1592
            png_colorp palette = png_ptr->palette;
1593
            int num_palette = png_ptr->num_palette;
1594
            int i;
1595
            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
1596
            {
1597
1598
 
1599
               back.green = png_ptr->gamma_table[png_ptr->background.green];
1600
               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
1601
1602
 
1603
               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
1604
               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
1605
            }
1606
            else
1607
            {
1608
               png_fixed_point g, gs;
1609
1610
 
1611
               {
1612
                  case PNG_BACKGROUND_GAMMA_SCREEN:
1613
                     g = (png_ptr->screen_gamma);
1614
                     gs = PNG_FP_1;
1615
                     break;
1616
1617
 
1618
                     g = png_reciprocal(png_ptr->colorspace.gamma);
1619
                     gs = png_reciprocal2(png_ptr->colorspace.gamma,
1620
                        png_ptr->screen_gamma);
1621
                     break;
1622
1623
 
1624
                     g = png_reciprocal(png_ptr->background_gamma);
1625
                     gs = png_reciprocal2(png_ptr->background_gamma,
1626
                        png_ptr->screen_gamma);
1627
                     break;
1628
                  default:
1629
                     g = PNG_FP_1;    /* back_1 */
1630
                     gs = PNG_FP_1;   /* back */
1631
                     break;
1632
               }
1633
1634
 
1635
               {
1636
                  back.red = png_gamma_8bit_correct(png_ptr->background.red,
1637
                      gs);
1638
                  back.green = png_gamma_8bit_correct(png_ptr->background.green,
1639
                      gs);
1640
                  back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1641
                      gs);
1642
               }
1643
1644
 
1645
               {
1646
                  back.red   = (png_byte)png_ptr->background.red;
1647
                  back.green = (png_byte)png_ptr->background.green;
1648
                  back.blue  = (png_byte)png_ptr->background.blue;
1649
               }
1650
1651
 
1652
               {
1653
                  back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
1654
                     g);
1655
                  back_1.green = png_gamma_8bit_correct(
1656
                     png_ptr->background.green, g);
1657
                  back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1658
                     g);
1659
               }
1660
1661
 
1662
               {
1663
                  back_1.red   = (png_byte)png_ptr->background.red;
1664
                  back_1.green = (png_byte)png_ptr->background.green;
1665
                  back_1.blue  = (png_byte)png_ptr->background.blue;
1666
               }
1667
            }
1668
1669
 
1670
            {
1671
               if (i < (int)png_ptr->num_trans &&
1672
                   png_ptr->trans_alpha[i] != 0xff)
1673
               {
1674
                  if (png_ptr->trans_alpha[i] == 0)
1675
                  {
1676
                     palette[i] = back;
1677
                  }
1678
                  else /* if (png_ptr->trans_alpha[i] != 0xff) */
1679
                  {
1680
                     png_byte v, w;
1681
1682
 
1683
                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
1684
                     palette[i].red = png_ptr->gamma_from_1[w];
1685
1686
 
1687
                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
1688
                     palette[i].green = png_ptr->gamma_from_1[w];
1689
1690
 
1691
                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
1692
                     palette[i].blue = png_ptr->gamma_from_1[w];
1693
                  }
1694
               }
1695
               else
1696
               {
1697
                  palette[i].red = png_ptr->gamma_table[palette[i].red];
1698
                  palette[i].green = png_ptr->gamma_table[palette[i].green];
1699
                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1700
               }
1701
            }
1702
1703
 
1704
             *
1705
             * NOTE: this is highly dubious; it removes the transformations in
1706
             * place.  This seems inconsistent with the general treatment of the
1707
             * transformations elsewhere.
1708
             */
1709
            png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
1710
         } /* color_type == PNG_COLOR_TYPE_PALETTE */
1711
1712
 
1713
         else /* color_type != PNG_COLOR_TYPE_PALETTE */
1714
         {
1715
            int gs_sig, g_sig;
1716
            png_fixed_point g = PNG_FP_1;  /* Correction to linear */
1717
            png_fixed_point gs = PNG_FP_1; /* Correction to screen */
1718
1719
 
1720
            {
1721
               case PNG_BACKGROUND_GAMMA_SCREEN:
1722
                  g = png_ptr->screen_gamma;
1723
                  /* gs = PNG_FP_1; */
1724
                  break;
1725
1726
 
1727
                  g = png_reciprocal(png_ptr->colorspace.gamma);
1728
                  gs = png_reciprocal2(png_ptr->colorspace.gamma,
1729
                     png_ptr->screen_gamma);
1730
                  break;
1731
1732
 
1733
                  g = png_reciprocal(png_ptr->background_gamma);
1734
                  gs = png_reciprocal2(png_ptr->background_gamma,
1735
                      png_ptr->screen_gamma);
1736
                  break;
1737
1738
 
1739
                  png_error(png_ptr, "invalid background gamma type");
1740
            }
1741
1742
 
1743
            gs_sig = png_gamma_significant(gs);
1744
1745
 
1746
               png_ptr->background_1.gray = png_gamma_correct(png_ptr,
1747
                   png_ptr->background.gray, g);
1748
1749
 
1750
               png_ptr->background.gray = png_gamma_correct(png_ptr,
1751
                   png_ptr->background.gray, gs);
1752
1753
 
1754
                (png_ptr->background.red != png_ptr->background.blue) ||
1755
                (png_ptr->background.red != png_ptr->background.gray))
1756
            {
1757
               /* RGB or RGBA with color background */
1758
               if (g_sig)
1759
               {
1760
                  png_ptr->background_1.red = png_gamma_correct(png_ptr,
1761
                      png_ptr->background.red, g);
1762
1763
 
1764
                      png_ptr->background.green, g);
1765
1766
 
1767
                      png_ptr->background.blue, g);
1768
               }
1769
1770
 
1771
               {
1772
                  png_ptr->background.red = png_gamma_correct(png_ptr,
1773
                      png_ptr->background.red, gs);
1774
1775
 
1776
                      png_ptr->background.green, gs);
1777
1778
 
1779
                      png_ptr->background.blue, gs);
1780
               }
1781
            }
1782
1783
 
1784
            {
1785
               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1786
               png_ptr->background_1.red = png_ptr->background_1.green
1787
                   = png_ptr->background_1.blue = png_ptr->background_1.gray;
1788
1789
 
1790
                   = png_ptr->background.blue = png_ptr->background.gray;
1791
            }
1792
1793
 
1794
            png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
1795
         } /* color_type != PNG_COLOR_TYPE_PALETTE */
1796
      }/* png_ptr->transformations & PNG_BACKGROUND */
1797
1798
 
1799
      /* Transformation does not include PNG_BACKGROUND */
1800
#endif /* PNG_READ_BACKGROUND_SUPPORTED */
1801
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
1802
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1803
         /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
1804
         && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
1805
         (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
1806
#endif
1807
         )
1808
      {
1809
         png_colorp palette = png_ptr->palette;
1810
         int num_palette = png_ptr->num_palette;
1811
         int i;
1812
1813
 
1814
          * here too.
1815
          */
1816
         for (i = 0; i < num_palette; i++)
1817
         {
1818
            palette[i].red = png_ptr->gamma_table[palette[i].red];
1819
            palette[i].green = png_ptr->gamma_table[palette[i].green];
1820
            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1821
         }
1822
1823
 
1824
         png_ptr->transformations &= ~PNG_GAMMA;
1825
      } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
1826
   }
1827
#ifdef PNG_READ_BACKGROUND_SUPPORTED
1828
   else
1829
#endif
1830
#endif /* PNG_READ_GAMMA_SUPPORTED */
1831
1832
 
1833
   /* No GAMMA transformation (see the hanging else 4 lines above) */
1834
   if ((png_ptr->transformations & PNG_COMPOSE) &&
1835
       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1836
   {
1837
      int i;
1838
      int istop = (int)png_ptr->num_trans;
1839
      png_color back;
1840
      png_colorp palette = png_ptr->palette;
1841
1842
 
1843
      back.green = (png_byte)png_ptr->background.green;
1844
      back.blue  = (png_byte)png_ptr->background.blue;
1845
1846
 
1847
      {
1848
         if (png_ptr->trans_alpha[i] == 0)
1849
         {
1850
            palette[i] = back;
1851
         }
1852
1853
 
1854
         {
1855
            /* The png_composite() macro is defined in png.h */
1856
            png_composite(palette[i].red, palette[i].red,
1857
                png_ptr->trans_alpha[i], back.red);
1858
1859
 
1860
                png_ptr->trans_alpha[i], back.green);
1861
1862
 
1863
                png_ptr->trans_alpha[i], back.blue);
1864
         }
1865
      }
1866
1867
 
1868
   }
1869
#endif /* PNG_READ_BACKGROUND_SUPPORTED */
1870
1871
 
1872
   if ((png_ptr->transformations & PNG_SHIFT) &&
1873
      !(png_ptr->transformations & PNG_EXPAND) &&
1874
       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1875
   {
1876
      int i;
1877
      int istop = png_ptr->num_palette;
1878
      int shift = 8 - png_ptr->sig_bit.red;
1879
1880
 
1881
1882
 
1883
       * the number of significant bits is 0 then no shift is done (this is an
1884
       * error condition which is silently ignored.)
1885
       */
1886
      if (shift > 0 && shift < 8)
1887
         for (i=0; i
1888
         {
1889
            int component = png_ptr->palette[i].red;
1890
1891
 
1892
            png_ptr->palette[i].red = (png_byte)component;
1893
         }
1894
1895
 
1896
      if (shift > 0 && shift < 8)
1897
         for (i=0; i
1898
         {
1899
            int component = png_ptr->palette[i].green;
1900
1901
 
1902
            png_ptr->palette[i].green = (png_byte)component;
1903
         }
1904
1905
 
1906
      if (shift > 0 && shift < 8)
1907
         for (i=0; i
1908
         {
1909
            int component = png_ptr->palette[i].blue;
1910
1911
 
1912
            png_ptr->palette[i].blue = (png_byte)component;
1913
         }
1914
   }
1915
#endif  /* PNG_READ_SHIFT_SUPPORTED */
1916
}
1917
1918
 
1919
 * info should be updated so a PNG file could be written with it,
1920
 * assuming the transformations result in valid PNG data.
1921
 */
1922
void /* PRIVATE */
1923
png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
1924
{
1925
   png_debug(1, "in png_read_transform_info");
1926
1927
 
1928
   if (png_ptr->transformations & PNG_EXPAND)
1929
   {
1930
      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1931
      {
1932
         /* This check must match what actually happens in
1933
          * png_do_expand_palette; if it ever checks the tRNS chunk to see if
1934
          * it is all opaque we must do the same (at present it does not.)
1935
          */
1936
         if (png_ptr->num_trans > 0)
1937
            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1938
1939
 
1940
            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
1941
1942
 
1943
         info_ptr->num_trans = 0;
1944
      }
1945
      else
1946
      {
1947
         if (png_ptr->num_trans)
1948
         {
1949
            if (png_ptr->transformations & PNG_EXPAND_tRNS)
1950
               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1951
         }
1952
         if (info_ptr->bit_depth < 8)
1953
            info_ptr->bit_depth = 8;
1954
1955
 
1956
      }
1957
   }
1958
#endif
1959
1960
 
1961
   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
1962
   /* The following is almost certainly wrong unless the background value is in
1963
    * the screen space!
1964
    */
1965
   if (png_ptr->transformations & PNG_COMPOSE)
1966
      info_ptr->background = png_ptr->background;
1967
#endif
1968
1969
 
1970
   /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
1971
    * however it seems that the code in png_init_read_transformations, which has
1972
    * been called before this from png_read_update_info->png_read_start_row
1973
    * sometimes does the gamma transform and cancels the flag.
1974
    *
1975
    * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
1976
    * the screen_gamma value.  The following probably results in weirdness if
1977
    * the info_ptr is used by the app after the rows have been read.
1978
    */
1979
   info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
1980
#endif
1981
1982
 
1983
   {
1984
#  ifdef PNG_READ_16BIT_SUPPORTED
1985
#     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1986
         if (png_ptr->transformations & PNG_SCALE_16_TO_8)
1987
            info_ptr->bit_depth = 8;
1988
#     endif
1989
1990
 
1991
         if (png_ptr->transformations & PNG_16_TO_8)
1992
            info_ptr->bit_depth = 8;
1993
#     endif
1994
1995
 
1996
      /* No 16 bit support: force chopping 16-bit input down to 8, in this case
1997
       * the app program can chose if both APIs are available by setting the
1998
       * correct scaling to use.
1999
       */
2000
#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2001
         /* For compatibility with previous versions use the strip method by
2002
          * default.  This code works because if PNG_SCALE_16_TO_8 is already
2003
          * set the code below will do that in preference to the chop.
2004
          */
2005
         png_ptr->transformations |= PNG_16_TO_8;
2006
         info_ptr->bit_depth = 8;
2007
#     else
2008
2009
 
2010
            png_ptr->transformations |= PNG_SCALE_16_TO_8;
2011
            info_ptr->bit_depth = 8;
2012
#        else
2013
2014
 
2015
#        endif
2016
#    endif
2017
#endif /* !READ_16BIT_SUPPORTED */
2018
   }
2019
2020
 
2021
   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
2022
      info_ptr->color_type = (png_byte)(info_ptr->color_type |
2023
         PNG_COLOR_MASK_COLOR);
2024
#endif
2025
2026
 
2027
   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
2028
      info_ptr->color_type = (png_byte)(info_ptr->color_type &
2029
         ~PNG_COLOR_MASK_COLOR);
2030
#endif
2031
2032
 
2033
   if (png_ptr->transformations & PNG_QUANTIZE)
2034
   {
2035
      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
2036
          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
2037
          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
2038
      {
2039
         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
2040
      }
2041
   }
2042
#endif
2043
2044
 
2045
   if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 &&
2046
      info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
2047
   {
2048
      info_ptr->bit_depth = 16;
2049
   }
2050
#endif
2051
2052
 
2053
   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
2054
      info_ptr->bit_depth = 8;
2055
#endif
2056
2057
 
2058
      info_ptr->channels = 1;
2059
2060
 
2061
      info_ptr->channels = 3;
2062
2063
 
2064
      info_ptr->channels = 1;
2065
2066
 
2067
   if (png_ptr->transformations & PNG_STRIP_ALPHA)
2068
   {
2069
      info_ptr->color_type = (png_byte)(info_ptr->color_type &
2070
         ~PNG_COLOR_MASK_ALPHA);
2071
      info_ptr->num_trans = 0;
2072
   }
2073
#endif
2074
2075
 
2076
      info_ptr->channels++;
2077
2078
 
2079
   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
2080
   if ((png_ptr->transformations & PNG_FILLER) &&
2081
       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
2082
       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
2083
   {
2084
      info_ptr->channels++;
2085
      /* If adding a true alpha channel not just filler */
2086
      if (png_ptr->transformations & PNG_ADD_ALPHA)
2087
         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
2088
   }
2089
#endif
2090
2091
 
2092
defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
2093
   if (png_ptr->transformations & PNG_USER_TRANSFORM)
2094
   {
2095
      if (info_ptr->bit_depth < png_ptr->user_transform_depth)
2096
         info_ptr->bit_depth = png_ptr->user_transform_depth;
2097
2098
 
2099
         info_ptr->channels = png_ptr->user_transform_channels;
2100
   }
2101
#endif
2102
2103
 
2104
       info_ptr->bit_depth);
2105
2106
 
2107
2108
 
2109
    * check in png_rowbytes that the user buffer won't get overwritten.  Note
2110
    * that the field is not always set - if png_read_update_info isn't called
2111
    * the application has to either not do any transforms or get the calculation
2112
    * right itself.
2113
    */
2114
   png_ptr->info_rowbytes = info_ptr->rowbytes;
2115
2116
 
2117
   if (png_ptr)
2118
      return;
2119
#endif
2120
}
2121
2122
 
2123
 * and is very touchy.  If you add a transformation, take care to
2124
 * decide how it fits in with the other transformations here.
2125
 */
2126
void /* PRIVATE */
2127
png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
2128
{
2129
   png_debug(1, "in png_do_read_transformations");
2130
2131
 
2132
   {
2133
      /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
2134
       * error is incredibly rare and incredibly easy to debug without this
2135
       * information.
2136
       */
2137
      png_error(png_ptr, "NULL row buffer");
2138
   }
2139
2140
 
2141
    * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
2142
    * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
2143
    * all transformations, however in practice the ROW_INIT always gets done on
2144
    * demand, if necessary.
2145
    */
2146
   if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
2147
      !(png_ptr->flags & PNG_FLAG_ROW_INIT))
2148
   {
2149
      /* Application has failed to call either png_read_start_image() or
2150
       * png_read_update_info() after setting transforms that expand pixels.
2151
       * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
2152
       */
2153
      png_error(png_ptr, "Uninitialized row");
2154
   }
2155
2156
 
2157
   if (png_ptr->transformations & PNG_EXPAND)
2158
   {
2159
      if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
2160
      {
2161
         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
2162
             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
2163
      }
2164
2165
 
2166
      {
2167
         if (png_ptr->num_trans &&
2168
             (png_ptr->transformations & PNG_EXPAND_tRNS))
2169
            png_do_expand(row_info, png_ptr->row_buf + 1,
2170
                &(png_ptr->trans_color));
2171
2172
 
2173
            png_do_expand(row_info, png_ptr->row_buf + 1,
2174
                NULL);
2175
      }
2176
   }
2177
#endif
2178
2179
 
2180
   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
2181
      !(png_ptr->transformations & PNG_COMPOSE) &&
2182
      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2183
      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2184
      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
2185
         0 /* at_start == false, because SWAP_ALPHA happens later */);
2186
 
2187
2188
 
2189
   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
2190
   {
2191
      int rgb_error =
2192
          png_do_rgb_to_gray(png_ptr, row_info,
2193
              png_ptr->row_buf + 1);
2194
2195
 
2196
      {
2197
         png_ptr->rgb_to_gray_status=1;
2198
         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
2199
             PNG_RGB_TO_GRAY_WARN)
2200
            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
2201
2202
 
2203
             PNG_RGB_TO_GRAY_ERR)
2204
            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
2205
      }
2206
   }
2207
#endif
2208
2209
 
2210
 *
2211
 *   In most cases, the "simple transparency" should be done prior to doing
2212
 *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
2213
 *   pixel is transparent.  You would also need to make sure that the
2214
 *   transparency information is upgraded to RGB.
2215
 *
2216
 *   To summarize, the current flow is:
2217
 *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
2218
 *                                   with background "in place" if transparent,
2219
 *                                   convert to RGB if necessary
2220
 *   - Gray + alpha -> composite with gray background and remove alpha bytes,
2221
 *                                   convert to RGB if necessary
2222
 *
2223
 *   To support RGB backgrounds for gray images we need:
2224
 *   - Gray + simple transparency -> convert to RGB + simple transparency,
2225
 *                                   compare 3 or 6 bytes and composite with
2226
 *                                   background "in place" if transparent
2227
 *                                   (3x compare/pixel compared to doing
2228
 *                                   composite with gray bkgrnd)
2229
 *   - Gray + alpha -> convert to RGB + alpha, composite with background and
2230
 *                                   remove alpha bytes (3x float
2231
 *                                   operations/pixel compared with composite
2232
 *                                   on gray background)
2233
 *
2234
 *  Greg's change will do this.  The reason it wasn't done before is for
2235
 *  performance, as this increases the per-pixel operations.  If we would check
2236
 *  in advance if the background was gray or RGB, and position the gray-to-RGB
2237
 *  transform appropriately, then it would save a lot of work/time.
2238
 */
2239
2240
 
2241
   /* If gray -> RGB, do so now only if background is non-gray; else do later
2242
    * for performance reasons
2243
    */
2244
   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
2245
       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
2246
      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
2247
#endif
2248
2249
 
2250
   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
2251
   if (png_ptr->transformations & PNG_COMPOSE)
2252
      png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
2253
#endif
2254
2255
 
2256
   if ((png_ptr->transformations & PNG_GAMMA) &&
2257
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2258
      /* Because RGB_TO_GRAY does the gamma transform. */
2259
      !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&
2260
#endif
2261
#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
2262
   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
2263
      /* Because PNG_COMPOSE does the gamma transform if there is something to
2264
       * do (if there is an alpha channel or transparency.)
2265
       */
2266
       !((png_ptr->transformations & PNG_COMPOSE) &&
2267
       ((png_ptr->num_trans != 0) ||
2268
       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
2269
#endif
2270
      /* Because png_init_read_transformations transforms the palette, unless
2271
       * RGB_TO_GRAY will do the transform.
2272
       */
2273
       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
2274
      png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
2275
#endif
2276
2277
 
2278
   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
2279
      (png_ptr->transformations & PNG_COMPOSE) &&
2280
      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2281
      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2282
      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
2283
         0 /* at_start == false, because SWAP_ALPHA happens later */);
2284
 
2285
2286
 
2287
   if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&
2288
      (row_info->color_type & PNG_COLOR_MASK_ALPHA))
2289
      png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
2290
#endif
2291
2292
 
2293
   if (png_ptr->transformations & PNG_SCALE_16_TO_8)
2294
      png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
2295
#endif
2296
2297
 
2298
   /* There is no harm in doing both of these because only one has any effect,
2299
    * by putting the 'scale' option first if the app asks for scale (either by
2300
    * calling the API or in a TRANSFORM flag) this is what happens.
2301
    */
2302
   if (png_ptr->transformations & PNG_16_TO_8)
2303
      png_do_chop(row_info, png_ptr->row_buf + 1);
2304
#endif
2305
2306
 
2307
   if (png_ptr->transformations & PNG_QUANTIZE)
2308
   {
2309
      png_do_quantize(row_info, png_ptr->row_buf + 1,
2310
          png_ptr->palette_lookup, png_ptr->quantize_index);
2311
2312
 
2313
         png_error(png_ptr, "png_do_quantize returned rowbytes=0");
2314
   }
2315
#endif /* PNG_READ_QUANTIZE_SUPPORTED */
2316
2317
 
2318
   /* Do the expansion now, after all the arithmetic has been done.  Notice
2319
    * that previous transformations can handle the PNG_EXPAND_16 flag if this
2320
    * is efficient (particularly true in the case of gamma correction, where
2321
    * better accuracy results faster!)
2322
    */
2323
   if (png_ptr->transformations & PNG_EXPAND_16)
2324
      png_do_expand_16(row_info, png_ptr->row_buf + 1);
2325
#endif
2326
2327
 
2328
   /* NOTE: moved here in 1.5.4 (from much later in this list.) */
2329
   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
2330
       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
2331
      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
2332
#endif
2333
2334
 
2335
   if (png_ptr->transformations & PNG_INVERT_MONO)
2336
      png_do_invert(row_info, png_ptr->row_buf + 1);
2337
#endif
2338
2339
 
2340
   if (png_ptr->transformations & PNG_SHIFT)
2341
      png_do_unshift(row_info, png_ptr->row_buf + 1,
2342
          &(png_ptr->shift));
2343
#endif
2344
2345
 
2346
   if (png_ptr->transformations & PNG_PACK)
2347
      png_do_unpack(row_info, png_ptr->row_buf + 1);
2348
#endif
2349
2350
 
2351
   /* Added at libpng-1.5.10 */
2352
   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
2353
       png_ptr->num_palette_max >= 0)
2354
      png_do_check_palette_indexes(png_ptr, row_info);
2355
#endif
2356
2357
 
2358
   if (png_ptr->transformations & PNG_BGR)
2359
      png_do_bgr(row_info, png_ptr->row_buf + 1);
2360
#endif
2361
2362
 
2363
   if (png_ptr->transformations & PNG_PACKSWAP)
2364
      png_do_packswap(row_info, png_ptr->row_buf + 1);
2365
#endif
2366
2367
 
2368
   if (png_ptr->transformations & PNG_FILLER)
2369
      png_do_read_filler(row_info, png_ptr->row_buf + 1,
2370
          (png_uint_32)png_ptr->filler, png_ptr->flags);
2371
#endif
2372
2373
 
2374
   if (png_ptr->transformations & PNG_INVERT_ALPHA)
2375
      png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
2376
#endif
2377
2378
 
2379
   if (png_ptr->transformations & PNG_SWAP_ALPHA)
2380
      png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
2381
#endif
2382
2383
 
2384
#ifdef PNG_READ_SWAP_SUPPORTED
2385
   if (png_ptr->transformations & PNG_SWAP_BYTES)
2386
      png_do_swap(row_info, png_ptr->row_buf + 1);
2387
#endif
2388
#endif
2389
2390
 
2391
   if (png_ptr->transformations & PNG_USER_TRANSFORM)
2392
    {
2393
      if (png_ptr->read_user_transform_fn != NULL)
2394
         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
2395
             (png_ptr,     /* png_ptr */
2396
             row_info,     /* row_info: */
2397
                /*  png_uint_32 width;       width of row */
2398
                /*  png_size_t rowbytes;     number of bytes in row */
2399
                /*  png_byte color_type;     color type of pixels */
2400
                /*  png_byte bit_depth;      bit depth of samples */
2401
                /*  png_byte channels;       number of channels (1-4) */
2402
                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
2403
             png_ptr->row_buf + 1);    /* start of pixel data for row */
2404
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
2405
      if (png_ptr->user_transform_depth)
2406
         row_info->bit_depth = png_ptr->user_transform_depth;
2407
2408
 
2409
         row_info->channels = png_ptr->user_transform_channels;
2410
#endif
2411
      row_info->pixel_depth = (png_byte)(row_info->bit_depth *
2412
          row_info->channels);
2413
2414
 
2415
   }
2416
#endif
2417
}
2418
2419
 
2420
/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
2421
 * without changing the actual values.  Thus, if you had a row with
2422
 * a bit depth of 1, you would end up with bytes that only contained
2423
 * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
2424
 * png_do_shift() after this.
2425
 */
2426
void /* PRIVATE */
2427
png_do_unpack(png_row_infop row_info, png_bytep row)
2428
{
2429
   png_debug(1, "in png_do_unpack");
2430
2431
 
2432
   {
2433
      png_uint_32 i;
2434
      png_uint_32 row_width=row_info->width;
2435
2436
 
2437
      {
2438
         case 1:
2439
         {
2440
            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
2441
            png_bytep dp = row + (png_size_t)row_width - 1;
2442
            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
2443
            for (i = 0; i < row_width; i++)
2444
            {
2445
               *dp = (png_byte)((*sp >> shift) & 0x01);
2446
2447
 
2448
               {
2449
                  shift = 0;
2450
                  sp--;
2451
               }
2452
2453
 
2454
                  shift++;
2455
2456
 
2457
            }
2458
            break;
2459
         }
2460
2461
 
2462
         {
2463
2464
 
2465
            png_bytep dp = row + (png_size_t)row_width - 1;
2466
            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
2467
            for (i = 0; i < row_width; i++)
2468
            {
2469
               *dp = (png_byte)((*sp >> shift) & 0x03);
2470
2471
 
2472
               {
2473
                  shift = 0;
2474
                  sp--;
2475
               }
2476
2477
 
2478
                  shift += 2;
2479
2480
 
2481
            }
2482
            break;
2483
         }
2484
2485
 
2486
         {
2487
            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
2488
            png_bytep dp = row + (png_size_t)row_width - 1;
2489
            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
2490
            for (i = 0; i < row_width; i++)
2491
            {
2492
               *dp = (png_byte)((*sp >> shift) & 0x0f);
2493
2494
 
2495
               {
2496
                  shift = 0;
2497
                  sp--;
2498
               }
2499
2500
 
2501
                  shift = 4;
2502
2503
 
2504
            }
2505
            break;
2506
         }
2507
2508
 
2509
            break;
2510
      }
2511
      row_info->bit_depth = 8;
2512
      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2513
      row_info->rowbytes = row_width * row_info->channels;
2514
   }
2515
}
2516
#endif
2517
2518
 
2519
/* Reverse the effects of png_do_shift.  This routine merely shifts the
2520
 * pixels back to their significant bits values.  Thus, if you have
2521
 * a row of bit depth 8, but only 5 are significant, this will shift
2522
 * the values back to 0 through 31.
2523
 */
2524
void /* PRIVATE */
2525
png_do_unshift(png_row_infop row_info, png_bytep row,
2526
    png_const_color_8p sig_bits)
2527
{
2528
   int color_type;
2529
2530
 
2531
2532
 
2533
   color_type = row_info->color_type;
2534
2535
 
2536
   {
2537
      int shift[4];
2538
      int channels = 0;
2539
      int bit_depth = row_info->bit_depth;
2540
2541
 
2542
      {
2543
         shift[channels++] = bit_depth - sig_bits->red;
2544
         shift[channels++] = bit_depth - sig_bits->green;
2545
         shift[channels++] = bit_depth - sig_bits->blue;
2546
      }
2547
2548
 
2549
      {
2550
         shift[channels++] = bit_depth - sig_bits->gray;
2551
      }
2552
2553
 
2554
      {
2555
         shift[channels++] = bit_depth - sig_bits->alpha;
2556
      }
2557
2558
 
2559
         int c, have_shift;
2560
2561
 
2562
         {
2563
            /* A shift of more than the bit depth is an error condition but it
2564
             * gets ignored here.
2565
             */
2566
            if (shift[c] <= 0 || shift[c] >= bit_depth)
2567
               shift[c] = 0;
2568
2569
 
2570
               have_shift = 1;
2571
         }
2572
2573
 
2574
            return;
2575
      }
2576
2577
 
2578
      {
2579
         default:
2580
         /* Must be 1bpp gray: should not be here! */
2581
            /* NOTREACHED */
2582
            break;
2583
2584
 
2585
         /* Must be 2bpp gray */
2586
         /* assert(channels == 1 && shift[0] == 1) */
2587
         {
2588
            png_bytep bp = row;
2589
            png_bytep bp_end = bp + row_info->rowbytes;
2590
2591
 
2592
            {
2593
               int b = (*bp >> 1) & 0x55;
2594
               *bp++ = (png_byte)b;
2595
            }
2596
            break;
2597
         }
2598
2599
 
2600
         /* Must be 4bpp gray */
2601
         /* assert(channels == 1) */
2602
         {
2603
            png_bytep bp = row;
2604
            png_bytep bp_end = bp + row_info->rowbytes;
2605
            int gray_shift = shift[0];
2606
            int mask =  0xf >> gray_shift;
2607
2608
 
2609
2610
 
2611
            {
2612
               int b = (*bp >> gray_shift) & mask;
2613
               *bp++ = (png_byte)b;
2614
            }
2615
            break;
2616
         }
2617
2618
 
2619
         /* Single byte components, G, GA, RGB, RGBA */
2620
         {
2621
            png_bytep bp = row;
2622
            png_bytep bp_end = bp + row_info->rowbytes;
2623
            int channel = 0;
2624
2625
 
2626
            {
2627
               int b = *bp >> shift[channel];
2628
               if (++channel >= channels)
2629
                  channel = 0;
2630
               *bp++ = (png_byte)b;
2631
            }
2632
            break;
2633
         }
2634
2635
 
2636
         case 16:
2637
         /* Double byte components, G, GA, RGB, RGBA */
2638
         {
2639
            png_bytep bp = row;
2640
            png_bytep bp_end = bp + row_info->rowbytes;
2641
            int channel = 0;
2642
2643
 
2644
            {
2645
               int value = (bp[0] << 8) + bp[1];
2646
2647
 
2648
               if (++channel >= channels)
2649
                  channel = 0;
2650
               *bp++ = (png_byte)(value >> 8);
2651
               *bp++ = (png_byte)(value & 0xff);
2652
            }
2653
            break;
2654
         }
2655
#endif
2656
      }
2657
   }
2658
}
2659
#endif
2660
2661
 
2662
/* Scale rows of bit depth 16 down to 8 accurately */
2663
void /* PRIVATE */
2664
png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
2665
{
2666
   png_debug(1, "in png_do_scale_16_to_8");
2667
2668
 
2669
   {
2670
      png_bytep sp = row; /* source */
2671
      png_bytep dp = row; /* destination */
2672
      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
2673
2674
 
2675
      {
2676
         /* The input is an array of 16 bit components, these must be scaled to
2677
          * 8 bits each.  For a 16 bit value V the required value (from the PNG
2678
          * specification) is:
2679
          *
2680
          *    (V * 255) / 65535
2681
          *
2682
          * This reduces to round(V / 257), or floor((V + 128.5)/257)
2683
          *
2684
          * Represent V as the two byte value vhi.vlo.  Make a guess that the
2685
          * result is the top byte of V, vhi, then the correction to this value
2686
          * is:
2687
          *
2688
          *    error = floor(((V-vhi.vhi) + 128.5) / 257)
2689
          *          = floor(((vlo-vhi) + 128.5) / 257)
2690
          *
2691
          * This can be approximated using integer arithmetic (and a signed
2692
          * shift):
2693
          *
2694
          *    error = (vlo-vhi+128) >> 8;
2695
          *
2696
          * The approximate differs from the exact answer only when (vlo-vhi) is
2697
          * 128; it then gives a correction of +1 when the exact correction is
2698
          * 0.  This gives 128 errors.  The exact answer (correct for all 16 bit
2699
          * input values) is:
2700
          *
2701
          *    error = (vlo-vhi+128)*65535 >> 24;
2702
          *
2703
          * An alternative arithmetic calculation which also gives no errors is:
2704
          *
2705
          *    (V * 255 + 32895) >> 16
2706
          */
2707
2708
 
2709
         tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
2710
         *dp++ = (png_byte)tmp;
2711
      }
2712
2713
 
2714
      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2715
      row_info->rowbytes = row_info->width * row_info->channels;
2716
   }
2717
}
2718
#endif
2719
2720
 
2721
void /* PRIVATE */
2722
/* Simply discard the low byte.  This was the default behavior prior
2723
 * to libpng-1.5.4.
2724
 */
2725
png_do_chop(png_row_infop row_info, png_bytep row)
2726
{
2727
   png_debug(1, "in png_do_chop");
2728
2729
 
2730
   {
2731
      png_bytep sp = row; /* source */
2732
      png_bytep dp = row; /* destination */
2733
      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
2734
2735
 
2736
      {
2737
         *dp++ = *sp;
2738
         sp += 2; /* skip low byte */
2739
      }
2740
2741
 
2742
      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2743
      row_info->rowbytes = row_info->width * row_info->channels;
2744
   }
2745
}
2746
#endif
2747
2748
 
2749
void /* PRIVATE */
2750
png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
2751
{
2752
   png_debug(1, "in png_do_read_swap_alpha");
2753
2754
 
2755
      png_uint_32 row_width = row_info->width;
2756
      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2757
      {
2758
         /* This converts from RGBA to ARGB */
2759
         if (row_info->bit_depth == 8)
2760
         {
2761
            png_bytep sp = row + row_info->rowbytes;
2762
            png_bytep dp = sp;
2763
            png_byte save;
2764
            png_uint_32 i;
2765
2766
 
2767
            {
2768
               save = *(--sp);
2769
               *(--dp) = *(--sp);
2770
               *(--dp) = *(--sp);
2771
               *(--dp) = *(--sp);
2772
               *(--dp) = save;
2773
            }
2774
         }
2775
2776
 
2777
         /* This converts from RRGGBBAA to AARRGGBB */
2778
         else
2779
         {
2780
            png_bytep sp = row + row_info->rowbytes;
2781
            png_bytep dp = sp;
2782
            png_byte save[2];
2783
            png_uint_32 i;
2784
2785
 
2786
            {
2787
               save[0] = *(--sp);
2788
               save[1] = *(--sp);
2789
               *(--dp) = *(--sp);
2790
               *(--dp) = *(--sp);
2791
               *(--dp) = *(--sp);
2792
               *(--dp) = *(--sp);
2793
               *(--dp) = *(--sp);
2794
               *(--dp) = *(--sp);
2795
               *(--dp) = save[0];
2796
               *(--dp) = save[1];
2797
            }
2798
         }
2799
#endif
2800
      }
2801
2802
 
2803
      {
2804
         /* This converts from GA to AG */
2805
         if (row_info->bit_depth == 8)
2806
         {
2807
            png_bytep sp = row + row_info->rowbytes;
2808
            png_bytep dp = sp;
2809
            png_byte save;
2810
            png_uint_32 i;
2811
2812
 
2813
            {
2814
               save = *(--sp);
2815
               *(--dp) = *(--sp);
2816
               *(--dp) = save;
2817
            }
2818
         }
2819
2820
 
2821
         /* This converts from GGAA to AAGG */
2822
         else
2823
         {
2824
            png_bytep sp = row + row_info->rowbytes;
2825
            png_bytep dp = sp;
2826
            png_byte save[2];
2827
            png_uint_32 i;
2828
2829
 
2830
            {
2831
               save[0] = *(--sp);
2832
               save[1] = *(--sp);
2833
               *(--dp) = *(--sp);
2834
               *(--dp) = *(--sp);
2835
               *(--dp) = save[0];
2836
               *(--dp) = save[1];
2837
            }
2838
         }
2839
#endif
2840
      }
2841
   }
2842
}
2843
#endif
2844
2845
 
2846
void /* PRIVATE */
2847
png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
2848
{
2849
   png_uint_32 row_width;
2850
   png_debug(1, "in png_do_read_invert_alpha");
2851
2852
 
2853
   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2854
   {
2855
      if (row_info->bit_depth == 8)
2856
      {
2857
         /* This inverts the alpha channel in RGBA */
2858
         png_bytep sp = row + row_info->rowbytes;
2859
         png_bytep dp = sp;
2860
         png_uint_32 i;
2861
2862
 
2863
         {
2864
            *(--dp) = (png_byte)(255 - *(--sp));
2865
2866
 
2867
            *(--dp) = *(--sp);
2868
            *(--dp) = *(--sp);
2869
            *(--dp) = *(--sp);
2870
            We can replace it with:
2871
*/
2872
            sp-=3;
2873
            dp=sp;
2874
         }
2875
      }
2876
2877
 
2878
      /* This inverts the alpha channel in RRGGBBAA */
2879
      else
2880
      {
2881
         png_bytep sp = row + row_info->rowbytes;
2882
         png_bytep dp = sp;
2883
         png_uint_32 i;
2884
2885
 
2886
         {
2887
            *(--dp) = (png_byte)(255 - *(--sp));
2888
            *(--dp) = (png_byte)(255 - *(--sp));
2889
2890
 
2891
            *(--dp) = *(--sp);
2892
            *(--dp) = *(--sp);
2893
            *(--dp) = *(--sp);
2894
            *(--dp) = *(--sp);
2895
            *(--dp) = *(--sp);
2896
            *(--dp) = *(--sp);
2897
            We can replace it with:
2898
*/
2899
            sp-=6;
2900
            dp=sp;
2901
         }
2902
      }
2903
#endif
2904
   }
2905
   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2906
   {
2907
      if (row_info->bit_depth == 8)
2908
      {
2909
         /* This inverts the alpha channel in GA */
2910
         png_bytep sp = row + row_info->rowbytes;
2911
         png_bytep dp = sp;
2912
         png_uint_32 i;
2913
2914
 
2915
         {
2916
            *(--dp) = (png_byte)(255 - *(--sp));
2917
            *(--dp) = *(--sp);
2918
         }
2919
      }
2920
2921
 
2922
      else
2923
      {
2924
         /* This inverts the alpha channel in GGAA */
2925
         png_bytep sp  = row + row_info->rowbytes;
2926
         png_bytep dp = sp;
2927
         png_uint_32 i;
2928
2929
 
2930
         {
2931
            *(--dp) = (png_byte)(255 - *(--sp));
2932
            *(--dp) = (png_byte)(255 - *(--sp));
2933
/*
2934
            *(--dp) = *(--sp);
2935
            *(--dp) = *(--sp);
2936
*/
2937
            sp-=2;
2938
            dp=sp;
2939
         }
2940
      }
2941
#endif
2942
   }
2943
}
2944
#endif
2945
2946
 
2947
/* Add filler channel if we have RGB color */
2948
void /* PRIVATE */
2949
png_do_read_filler(png_row_infop row_info, png_bytep row,
2950
    png_uint_32 filler, png_uint_32 flags)
2951
{
2952
   png_uint_32 i;
2953
   png_uint_32 row_width = row_info->width;
2954
2955
 
2956
   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
2957
#endif
2958
   png_byte lo_filler = (png_byte)(filler & 0xff);
2959
2960
 
2961
2962
 
2963
       row_info->color_type == PNG_COLOR_TYPE_GRAY)
2964
   {
2965
      if (row_info->bit_depth == 8)
2966
      {
2967
         if (flags & PNG_FLAG_FILLER_AFTER)
2968
         {
2969
            /* This changes the data from G to GX */
2970
            png_bytep sp = row + (png_size_t)row_width;
2971
            png_bytep dp =  sp + (png_size_t)row_width;
2972
            for (i = 1; i < row_width; i++)
2973
            {
2974
               *(--dp) = lo_filler;
2975
               *(--dp) = *(--sp);
2976
            }
2977
            *(--dp) = lo_filler;
2978
            row_info->channels = 2;
2979
            row_info->pixel_depth = 16;
2980
            row_info->rowbytes = row_width * 2;
2981
         }
2982
2983
 
2984
         {
2985
            /* This changes the data from G to XG */
2986
            png_bytep sp = row + (png_size_t)row_width;
2987
            png_bytep dp = sp  + (png_size_t)row_width;
2988
            for (i = 0; i < row_width; i++)
2989
            {
2990
               *(--dp) = *(--sp);
2991
               *(--dp) = lo_filler;
2992
            }
2993
            row_info->channels = 2;
2994
            row_info->pixel_depth = 16;
2995
            row_info->rowbytes = row_width * 2;
2996
         }
2997
      }
2998
2999
 
3000
      else if (row_info->bit_depth == 16)
3001
      {
3002
         if (flags & PNG_FLAG_FILLER_AFTER)
3003
         {
3004
            /* This changes the data from GG to GGXX */
3005
            png_bytep sp = row + (png_size_t)row_width * 2;
3006
            png_bytep dp = sp  + (png_size_t)row_width * 2;
3007
            for (i = 1; i < row_width; i++)
3008
            {
3009
               *(--dp) = hi_filler;
3010
               *(--dp) = lo_filler;
3011
               *(--dp) = *(--sp);
3012
               *(--dp) = *(--sp);
3013
            }
3014
            *(--dp) = hi_filler;
3015
            *(--dp) = lo_filler;
3016
            row_info->channels = 2;
3017
            row_info->pixel_depth = 32;
3018
            row_info->rowbytes = row_width * 4;
3019
         }
3020
3021
 
3022
         {
3023
            /* This changes the data from GG to XXGG */
3024
            png_bytep sp = row + (png_size_t)row_width * 2;
3025
            png_bytep dp = sp  + (png_size_t)row_width * 2;
3026
            for (i = 0; i < row_width; i++)
3027
            {
3028
               *(--dp) = *(--sp);
3029
               *(--dp) = *(--sp);
3030
               *(--dp) = hi_filler;
3031
               *(--dp) = lo_filler;
3032
            }
3033
            row_info->channels = 2;
3034
            row_info->pixel_depth = 32;
3035
            row_info->rowbytes = row_width * 4;
3036
         }
3037
      }
3038
#endif
3039
   } /* COLOR_TYPE == GRAY */
3040
   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
3041
   {
3042
      if (row_info->bit_depth == 8)
3043
      {
3044
         if (flags & PNG_FLAG_FILLER_AFTER)
3045
         {
3046
            /* This changes the data from RGB to RGBX */
3047
            png_bytep sp = row + (png_size_t)row_width * 3;
3048
            png_bytep dp = sp  + (png_size_t)row_width;
3049
            for (i = 1; i < row_width; i++)
3050
            {
3051
               *(--dp) = lo_filler;
3052
               *(--dp) = *(--sp);
3053
               *(--dp) = *(--sp);
3054
               *(--dp) = *(--sp);
3055
            }
3056
            *(--dp) = lo_filler;
3057
            row_info->channels = 4;
3058
            row_info->pixel_depth = 32;
3059
            row_info->rowbytes = row_width * 4;
3060
         }
3061
3062
 
3063
         {
3064
            /* This changes the data from RGB to XRGB */
3065
            png_bytep sp = row + (png_size_t)row_width * 3;
3066
            png_bytep dp = sp + (png_size_t)row_width;
3067
            for (i = 0; i < row_width; i++)
3068
            {
3069
               *(--dp) = *(--sp);
3070
               *(--dp) = *(--sp);
3071
               *(--dp) = *(--sp);
3072
               *(--dp) = lo_filler;
3073
            }
3074
            row_info->channels = 4;
3075
            row_info->pixel_depth = 32;
3076
            row_info->rowbytes = row_width * 4;
3077
         }
3078
      }
3079
3080
 
3081
      else if (row_info->bit_depth == 16)
3082
      {
3083
         if (flags & PNG_FLAG_FILLER_AFTER)
3084
         {
3085
            /* This changes the data from RRGGBB to RRGGBBXX */
3086
            png_bytep sp = row + (png_size_t)row_width * 6;
3087
            png_bytep dp = sp  + (png_size_t)row_width * 2;
3088
            for (i = 1; i < row_width; i++)
3089
            {
3090
               *(--dp) = hi_filler;
3091
               *(--dp) = lo_filler;
3092
               *(--dp) = *(--sp);
3093
               *(--dp) = *(--sp);
3094
               *(--dp) = *(--sp);
3095
               *(--dp) = *(--sp);
3096
               *(--dp) = *(--sp);
3097
               *(--dp) = *(--sp);
3098
            }
3099
            *(--dp) = hi_filler;
3100
            *(--dp) = lo_filler;
3101
            row_info->channels = 4;
3102
            row_info->pixel_depth = 64;
3103
            row_info->rowbytes = row_width * 8;
3104
         }
3105
3106
 
3107
         {
3108
            /* This changes the data from RRGGBB to XXRRGGBB */
3109
            png_bytep sp = row + (png_size_t)row_width * 6;
3110
            png_bytep dp = sp  + (png_size_t)row_width * 2;
3111
            for (i = 0; i < row_width; i++)
3112
            {
3113
               *(--dp) = *(--sp);
3114
               *(--dp) = *(--sp);
3115
               *(--dp) = *(--sp);
3116
               *(--dp) = *(--sp);
3117
               *(--dp) = *(--sp);
3118
               *(--dp) = *(--sp);
3119
               *(--dp) = hi_filler;
3120
               *(--dp) = lo_filler;
3121
            }
3122
3123
 
3124
            row_info->pixel_depth = 64;
3125
            row_info->rowbytes = row_width * 8;
3126
         }
3127
      }
3128
#endif
3129
   } /* COLOR_TYPE == RGB */
3130
}
3131
#endif
3132
3133
 
3134
/* Expand grayscale files to RGB, with or without alpha */
3135
void /* PRIVATE */
3136
png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
3137
{
3138
   png_uint_32 i;
3139
   png_uint_32 row_width = row_info->width;
3140
3141
 
3142
3143
 
3144
       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
3145
   {
3146
      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
3147
      {
3148
         if (row_info->bit_depth == 8)
3149
         {
3150
            /* This changes G to RGB */
3151
            png_bytep sp = row + (png_size_t)row_width - 1;
3152
            png_bytep dp = sp  + (png_size_t)row_width * 2;
3153
            for (i = 0; i < row_width; i++)
3154
            {
3155
               *(dp--) = *sp;
3156
               *(dp--) = *sp;
3157
               *(dp--) = *(sp--);
3158
            }
3159
         }
3160
3161
 
3162
         {
3163
            /* This changes GG to RRGGBB */
3164
            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
3165
            png_bytep dp = sp  + (png_size_t)row_width * 4;
3166
            for (i = 0; i < row_width; i++)
3167
            {
3168
               *(dp--) = *sp;
3169
               *(dp--) = *(sp - 1);
3170
               *(dp--) = *sp;
3171
               *(dp--) = *(sp - 1);
3172
               *(dp--) = *(sp--);
3173
               *(dp--) = *(sp--);
3174
            }
3175
         }
3176
      }
3177
3178
 
3179
      {
3180
         if (row_info->bit_depth == 8)
3181
         {
3182
            /* This changes GA to RGBA */
3183
            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
3184
            png_bytep dp = sp  + (png_size_t)row_width * 2;
3185
            for (i = 0; i < row_width; i++)
3186
            {
3187
               *(dp--) = *(sp--);
3188
               *(dp--) = *sp;
3189
               *(dp--) = *sp;
3190
               *(dp--) = *(sp--);
3191
            }
3192
         }
3193
3194
 
3195
         {
3196
            /* This changes GGAA to RRGGBBAA */
3197
            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
3198
            png_bytep dp = sp  + (png_size_t)row_width * 4;
3199
            for (i = 0; i < row_width; i++)
3200
            {
3201
               *(dp--) = *(sp--);
3202
               *(dp--) = *(sp--);
3203
               *(dp--) = *sp;
3204
               *(dp--) = *(sp - 1);
3205
               *(dp--) = *sp;
3206
               *(dp--) = *(sp - 1);
3207
               *(dp--) = *(sp--);
3208
               *(dp--) = *(sp--);
3209
            }
3210
         }
3211
      }
3212
      row_info->channels = (png_byte)(row_info->channels + 2);
3213
      row_info->color_type |= PNG_COLOR_MASK_COLOR;
3214
      row_info->pixel_depth = (png_byte)(row_info->channels *
3215
          row_info->bit_depth);
3216
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3217
   }
3218
}
3219
#endif
3220
3221
 
3222
/* Reduce RGB files to grayscale, with or without alpha
3223
 * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
3224
 *   (THIS LINK IS DEAD June 2008 but
3225
 * versions dated 1998 through November 2002 have been archived at
3226
 * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
3227
 * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
3228
 * Charles Poynton poynton at poynton.com
3229
 *
3230
 *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
3231
 *
3232
 *  which can be expressed with integers as
3233
 *
3234
 *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
3235
 *
3236
 * Poynton's current link (as of January 2003 through July 2011):
3237
 * 
3238
 * has changed the numbers slightly:
3239
 *
3240
 *     Y = 0.2126*R + 0.7152*G + 0.0722*B
3241
 *
3242
 *  which can be expressed with integers as
3243
 *
3244
 *     Y = (6966 * R + 23436 * G + 2366 * B)/32768
3245
 *
3246
 *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709
3247
 *  end point chromaticities and the D65 white point.  Depending on the
3248
 *  precision used for the D65 white point this produces a variety of different
3249
 *  numbers, however if the four decimal place value used in ITU-R Rec 709 is
3250
 *  used (0.3127,0.3290) the Y calculation would be:
3251
 *
3252
 *     Y = (6968 * R + 23435 * G + 2366 * B)/32768
3253
 *
3254
 *  While this is correct the rounding results in an overflow for white, because
3255
 *  the sum of the rounded coefficients is 32769, not 32768.  Consequently
3256
 *  libpng uses, instead, the closest non-overflowing approximation:
3257
 *
3258
 *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
3259
 *
3260
 *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
3261
 *  (including an sRGB chunk) then the chromaticities are used to calculate the
3262
 *  coefficients.  See the chunk handling in pngrutil.c for more information.
3263
 *
3264
 *  In all cases the calculation is to be done in a linear colorspace.  If no
3265
 *  gamma information is available to correct the encoding of the original RGB
3266
 *  values this results in an implicit assumption that the original PNG RGB
3267
 *  values were linear.
3268
 *
3269
 *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
3270
 *  the API takes just red and green coefficients the blue coefficient is
3271
 *  calculated to make the sum 32768.  This will result in different rounding
3272
 *  to that used above.
3273
 */
3274
int /* PRIVATE */
3275
png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
3276
3277
 
3278
   int rgb_error = 0;
3279
3280
 
3281
3282
 
3283
       (row_info->color_type & PNG_COLOR_MASK_COLOR))
3284
   {
3285
      PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
3286
      PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
3287
      PNG_CONST png_uint_32 bc = 32768 - rc - gc;
3288
      PNG_CONST png_uint_32 row_width = row_info->width;
3289
      PNG_CONST int have_alpha =
3290
         (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
3291
3292
 
3293
      {
3294
#ifdef PNG_READ_GAMMA_SUPPORTED
3295
         /* Notice that gamma to/from 1 are not necessarily inverses (if
3296
          * there is an overall gamma correction).  Prior to 1.5.5 this code
3297
          * checked the linearized values for equality; this doesn't match
3298
          * the documentation, the original values must be checked.
3299
          */
3300
         if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
3301
         {
3302
            png_bytep sp = row;
3303
            png_bytep dp = row;
3304
            png_uint_32 i;
3305
3306
 
3307
            {
3308
               png_byte red   = *(sp++);
3309
               png_byte green = *(sp++);
3310
               png_byte blue  = *(sp++);
3311
3312
 
3313
               {
3314
                  red = png_ptr->gamma_to_1[red];
3315
                  green = png_ptr->gamma_to_1[green];
3316
                  blue = png_ptr->gamma_to_1[blue];
3317
3318
 
3319
                  *(dp++) = png_ptr->gamma_from_1[
3320
                      (rc*red + gc*green + bc*blue + 16384)>>15];
3321
               }
3322
3323
 
3324
               {
3325
                  /* If there is no overall correction the table will not be
3326
                   * set.
3327
                   */
3328
                  if (png_ptr->gamma_table != NULL)
3329
                     red = png_ptr->gamma_table[red];
3330
3331
 
3332
               }
3333
3334
 
3335
                  *(dp++) = *(sp++);
3336
            }
3337
         }
3338
         else
3339
#endif
3340
         {
3341
            png_bytep sp = row;
3342
            png_bytep dp = row;
3343
            png_uint_32 i;
3344
3345
 
3346
            {
3347
               png_byte red   = *(sp++);
3348
               png_byte green = *(sp++);
3349
               png_byte blue  = *(sp++);
3350
3351
 
3352
               {
3353
                  rgb_error |= 1;
3354
                  /* NOTE: this is the historical approach which simply
3355
                   * truncates the results.
3356
                   */
3357
                  *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
3358
               }
3359
3360
 
3361
                  *(dp++) = red;
3362
3363
 
3364
                  *(dp++) = *(sp++);
3365
            }
3366
         }
3367
      }
3368
3369
 
3370
      {
3371
#ifdef PNG_READ_GAMMA_SUPPORTED
3372
         if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
3373
         {
3374
            png_bytep sp = row;
3375
            png_bytep dp = row;
3376
            png_uint_32 i;
3377
3378
 
3379
            {
3380
               png_uint_16 red, green, blue, w;
3381
3382
 
3383
               green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3384
               blue  = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3385
3386
 
3387
               {
3388
                  if (png_ptr->gamma_16_table != NULL)
3389
                     w = png_ptr->gamma_16_table[(red&0xff)
3390
                         >> png_ptr->gamma_shift][red>>8];
3391
3392
 
3393
                     w = red;
3394
               }
3395
3396
 
3397
               {
3398
                  png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff)
3399
                      >> png_ptr->gamma_shift][red>>8];
3400
                  png_uint_16 green_1 =
3401
                      png_ptr->gamma_16_to_1[(green&0xff) >>
3402
                      png_ptr->gamma_shift][green>>8];
3403
                  png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff)
3404
                      >> png_ptr->gamma_shift][blue>>8];
3405
                  png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
3406
                      + bc*blue_1 + 16384)>>15);
3407
                  w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
3408
                      png_ptr->gamma_shift][gray16 >> 8];
3409
                  rgb_error |= 1;
3410
               }
3411
3412
 
3413
               *(dp++) = (png_byte)(w & 0xff);
3414
3415
 
3416
               {
3417
                  *(dp++) = *(sp++);
3418
                  *(dp++) = *(sp++);
3419
               }
3420
            }
3421
         }
3422
         else
3423
#endif
3424
         {
3425
            png_bytep sp = row;
3426
            png_bytep dp = row;
3427
            png_uint_32 i;
3428
3429
 
3430
            {
3431
               png_uint_16 red, green, blue, gray16;
3432
3433
 
3434
               green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3435
               blue  = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3436
3437
 
3438
                  rgb_error |= 1;
3439
3440
 
3441
                * in the 'fast' case - this is because this is where the code
3442
                * ends up when handling linear 16 bit data.
3443
                */
3444
               gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
3445
                  15);
3446
               *(dp++) = (png_byte)((gray16>>8) & 0xff);
3447
               *(dp++) = (png_byte)(gray16 & 0xff);
3448
3449
 
3450
               {
3451
                  *(dp++) = *(sp++);
3452
                  *(dp++) = *(sp++);
3453
               }
3454
            }
3455
         }
3456
      }
3457
3458
 
3459
      row_info->color_type = (png_byte)(row_info->color_type &
3460
          ~PNG_COLOR_MASK_COLOR);
3461
      row_info->pixel_depth = (png_byte)(row_info->channels *
3462
          row_info->bit_depth);
3463
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3464
   }
3465
   return rgb_error;
3466
}
3467
#endif
3468
#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
3469
3470
 
3471
/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
3472
 * large of png_color.  This lets grayscale images be treated as
3473
 * paletted.  Most useful for gamma correction and simplification
3474
 * of code.  This API is not used internally.
3475
 */
3476
void PNGAPI
3477
png_build_grayscale_palette(int bit_depth, png_colorp palette)
3478
{
3479
   int num_palette;
3480
   int color_inc;
3481
   int i;
3482
   int v;
3483
3484
 
3485
3486
 
3487
      return;
3488
3489
 
3490
   {
3491
      case 1:
3492
         num_palette = 2;
3493
         color_inc = 0xff;
3494
         break;
3495
3496
 
3497
         num_palette = 4;
3498
         color_inc = 0x55;
3499
         break;
3500
3501
 
3502
         num_palette = 16;
3503
         color_inc = 0x11;
3504
         break;
3505
3506
 
3507
         num_palette = 256;
3508
         color_inc = 1;
3509
         break;
3510
3511
 
3512
         num_palette = 0;
3513
         color_inc = 0;
3514
         break;
3515
   }
3516
3517
 
3518
   {
3519
      palette[i].red = (png_byte)v;
3520
      palette[i].green = (png_byte)v;
3521
      palette[i].blue = (png_byte)v;
3522
   }
3523
}
3524
#endif
3525
3526
 
3527
 
3528
#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
3529
   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
3530
/* Replace any alpha or transparency with the supplied background color.
3531
 * "background" is already in the screen gamma, while "background_1" is
3532
 * at a gamma of 1.0.  Paletted files have already been taken care of.
3533
 */
3534
void /* PRIVATE */
3535
png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3536
{
3537
#ifdef PNG_READ_GAMMA_SUPPORTED
3538
   png_const_bytep gamma_table = png_ptr->gamma_table;
3539
   png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
3540
   png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
3541
   png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
3542
   png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
3543
   png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
3544
   int gamma_shift = png_ptr->gamma_shift;
3545
   int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
3546
#endif
3547
3548
 
3549
   png_uint_32 i;
3550
   png_uint_32 row_width = row_info->width;
3551
   int shift;
3552
3553
 
3554
3555
 
3556
      switch (row_info->color_type)
3557
      {
3558
         case PNG_COLOR_TYPE_GRAY:
3559
         {
3560
            switch (row_info->bit_depth)
3561
            {
3562
               case 1:
3563
               {
3564
                  sp = row;
3565
                  shift = 7;
3566
                  for (i = 0; i < row_width; i++)
3567
                  {
3568
                     if ((png_uint_16)((*sp >> shift) & 0x01)
3569
                        == png_ptr->trans_color.gray)
3570
                     {
3571
                        unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
3572
                        tmp |= png_ptr->background.gray << shift;
3573
                        *sp = (png_byte)(tmp & 0xff);
3574
                     }
3575
3576
 
3577
                     {
3578
                        shift = 7;
3579
                        sp++;
3580
                     }
3581
3582
 
3583
                        shift--;
3584
                  }
3585
                  break;
3586
               }
3587
3588
 
3589
               {
3590
#ifdef PNG_READ_GAMMA_SUPPORTED
3591
                  if (gamma_table != NULL)
3592
                  {
3593
                     sp = row;
3594
                     shift = 6;
3595
                     for (i = 0; i < row_width; i++)
3596
                     {
3597
                        if ((png_uint_16)((*sp >> shift) & 0x03)
3598
                            == png_ptr->trans_color.gray)
3599
                        {
3600
                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3601
                           tmp |= png_ptr->background.gray << shift;
3602
                           *sp = (png_byte)(tmp & 0xff);
3603
                        }
3604
3605
 
3606
                        {
3607
                           unsigned int p = (*sp >> shift) & 0x03;
3608
                           unsigned int g = (gamma_table [p | (p << 2) |
3609
                               (p << 4) | (p << 6)] >> 6) & 0x03;
3610
                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3611
                           tmp |= g << shift;
3612
                           *sp = (png_byte)(tmp & 0xff);
3613
                        }
3614
3615
 
3616
                        {
3617
                           shift = 6;
3618
                           sp++;
3619
                        }
3620
3621
 
3622
                           shift -= 2;
3623
                     }
3624
                  }
3625
3626
 
3627
#endif
3628
                  {
3629
                     sp = row;
3630
                     shift = 6;
3631
                     for (i = 0; i < row_width; i++)
3632
                     {
3633
                        if ((png_uint_16)((*sp >> shift) & 0x03)
3634
                            == png_ptr->trans_color.gray)
3635
                        {
3636
                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3637
                           tmp |= png_ptr->background.gray << shift;
3638
                           *sp = (png_byte)(tmp & 0xff);
3639
                        }
3640
3641
 
3642
                        {
3643
                           shift = 6;
3644
                           sp++;
3645
                        }
3646
3647
 
3648
                           shift -= 2;
3649
                     }
3650
                  }
3651
                  break;
3652
               }
3653
3654
 
3655
               {
3656
#ifdef PNG_READ_GAMMA_SUPPORTED
3657
                  if (gamma_table != NULL)
3658
                  {
3659
                     sp = row;
3660
                     shift = 4;
3661
                     for (i = 0; i < row_width; i++)
3662
                     {
3663
                        if ((png_uint_16)((*sp >> shift) & 0x0f)
3664
                            == png_ptr->trans_color.gray)
3665
                        {
3666
                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
3667
                           tmp |= png_ptr->background.gray << shift;
3668
                           *sp = (png_byte)(tmp & 0xff);
3669
                        }
3670
3671
 
3672
                        {
3673
                           unsigned int p = (*sp >> shift) & 0x0f;
3674
                           unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
3675
                              0x0f;
3676
                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
3677
                           tmp |= g << shift;
3678
                           *sp = (png_byte)(tmp & 0xff);
3679
                        }
3680
3681
 
3682
                        {
3683
                           shift = 4;
3684
                           sp++;
3685
                        }
3686
3687
 
3688
                           shift -= 4;
3689
                     }
3690
                  }
3691
3692
 
3693
#endif
3694
                  {
3695
                     sp = row;
3696
                     shift = 4;
3697
                     for (i = 0; i < row_width; i++)
3698
                     {
3699
                        if ((png_uint_16)((*sp >> shift) & 0x0f)
3700
                            == png_ptr->trans_color.gray)
3701
                        {
3702
                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
3703
                           tmp |= png_ptr->background.gray << shift;
3704
                           *sp = (png_byte)(tmp & 0xff);
3705
                        }
3706
3707
 
3708
                        {
3709
                           shift = 4;
3710
                           sp++;
3711
                        }
3712
3713
 
3714
                           shift -= 4;
3715
                     }
3716
                  }
3717
                  break;
3718
               }
3719
3720
 
3721
               {
3722
#ifdef PNG_READ_GAMMA_SUPPORTED
3723
                  if (gamma_table != NULL)
3724
                  {
3725
                     sp = row;
3726
                     for (i = 0; i < row_width; i++, sp++)
3727
                     {
3728
                        if (*sp == png_ptr->trans_color.gray)
3729
                           *sp = (png_byte)png_ptr->background.gray;
3730
3731
 
3732
                           *sp = gamma_table[*sp];
3733
                     }
3734
                  }
3735
                  else
3736
#endif
3737
                  {
3738
                     sp = row;
3739
                     for (i = 0; i < row_width; i++, sp++)
3740
                     {
3741
                        if (*sp == png_ptr->trans_color.gray)
3742
                           *sp = (png_byte)png_ptr->background.gray;
3743
                     }
3744
                  }
3745
                  break;
3746
               }
3747
3748
 
3749
               {
3750
#ifdef PNG_READ_GAMMA_SUPPORTED
3751
                  if (gamma_16 != NULL)
3752
                  {
3753
                     sp = row;
3754
                     for (i = 0; i < row_width; i++, sp += 2)
3755
                     {
3756
                        png_uint_16 v;
3757
3758
 
3759
3760
 
3761
                        {
3762
                           /* Background is already in screen gamma */
3763
                           *sp = (png_byte)((png_ptr->background.gray >> 8)
3764
                                & 0xff);
3765
                           *(sp + 1) = (png_byte)(png_ptr->background.gray
3766
                                & 0xff);
3767
                        }
3768
3769
 
3770
                        {
3771
                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3772
                           *sp = (png_byte)((v >> 8) & 0xff);
3773
                           *(sp + 1) = (png_byte)(v & 0xff);
3774
                        }
3775
                     }
3776
                  }
3777
                  else
3778
#endif
3779
                  {
3780
                     sp = row;
3781
                     for (i = 0; i < row_width; i++, sp += 2)
3782
                     {
3783
                        png_uint_16 v;
3784
3785
 
3786
3787
 
3788
                        {
3789
                           *sp = (png_byte)((png_ptr->background.gray >> 8)
3790
                                & 0xff);
3791
                           *(sp + 1) = (png_byte)(png_ptr->background.gray
3792
                                & 0xff);
3793
                        }
3794
                     }
3795
                  }
3796
                  break;
3797
               }
3798
3799
 
3800
                  break;
3801
            }
3802
            break;
3803
         }
3804
3805
 
3806
         {
3807
            if (row_info->bit_depth == 8)
3808
            {
3809
#ifdef PNG_READ_GAMMA_SUPPORTED
3810
               if (gamma_table != NULL)
3811
               {
3812
                  sp = row;
3813
                  for (i = 0; i < row_width; i++, sp += 3)
3814
                  {
3815
                     if (*sp == png_ptr->trans_color.red &&
3816
                         *(sp + 1) == png_ptr->trans_color.green &&
3817
                         *(sp + 2) == png_ptr->trans_color.blue)
3818
                     {
3819
                        *sp = (png_byte)png_ptr->background.red;
3820
                        *(sp + 1) = (png_byte)png_ptr->background.green;
3821
                        *(sp + 2) = (png_byte)png_ptr->background.blue;
3822
                     }
3823
3824
 
3825
                     {
3826
                        *sp = gamma_table[*sp];
3827
                        *(sp + 1) = gamma_table[*(sp + 1)];
3828
                        *(sp + 2) = gamma_table[*(sp + 2)];
3829
                     }
3830
                  }
3831
               }
3832
               else
3833
#endif
3834
               {
3835
                  sp = row;
3836
                  for (i = 0; i < row_width; i++, sp += 3)
3837
                  {
3838
                     if (*sp == png_ptr->trans_color.red &&
3839
                         *(sp + 1) == png_ptr->trans_color.green &&
3840
                         *(sp + 2) == png_ptr->trans_color.blue)
3841
                     {
3842
                        *sp = (png_byte)png_ptr->background.red;
3843
                        *(sp + 1) = (png_byte)png_ptr->background.green;
3844
                        *(sp + 2) = (png_byte)png_ptr->background.blue;
3845
                     }
3846
                  }
3847
               }
3848
            }
3849
            else /* if (row_info->bit_depth == 16) */
3850
            {
3851
#ifdef PNG_READ_GAMMA_SUPPORTED
3852
               if (gamma_16 != NULL)
3853
               {
3854
                  sp = row;
3855
                  for (i = 0; i < row_width; i++, sp += 6)
3856
                  {
3857
                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3858
3859
 
3860
                         + *(sp + 3));
3861
3862
 
3863
                         + *(sp + 5));
3864
3865
 
3866
                         g == png_ptr->trans_color.green &&
3867
                         b == png_ptr->trans_color.blue)
3868
                     {
3869
                        /* Background is already in screen gamma */
3870
                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3871
                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3872
                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3873
                                & 0xff);
3874
                        *(sp + 3) = (png_byte)(png_ptr->background.green
3875
                                & 0xff);
3876
                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3877
                                & 0xff);
3878
                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3879
                     }
3880
3881
 
3882
                     {
3883
                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3884
                        *sp = (png_byte)((v >> 8) & 0xff);
3885
                        *(sp + 1) = (png_byte)(v & 0xff);
3886
3887
 
3888
                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3889
                        *(sp + 3) = (png_byte)(v & 0xff);
3890
3891
 
3892
                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3893
                        *(sp + 5) = (png_byte)(v & 0xff);
3894
                     }
3895
                  }
3896
               }
3897
3898
 
3899
#endif
3900
               {
3901
                  sp = row;
3902
                  for (i = 0; i < row_width; i++, sp += 6)
3903
                  {
3904
                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3905
3906
 
3907
                         + *(sp + 3));
3908
3909
 
3910
                         + *(sp + 5));
3911
3912
 
3913
                         g == png_ptr->trans_color.green &&
3914
                         b == png_ptr->trans_color.blue)
3915
                     {
3916
                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3917
                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3918
                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3919
                                & 0xff);
3920
                        *(sp + 3) = (png_byte)(png_ptr->background.green
3921
                                & 0xff);
3922
                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3923
                                & 0xff);
3924
                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3925
                     }
3926
                  }
3927
               }
3928
            }
3929
            break;
3930
         }
3931
3932
 
3933
         {
3934
            if (row_info->bit_depth == 8)
3935
            {
3936
#ifdef PNG_READ_GAMMA_SUPPORTED
3937
               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3938
                   gamma_table != NULL)
3939
               {
3940
                  sp = row;
3941
                  for (i = 0; i < row_width; i++, sp += 2)
3942
                  {
3943
                     png_uint_16 a = *(sp + 1);
3944
3945
 
3946
                        *sp = gamma_table[*sp];
3947
3948
 
3949
                     {
3950
                        /* Background is already in screen gamma */
3951
                        *sp = (png_byte)png_ptr->background.gray;
3952
                     }
3953
3954
 
3955
                     {
3956
                        png_byte v, w;
3957
3958
 
3959
                        png_composite(w, v, a, png_ptr->background_1.gray);
3960
                        if (!optimize)
3961
                           w = gamma_from_1[w];
3962
                        *sp = w;
3963
                     }
3964
                  }
3965
               }
3966
               else
3967
#endif
3968
               {
3969
                  sp = row;
3970
                  for (i = 0; i < row_width; i++, sp += 2)
3971
                  {
3972
                     png_byte a = *(sp + 1);
3973
3974
 
3975
                        *sp = (png_byte)png_ptr->background.gray;
3976
3977
 
3978
                        png_composite(*sp, *sp, a, png_ptr->background.gray);
3979
                  }
3980
               }
3981
            }
3982
            else /* if (png_ptr->bit_depth == 16) */
3983
            {
3984
#ifdef PNG_READ_GAMMA_SUPPORTED
3985
               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3986
                   gamma_16_to_1 != NULL)
3987
               {
3988
                  sp = row;
3989
                  for (i = 0; i < row_width; i++, sp += 4)
3990
                  {
3991
                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3992
                         + *(sp + 3));
3993
3994
 
3995
                     {
3996
                        png_uint_16 v;
3997
3998
 
3999
                        *sp = (png_byte)((v >> 8) & 0xff);
4000
                        *(sp + 1) = (png_byte)(v & 0xff);
4001
                     }
4002
4003
 
4004
                     {
4005
                        /* Background is already in screen gamma */
4006
                        *sp = (png_byte)((png_ptr->background.gray >> 8)
4007
                                & 0xff);
4008
                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
4009
                     }
4010
4011
 
4012
                     {
4013
                        png_uint_16 g, v, w;
4014
4015
 
4016
                        png_composite_16(v, g, a, png_ptr->background_1.gray);
4017
                        if (optimize)
4018
                           w = v;
4019
                        else
4020
                           w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
4021
                        *sp = (png_byte)((w >> 8) & 0xff);
4022
                        *(sp + 1) = (png_byte)(w & 0xff);
4023
                     }
4024
                  }
4025
               }
4026
               else
4027
#endif
4028
               {
4029
                  sp = row;
4030
                  for (i = 0; i < row_width; i++, sp += 4)
4031
                  {
4032
                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
4033
                         + *(sp + 3));
4034
4035
 
4036
                     {
4037
                        *sp = (png_byte)((png_ptr->background.gray >> 8)
4038
                                & 0xff);
4039
                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
4040
                     }
4041
4042
 
4043
                     {
4044
                        png_uint_16 g, v;
4045
4046
 
4047
                        png_composite_16(v, g, a, png_ptr->background.gray);
4048
                        *sp = (png_byte)((v >> 8) & 0xff);
4049
                        *(sp + 1) = (png_byte)(v & 0xff);
4050
                     }
4051
                  }
4052
               }
4053
            }
4054
            break;
4055
         }
4056
4057
 
4058
         {
4059
            if (row_info->bit_depth == 8)
4060
            {
4061
#ifdef PNG_READ_GAMMA_SUPPORTED
4062
               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
4063
                   gamma_table != NULL)
4064
               {
4065
                  sp = row;
4066
                  for (i = 0; i < row_width; i++, sp += 4)
4067
                  {
4068
                     png_byte a = *(sp + 3);
4069
4070
 
4071
                     {
4072
                        *sp = gamma_table[*sp];
4073
                        *(sp + 1) = gamma_table[*(sp + 1)];
4074
                        *(sp + 2) = gamma_table[*(sp + 2)];
4075
                     }
4076
4077
 
4078
                     {
4079
                        /* Background is already in screen gamma */
4080
                        *sp = (png_byte)png_ptr->background.red;
4081
                        *(sp + 1) = (png_byte)png_ptr->background.green;
4082
                        *(sp + 2) = (png_byte)png_ptr->background.blue;
4083
                     }
4084
4085
 
4086
                     {
4087
                        png_byte v, w;
4088
4089
 
4090
                        png_composite(w, v, a, png_ptr->background_1.red);
4091
                        if (!optimize) w = gamma_from_1[w];
4092
                        *sp = w;
4093
4094
 
4095
                        png_composite(w, v, a, png_ptr->background_1.green);
4096
                        if (!optimize) w = gamma_from_1[w];
4097
                        *(sp + 1) = w;
4098
4099
 
4100
                        png_composite(w, v, a, png_ptr->background_1.blue);
4101
                        if (!optimize) w = gamma_from_1[w];
4102
                        *(sp + 2) = w;
4103
                     }
4104
                  }
4105
               }
4106
               else
4107
#endif
4108
               {
4109
                  sp = row;
4110
                  for (i = 0; i < row_width; i++, sp += 4)
4111
                  {
4112
                     png_byte a = *(sp + 3);
4113
4114
 
4115
                     {
4116
                        *sp = (png_byte)png_ptr->background.red;
4117
                        *(sp + 1) = (png_byte)png_ptr->background.green;
4118
                        *(sp + 2) = (png_byte)png_ptr->background.blue;
4119
                     }
4120
4121
 
4122
                     {
4123
                        png_composite(*sp, *sp, a, png_ptr->background.red);
4124
4125
 
4126
                            png_ptr->background.green);
4127
4128
 
4129
                            png_ptr->background.blue);
4130
                     }
4131
                  }
4132
               }
4133
            }
4134
            else /* if (row_info->bit_depth == 16) */
4135
            {
4136
#ifdef PNG_READ_GAMMA_SUPPORTED
4137
               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
4138
                   gamma_16_to_1 != NULL)
4139
               {
4140
                  sp = row;
4141
                  for (i = 0; i < row_width; i++, sp += 8)
4142
                  {
4143
                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
4144
                         << 8) + (png_uint_16)(*(sp + 7)));
4145
4146
 
4147
                     {
4148
                        png_uint_16 v;
4149
4150
 
4151
                        *sp = (png_byte)((v >> 8) & 0xff);
4152
                        *(sp + 1) = (png_byte)(v & 0xff);
4153
4154
 
4155
                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
4156
                        *(sp + 3) = (png_byte)(v & 0xff);
4157
4158
 
4159
                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
4160
                        *(sp + 5) = (png_byte)(v & 0xff);
4161
                     }
4162
4163
 
4164
                     {
4165
                        /* Background is already in screen gamma */
4166
                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
4167
                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
4168
                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
4169
                                & 0xff);
4170
                        *(sp + 3) = (png_byte)(png_ptr->background.green
4171
                                & 0xff);
4172
                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
4173
                                & 0xff);
4174
                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
4175
                     }
4176
4177
 
4178
                     {
4179
                        png_uint_16 v, w;
4180
4181
 
4182
                        png_composite_16(w, v, a, png_ptr->background_1.red);
4183
                        if (!optimize)
4184
                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
4185
                                8];
4186
                        *sp = (png_byte)((w >> 8) & 0xff);
4187
                        *(sp + 1) = (png_byte)(w & 0xff);
4188
4189
 
4190
                        png_composite_16(w, v, a, png_ptr->background_1.green);
4191
                        if (!optimize)
4192
                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
4193
                                8];
4194
4195
 
4196
                        *(sp + 3) = (png_byte)(w & 0xff);
4197
4198
 
4199
                        png_composite_16(w, v, a, png_ptr->background_1.blue);
4200
                        if (!optimize)
4201
                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
4202
                                8];
4203
4204
 
4205
                        *(sp + 5) = (png_byte)(w & 0xff);
4206
                     }
4207
                  }
4208
               }
4209
4210
 
4211
#endif
4212
               {
4213
                  sp = row;
4214
                  for (i = 0; i < row_width; i++, sp += 8)
4215
                  {
4216
                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
4217
                         << 8) + (png_uint_16)(*(sp + 7)));
4218
4219
 
4220
                     {
4221
                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
4222
                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
4223
                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
4224
                                & 0xff);
4225
                        *(sp + 3) = (png_byte)(png_ptr->background.green
4226
                                & 0xff);
4227
                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
4228
                                & 0xff);
4229
                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
4230
                     }
4231
4232
 
4233
                     {
4234
                        png_uint_16 v;
4235
4236
 
4237
                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
4238
                            + *(sp + 3));
4239
                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
4240
                            + *(sp + 5));
4241
4242
 
4243
                        *sp = (png_byte)((v >> 8) & 0xff);
4244
                        *(sp + 1) = (png_byte)(v & 0xff);
4245
4246
 
4247
                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
4248
                        *(sp + 3) = (png_byte)(v & 0xff);
4249
4250
 
4251
                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
4252
                        *(sp + 5) = (png_byte)(v & 0xff);
4253
                     }
4254
                  }
4255
               }
4256
            }
4257
            break;
4258
         }
4259
4260
 
4261
            break;
4262
      }
4263
   }
4264
}
4265
#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */
4266
4267
 
4268
/* Gamma correct the image, avoiding the alpha channel.  Make sure
4269
 * you do this after you deal with the transparency issue on grayscale
4270
 * or RGB images. If your bit depth is 8, use gamma_table, if it
4271
 * is 16, use gamma_16_table and gamma_shift.  Build these with
4272
 * build_gamma_table().
4273
 */
4274
void /* PRIVATE */
4275
png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4276
{
4277
   png_const_bytep gamma_table = png_ptr->gamma_table;
4278
   png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
4279
   int gamma_shift = png_ptr->gamma_shift;
4280
4281
 
4282
   png_uint_32 i;
4283
   png_uint_32 row_width=row_info->width;
4284
4285
 
4286
4287
 
4288
       (row_info->bit_depth == 16 && gamma_16_table != NULL)))
4289
   {
4290
      switch (row_info->color_type)
4291
      {
4292
         case PNG_COLOR_TYPE_RGB:
4293
         {
4294
            if (row_info->bit_depth == 8)
4295
            {
4296
               sp = row;
4297
               for (i = 0; i < row_width; i++)
4298
               {
4299
                  *sp = gamma_table[*sp];
4300
                  sp++;
4301
                  *sp = gamma_table[*sp];
4302
                  sp++;
4303
                  *sp = gamma_table[*sp];
4304
                  sp++;
4305
               }
4306
            }
4307
4308
 
4309
            {
4310
               sp = row;
4311
               for (i = 0; i < row_width; i++)
4312
               {
4313
                  png_uint_16 v;
4314
4315
 
4316
                  *sp = (png_byte)((v >> 8) & 0xff);
4317
                  *(sp + 1) = (png_byte)(v & 0xff);
4318
                  sp += 2;
4319
4320
 
4321
                  *sp = (png_byte)((v >> 8) & 0xff);
4322
                  *(sp + 1) = (png_byte)(v & 0xff);
4323
                  sp += 2;
4324
4325
 
4326
                  *sp = (png_byte)((v >> 8) & 0xff);
4327
                  *(sp + 1) = (png_byte)(v & 0xff);
4328
                  sp += 2;
4329
               }
4330
            }
4331
            break;
4332
         }
4333
4334
 
4335
         {
4336
            if (row_info->bit_depth == 8)
4337
            {
4338
               sp = row;
4339
               for (i = 0; i < row_width; i++)
4340
               {
4341
                  *sp = gamma_table[*sp];
4342
                  sp++;
4343
4344
 
4345
                  sp++;
4346
4347
 
4348
                  sp++;
4349
4350
 
4351
               }
4352
            }
4353
4354
 
4355
            {
4356
               sp = row;
4357
               for (i = 0; i < row_width; i++)
4358
               {
4359
                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4360
                  *sp = (png_byte)((v >> 8) & 0xff);
4361
                  *(sp + 1) = (png_byte)(v & 0xff);
4362
                  sp += 2;
4363
4364
 
4365
                  *sp = (png_byte)((v >> 8) & 0xff);
4366
                  *(sp + 1) = (png_byte)(v & 0xff);
4367
                  sp += 2;
4368
4369
 
4370
                  *sp = (png_byte)((v >> 8) & 0xff);
4371
                  *(sp + 1) = (png_byte)(v & 0xff);
4372
                  sp += 4;
4373
               }
4374
            }
4375
            break;
4376
         }
4377
4378
 
4379
         {
4380
            if (row_info->bit_depth == 8)
4381
            {
4382
               sp = row;
4383
               for (i = 0; i < row_width; i++)
4384
               {
4385
                  *sp = gamma_table[*sp];
4386
                  sp += 2;
4387
               }
4388
            }
4389
4390
 
4391
            {
4392
               sp = row;
4393
               for (i = 0; i < row_width; i++)
4394
               {
4395
                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4396
                  *sp = (png_byte)((v >> 8) & 0xff);
4397
                  *(sp + 1) = (png_byte)(v & 0xff);
4398
                  sp += 4;
4399
               }
4400
            }
4401
            break;
4402
         }
4403
4404
 
4405
         {
4406
            if (row_info->bit_depth == 2)
4407
            {
4408
               sp = row;
4409
               for (i = 0; i < row_width; i += 4)
4410
               {
4411
                  int a = *sp & 0xc0;
4412
                  int b = *sp & 0x30;
4413
                  int c = *sp & 0x0c;
4414
                  int d = *sp & 0x03;
4415
4416
 
4417
                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
4418
                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
4419
                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
4420
                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
4421
                  sp++;
4422
               }
4423
            }
4424
4425
 
4426
            {
4427
               sp = row;
4428
               for (i = 0; i < row_width; i += 2)
4429
               {
4430
                  int msb = *sp & 0xf0;
4431
                  int lsb = *sp & 0x0f;
4432
4433
 
4434
                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
4435
                  sp++;
4436
               }
4437
            }
4438
4439
 
4440
            {
4441
               sp = row;
4442
               for (i = 0; i < row_width; i++)
4443
               {
4444
                  *sp = gamma_table[*sp];
4445
                  sp++;
4446
               }
4447
            }
4448
4449
 
4450
            {
4451
               sp = row;
4452
               for (i = 0; i < row_width; i++)
4453
               {
4454
                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4455
                  *sp = (png_byte)((v >> 8) & 0xff);
4456
                  *(sp + 1) = (png_byte)(v & 0xff);
4457
                  sp += 2;
4458
               }
4459
            }
4460
            break;
4461
         }
4462
4463
 
4464
            break;
4465
      }
4466
   }
4467
}
4468
#endif
4469
4470
 
4471
/* Encode the alpha channel to the output gamma (the input channel is always
4472
 * linear.)  Called only with color types that have an alpha channel.  Needs the
4473
 * from_1 tables.
4474
 */
4475
void /* PRIVATE */
4476
png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4477
{
4478
   png_uint_32 row_width = row_info->width;
4479
4480
 
4481
4482
 
4483
   {
4484
      if (row_info->bit_depth == 8)
4485
      {
4486
         PNG_CONST png_bytep table = png_ptr->gamma_from_1;
4487
4488
 
4489
         {
4490
            PNG_CONST int step =
4491
               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
4492
4493
 
4494
            row += step - 1;
4495
4496
 
4497
               *row = table[*row];
4498
4499
 
4500
         }
4501
      }
4502
4503
 
4504
      {
4505
         PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
4506
         PNG_CONST int gamma_shift = png_ptr->gamma_shift;
4507
4508
 
4509
         {
4510
            PNG_CONST int step =
4511
               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
4512
4513
 
4514
            row += step - 2;
4515
4516
 
4517
            {
4518
               png_uint_16 v;
4519
4520
 
4521
               *row = (png_byte)((v >> 8) & 0xff);
4522
               *(row + 1) = (png_byte)(v & 0xff);
4523
            }
4524
4525
 
4526
         }
4527
      }
4528
   }
4529
4530
 
4531
    * so just issue a warning.
4532
    */
4533
   png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
4534
}
4535
#endif
4536
4537
 
4538
/* Expands a palette row to an RGB or RGBA row depending
4539
 * upon whether you supply trans and num_trans.
4540
 */
4541
void /* PRIVATE */
4542
png_do_expand_palette(png_row_infop row_info, png_bytep row,
4543
   png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
4544
{
4545
   int shift, value;
4546
   png_bytep sp, dp;
4547
   png_uint_32 i;
4548
   png_uint_32 row_width=row_info->width;
4549
4550
 
4551
4552
 
4553
   {
4554
      if (row_info->bit_depth < 8)
4555
      {
4556
         switch (row_info->bit_depth)
4557
         {
4558
            case 1:
4559
            {
4560
               sp = row + (png_size_t)((row_width - 1) >> 3);
4561
               dp = row + (png_size_t)row_width - 1;
4562
               shift = 7 - (int)((row_width + 7) & 0x07);
4563
               for (i = 0; i < row_width; i++)
4564
               {
4565
                  if ((*sp >> shift) & 0x01)
4566
                     *dp = 1;
4567
4568
 
4569
                     *dp = 0;
4570
4571
 
4572
                  {
4573
                     shift = 0;
4574
                     sp--;
4575
                  }
4576
4577
 
4578
                     shift++;
4579
4580
 
4581
               }
4582
               break;
4583
            }
4584
4585
 
4586
            {
4587
               sp = row + (png_size_t)((row_width - 1) >> 2);
4588
               dp = row + (png_size_t)row_width - 1;
4589
               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4590
               for (i = 0; i < row_width; i++)
4591
               {
4592
                  value = (*sp >> shift) & 0x03;
4593
                  *dp = (png_byte)value;
4594
                  if (shift == 6)
4595
                  {
4596
                     shift = 0;
4597
                     sp--;
4598
                  }
4599
4600
 
4601
                     shift += 2;
4602
4603
 
4604
               }
4605
               break;
4606
            }
4607
4608
 
4609
            {
4610
               sp = row + (png_size_t)((row_width - 1) >> 1);
4611
               dp = row + (png_size_t)row_width - 1;
4612
               shift = (int)((row_width & 0x01) << 2);
4613
               for (i = 0; i < row_width; i++)
4614
               {
4615
                  value = (*sp >> shift) & 0x0f;
4616
                  *dp = (png_byte)value;
4617
                  if (shift == 4)
4618
                  {
4619
                     shift = 0;
4620
                     sp--;
4621
                  }
4622
4623
 
4624
                     shift += 4;
4625
4626
 
4627
               }
4628
               break;
4629
            }
4630
4631
 
4632
               break;
4633
         }
4634
         row_info->bit_depth = 8;
4635
         row_info->pixel_depth = 8;
4636
         row_info->rowbytes = row_width;
4637
      }
4638
4639
 
4640
      {
4641
         {
4642
            if (num_trans > 0)
4643
            {
4644
               sp = row + (png_size_t)row_width - 1;
4645
               dp = row + (png_size_t)(row_width << 2) - 1;
4646
4647
 
4648
               {
4649
                  if ((int)(*sp) >= num_trans)
4650
                     *dp-- = 0xff;
4651
4652
 
4653
                     *dp-- = trans_alpha[*sp];
4654
4655
 
4656
                  *dp-- = palette[*sp].green;
4657
                  *dp-- = palette[*sp].red;
4658
                  sp--;
4659
               }
4660
               row_info->bit_depth = 8;
4661
               row_info->pixel_depth = 32;
4662
               row_info->rowbytes = row_width * 4;
4663
               row_info->color_type = 6;
4664
               row_info->channels = 4;
4665
            }
4666
4667
 
4668
            {
4669
               sp = row + (png_size_t)row_width - 1;
4670
               dp = row + (png_size_t)(row_width * 3) - 1;
4671
4672
 
4673
               {
4674
                  *dp-- = palette[*sp].blue;
4675
                  *dp-- = palette[*sp].green;
4676
                  *dp-- = palette[*sp].red;
4677
                  sp--;
4678
               }
4679
4680
 
4681
               row_info->pixel_depth = 24;
4682
               row_info->rowbytes = row_width * 3;
4683
               row_info->color_type = 2;
4684
               row_info->channels = 3;
4685
            }
4686
         }
4687
      }
4688
   }
4689
}
4690
4691
 
4692
 * expanded transparency value is supplied, an alpha channel is built.
4693
 */
4694
void /* PRIVATE */
4695
png_do_expand(png_row_infop row_info, png_bytep row,
4696
    png_const_color_16p trans_color)
4697
{
4698
   int shift, value;
4699
   png_bytep sp, dp;
4700
   png_uint_32 i;
4701
   png_uint_32 row_width=row_info->width;
4702
4703
 
4704
4705
 
4706
      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
4707
      {
4708
         unsigned int gray = trans_color ? trans_color->gray : 0;
4709
4710
 
4711
         {
4712
            switch (row_info->bit_depth)
4713
            {
4714
               case 1:
4715
               {
4716
                  gray = (gray & 0x01) * 0xff;
4717
                  sp = row + (png_size_t)((row_width - 1) >> 3);
4718
                  dp = row + (png_size_t)row_width - 1;
4719
                  shift = 7 - (int)((row_width + 7) & 0x07);
4720
                  for (i = 0; i < row_width; i++)
4721
                  {
4722
                     if ((*sp >> shift) & 0x01)
4723
                        *dp = 0xff;
4724
4725
 
4726
                        *dp = 0;
4727
4728
 
4729
                     {
4730
                        shift = 0;
4731
                        sp--;
4732
                     }
4733
4734
 
4735
                        shift++;
4736
4737
 
4738
                  }
4739
                  break;
4740
               }
4741
4742
 
4743
               {
4744
                  gray = (gray & 0x03) * 0x55;
4745
                  sp = row + (png_size_t)((row_width - 1) >> 2);
4746
                  dp = row + (png_size_t)row_width - 1;
4747
                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4748
                  for (i = 0; i < row_width; i++)
4749
                  {
4750
                     value = (*sp >> shift) & 0x03;
4751
                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
4752
                        (value << 6));
4753
                     if (shift == 6)
4754
                     {
4755
                        shift = 0;
4756
                        sp--;
4757
                     }
4758
4759
 
4760
                        shift += 2;
4761
4762
 
4763
                  }
4764
                  break;
4765
               }
4766
4767
 
4768
               {
4769
                  gray = (gray & 0x0f) * 0x11;
4770
                  sp = row + (png_size_t)((row_width - 1) >> 1);
4771
                  dp = row + (png_size_t)row_width - 1;
4772
                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
4773
                  for (i = 0; i < row_width; i++)
4774
                  {
4775
                     value = (*sp >> shift) & 0x0f;
4776
                     *dp = (png_byte)(value | (value << 4));
4777
                     if (shift == 4)
4778
                     {
4779
                        shift = 0;
4780
                        sp--;
4781
                     }
4782
4783
 
4784
                        shift = 4;
4785
4786
 
4787
                  }
4788
                  break;
4789
               }
4790
4791
 
4792
                  break;
4793
            }
4794
4795
 
4796
            row_info->pixel_depth = 8;
4797
            row_info->rowbytes = row_width;
4798
         }
4799
4800
 
4801
         {
4802
            if (row_info->bit_depth == 8)
4803
            {
4804
               gray = gray & 0xff;
4805
               sp = row + (png_size_t)row_width - 1;
4806
               dp = row + (png_size_t)(row_width << 1) - 1;
4807
4808
 
4809
               {
4810
                  if (*sp == gray)
4811
                     *dp-- = 0;
4812
4813
 
4814
                     *dp-- = 0xff;
4815
4816
 
4817
               }
4818
            }
4819
4820
 
4821
            {
4822
               unsigned int gray_high = (gray >> 8) & 0xff;
4823
               unsigned int gray_low = gray & 0xff;
4824
               sp = row + row_info->rowbytes - 1;
4825
               dp = row + (row_info->rowbytes << 1) - 1;
4826
               for (i = 0; i < row_width; i++)
4827
               {
4828
                  if (*(sp - 1) == gray_high && *(sp) == gray_low)
4829
                  {
4830
                     *dp-- = 0;
4831
                     *dp-- = 0;
4832
                  }
4833
4834
 
4835
                  {
4836
                     *dp-- = 0xff;
4837
                     *dp-- = 0xff;
4838
                  }
4839
4840
 
4841
                  *dp-- = *sp--;
4842
               }
4843
            }
4844
4845
 
4846
            row_info->channels = 2;
4847
            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
4848
            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
4849
               row_width);
4850
         }
4851
      }
4852
      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color)
4853
      {
4854
         if (row_info->bit_depth == 8)
4855
         {
4856
            png_byte red = (png_byte)(trans_color->red & 0xff);
4857
            png_byte green = (png_byte)(trans_color->green & 0xff);
4858
            png_byte blue = (png_byte)(trans_color->blue & 0xff);
4859
            sp = row + (png_size_t)row_info->rowbytes - 1;
4860
            dp = row + (png_size_t)(row_width << 2) - 1;
4861
            for (i = 0; i < row_width; i++)
4862
            {
4863
               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
4864
                  *dp-- = 0;
4865
4866
 
4867
                  *dp-- = 0xff;
4868
4869
 
4870
               *dp-- = *sp--;
4871
               *dp-- = *sp--;
4872
            }
4873
         }
4874
         else if (row_info->bit_depth == 16)
4875
         {
4876
            png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
4877
            png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
4878
            png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
4879
            png_byte red_low = (png_byte)(trans_color->red & 0xff);
4880
            png_byte green_low = (png_byte)(trans_color->green & 0xff);
4881
            png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
4882
            sp = row + row_info->rowbytes - 1;
4883
            dp = row + (png_size_t)(row_width << 3) - 1;
4884
            for (i = 0; i < row_width; i++)
4885
            {
4886
               if (*(sp - 5) == red_high &&
4887
                   *(sp - 4) == red_low &&
4888
                   *(sp - 3) == green_high &&
4889
                   *(sp - 2) == green_low &&
4890
                   *(sp - 1) == blue_high &&
4891
                   *(sp    ) == blue_low)
4892
               {
4893
                  *dp-- = 0;
4894
                  *dp-- = 0;
4895
               }
4896
4897
 
4898
               {
4899
                  *dp-- = 0xff;
4900
                  *dp-- = 0xff;
4901
               }
4902
4903
 
4904
               *dp-- = *sp--;
4905
               *dp-- = *sp--;
4906
               *dp-- = *sp--;
4907
               *dp-- = *sp--;
4908
               *dp-- = *sp--;
4909
            }
4910
         }
4911
         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
4912
         row_info->channels = 4;
4913
         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
4914
         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4915
      }
4916
   }
4917
}
4918
#endif
4919
4920
 
4921
/* If the bit depth is 8 and the color type is not a palette type expand the
4922
 * whole row to 16 bits.  Has no effect otherwise.
4923
 */
4924
void /* PRIVATE */
4925
png_do_expand_16(png_row_infop row_info, png_bytep row)
4926
{
4927
   if (row_info->bit_depth == 8 &&
4928
      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
4929
   {
4930
      /* The row have a sequence of bytes containing [0..255] and we need
4931
       * to turn it into another row containing [0..65535], to do this we
4932
       * calculate:
4933
       *
4934
       *  (input / 255) * 65535
4935
       *
4936
       *  Which happens to be exactly input * 257 and this can be achieved
4937
       *  simply by byte replication in place (copying backwards).
4938
       */
4939
      png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
4940
      png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
4941
      while (dp > sp)
4942
         dp[-2] = dp[-1] = *--sp, dp -= 2;
4943
4944
 
4945
      row_info->bit_depth = 16;
4946
      row_info->pixel_depth = (png_byte)(row_info->channels * 16);
4947
   }
4948
}
4949
#endif
4950
4951
 
4952
void /* PRIVATE */
4953
png_do_quantize(png_row_infop row_info, png_bytep row,
4954
    png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
4955
{
4956
   png_bytep sp, dp;
4957
   png_uint_32 i;
4958
   png_uint_32 row_width=row_info->width;
4959
4960
 
4961
4962
 
4963
   {
4964
      if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
4965
      {
4966
         int r, g, b, p;
4967
         sp = row;
4968
         dp = row;
4969
         for (i = 0; i < row_width; i++)
4970
         {
4971
            r = *sp++;
4972
            g = *sp++;
4973
            b = *sp++;
4974
4975
 
4976
             * it down to a reasonable formula.  For example, with
4977
             * 5 bits per color, we get:
4978
             * p = (((r >> 3) & 0x1f) << 10) |
4979
             *    (((g >> 3) & 0x1f) << 5) |
4980
             *    ((b >> 3) & 0x1f);
4981
             */
4982
            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4983
                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4984
                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4985
                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4986
                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4987
                (PNG_QUANTIZE_BLUE_BITS)) |
4988
                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4989
                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4990
4991
 
4992
         }
4993
4994
 
4995
         row_info->channels = 1;
4996
         row_info->pixel_depth = row_info->bit_depth;
4997
         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4998
      }
4999
5000
 
5001
         palette_lookup != NULL)
5002
      {
5003
         int r, g, b, p;
5004
         sp = row;
5005
         dp = row;
5006
         for (i = 0; i < row_width; i++)
5007
         {
5008
            r = *sp++;
5009
            g = *sp++;
5010
            b = *sp++;
5011
            sp++;
5012
5013
 
5014
                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
5015
                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
5016
                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
5017
                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
5018
                (PNG_QUANTIZE_BLUE_BITS)) |
5019
                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
5020
                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
5021
5022
 
5023
         }
5024
5025
 
5026
         row_info->channels = 1;
5027
         row_info->pixel_depth = row_info->bit_depth;
5028
         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
5029
      }
5030
5031
 
5032
         quantize_lookup)
5033
      {
5034
         sp = row;
5035
5036
 
5037
         {
5038
            *sp = quantize_lookup[*sp];
5039
         }
5040
      }
5041
   }
5042
}
5043
#endif /* PNG_READ_QUANTIZE_SUPPORTED */
5044
#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
5045
5046
 
5047
/* Undoes intrapixel differencing  */
5048
void /* PRIVATE */
5049
png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
5050
{
5051
   png_debug(1, "in png_do_read_intrapixel");
5052
5053
 
5054
       (row_info->color_type & PNG_COLOR_MASK_COLOR))
5055
   {
5056
      int bytes_per_pixel;
5057
      png_uint_32 row_width = row_info->width;
5058
5059
 
5060
      {
5061
         png_bytep rp;
5062
         png_uint_32 i;
5063
5064
 
5065
            bytes_per_pixel = 3;
5066
5067
 
5068
            bytes_per_pixel = 4;
5069
5070
 
5071
            return;
5072
5073
 
5074
         {
5075
            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
5076
            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
5077
         }
5078
      }
5079
      else if (row_info->bit_depth == 16)
5080
      {
5081
         png_bytep rp;
5082
         png_uint_32 i;
5083
5084
 
5085
            bytes_per_pixel = 6;
5086
5087
 
5088
            bytes_per_pixel = 8;
5089
5090
 
5091
            return;
5092
5093
 
5094
         {
5095
            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
5096
            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
5097
            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
5098
            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
5099
            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
5100
            *(rp    ) = (png_byte)((red >> 8) & 0xff);
5101
            *(rp + 1) = (png_byte)(red & 0xff);
5102
            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
5103
            *(rp + 5) = (png_byte)(blue & 0xff);
5104
         }
5105
      }
5106
   }
5107
}
5108
#endif /* PNG_MNG_FEATURES_SUPPORTED */
5109
#endif /* PNG_READ_SUPPORTED */
5110
>