Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1897 serge 1
 
2
 *
3
 * Last changed in libpng 1.5.0 [January 6, 2011]
4
 * Copyright (c) 1998-2011 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
13
 
14
15
 
16
17
 
18
/* Place a 32-bit number into a buffer in PNG byte order.  We work
19
 * with unsigned numbers for convenience, although one supported
20
 * ancillary chunk uses signed (two's complement) numbers.
21
 */
22
void PNGAPI
23
png_save_uint_32(png_bytep buf, png_uint_32 i)
24
{
25
   buf[0] = (png_byte)((i >> 24) & 0xff);
26
   buf[1] = (png_byte)((i >> 16) & 0xff);
27
   buf[2] = (png_byte)((i >> 8) & 0xff);
28
   buf[3] = (png_byte)(i & 0xff);
29
}
30
31
 
32
/* The png_save_int_32 function assumes integers are stored in two's
33
 * complement format.  If this isn't the case, then this routine needs to
34
 * be modified to write data in two's complement format.  Note that,
35
 * the following works correctly even if png_int_32 has more than 32 bits
36
 * (compare the more complex code required on read for sign extention.)
37
 */
38
void PNGAPI
39
png_save_int_32(png_bytep buf, png_int_32 i)
40
{
41
   buf[0] = (png_byte)((i >> 24) & 0xff);
42
   buf[1] = (png_byte)((i >> 16) & 0xff);
43
   buf[2] = (png_byte)((i >> 8) & 0xff);
44
   buf[3] = (png_byte)(i & 0xff);
45
}
46
#endif
47
48
 
49
 * The parameter is declared unsigned int, not png_uint_16,
50
 * just to avoid potential problems on pre-ANSI C compilers.
51
 */
52
void PNGAPI
53
png_save_uint_16(png_bytep buf, unsigned int i)
54
{
55
   buf[0] = (png_byte)((i >> 8) & 0xff);
56
   buf[1] = (png_byte)(i & 0xff);
57
}
58
#endif
59
60
 
61
 * the magic bytes of the signature, or more likely, the PNG stream is
62
 * being embedded into another stream and doesn't need its own signature,
63
 * we should call png_set_sig_bytes() to tell libpng how many of the
64
 * bytes have already been written.
65
 */
66
void PNGAPI
67
png_write_sig(png_structp png_ptr)
68
{
69
   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
70
71
 
72
   /* Inform the I/O callback that the signature is being written */
73
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
74
#endif
75
76
 
77
   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
78
      (png_size_t)(8 - png_ptr->sig_bytes));
79
80
 
81
      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
82
}
83
84
 
85
 * representing the chunk name.  The array must be at least 4 bytes in
86
 * length, and does not need to be null terminated.  To be safe, pass the
87
 * pre-defined chunk names here, and if you need a new one, define it
88
 * where the others are defined.  The length is the length of the data.
89
 * All the data must be present.  If that is not possible, use the
90
 * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
91
 * functions instead.
92
 */
93
void PNGAPI
94
png_write_chunk(png_structp png_ptr, png_const_bytep chunk_name,
95
   png_const_bytep data, png_size_t length)
96
{
97
   if (png_ptr == NULL)
98
      return;
99
100
 
101
   png_write_chunk_data(png_ptr, data, (png_size_t)length);
102
   png_write_chunk_end(png_ptr);
103
}
104
105
 
106
 * The total_length is the sum of the lengths of all the data you will be
107
 * passing in png_write_chunk_data().
108
 */
109
void PNGAPI
110
png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name,
111
    png_uint_32 length)
112
{
113
   png_byte buf[8];
114
115
 
116
      (unsigned long)length);
117
118
 
119
      return;
120
121
 
122
   /* Inform the I/O callback that the chunk header is being written.
123
    * PNG_IO_CHUNK_HDR requires a single I/O call.
124
    */
125
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
126
#endif
127
128
 
129
   png_save_uint_32(buf, length);
130
   png_memcpy(buf + 4, chunk_name, 4);
131
   png_write_data(png_ptr, buf, (png_size_t)8);
132
133
 
134
   png_memcpy(png_ptr->chunk_name, chunk_name, 4);
135
136
 
137
   png_reset_crc(png_ptr);
138
139
 
140
141
 
142
   /* Inform the I/O callback that chunk data will (possibly) be written.
143
    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
144
    */
145
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
146
#endif
147
}
148
149
 
150
 * Note that multiple calls to this function are allowed, and that the
151
 * sum of the lengths from these calls *must* add up to the total_length
152
 * given to png_write_chunk_start().
153
 */
154
void PNGAPI
155
png_write_chunk_data(png_structp png_ptr, png_const_bytep data,
156
    png_size_t length)
157
{
158
   /* Write the data, and run the CRC over it */
159
   if (png_ptr == NULL)
160
      return;
161
162
 
163
   {
164
      png_write_data(png_ptr, data, length);
165
166
 
167
       * in case that the user I/O routine alters it.
168
       */
169
      png_calculate_crc(png_ptr, data, length);
170
   }
171
}
172
173
 
174
void PNGAPI
175
png_write_chunk_end(png_structp png_ptr)
176
{
177
   png_byte buf[4];
178
179
 
180
181
 
182
   /* Inform the I/O callback that the chunk CRC is being written.
183
    * PNG_IO_CHUNK_CRC requires a single I/O function call.
184
    */
185
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
186
#endif
187
188
 
189
   png_save_uint_32(buf, png_ptr->crc);
190
191
 
192
}
193
194
 
195
/* This pair of functions encapsulates the operation of (a) compressing a
196
 * text string, and (b) issuing it later as a series of chunk data writes.
197
 * The compression_state structure is shared context for these functions
198
 * set up by the caller in order to make the whole mess thread-safe.
199
 */
200
201
 
202
{
203
   png_const_bytep input;   /* The uncompressed input data */
204
   png_size_t input_len;    /* Its length */
205
   int num_output_ptr;      /* Number of output pointers used */
206
   int max_output_ptr;      /* Size of output_ptr */
207
   png_bytep *output_ptr;   /* Array of pointers to output */
208
} compression_state;
209
210
 
211
static int /* PRIVATE */
212
png_text_compress(png_structp png_ptr,
213
    png_const_charp text, png_size_t text_len, int compression,
214
    compression_state *comp)
215
{
216
   int ret;
217
218
 
219
   comp->max_output_ptr = 0;
220
   comp->output_ptr = NULL;
221
   comp->input = NULL;
222
   comp->input_len = 0;
223
224
 
225
   if (compression == PNG_TEXT_COMPRESSION_NONE)
226
   {
227
      comp->input = (png_const_bytep)text;
228
      comp->input_len = text_len;
229
      return((int)text_len);
230
   }
231
232
 
233
   {
234
#ifdef PNG_CONSOLE_IO_SUPPORTED
235
      char msg[50];
236
      png_snprintf(msg, 50, "Unknown compression type %d", compression);
237
      png_warning(png_ptr, msg);
238
#else
239
      png_warning(png_ptr, "Unknown compression type");
240
#endif
241
   }
242
243
 
244
    * which means we need to run the compressor first and save the
245
    * output.  This shouldn't be a problem, as the vast majority of
246
    * comments should be reasonable, but we will set up an array of
247
    * malloc'd pointers to be sure.
248
    *
249
    * If we knew the application was well behaved, we could simplify this
250
    * greatly by assuming we can always malloc an output buffer large
251
    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
252
    * and malloc this directly.  The only time this would be a bad idea is
253
    * if we can't malloc more than 64K and we have 64K of random input
254
    * data, or if the input string is incredibly large (although this
255
    * wouldn't cause a failure, just a slowdown due to swapping).
256
    */
257
258
 
259
   /* TODO: the following cast hides a potential overflow problem. */
260
   png_ptr->zstream.avail_in = (uInt)text_len;
261
   /* NOTE: assume zlib doesn't overwrite the input */
262
   png_ptr->zstream.next_in = (Bytef *)text;
263
   png_ptr->zstream.avail_out = png_ptr->zbuf_size;
264
   png_ptr->zstream.next_out = png_ptr->zbuf;
265
266
 
267
   do
268
   {
269
      /* Compress the data */
270
      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
271
272
 
273
      {
274
         /* Error */
275
         if (png_ptr->zstream.msg != NULL)
276
            png_error(png_ptr, png_ptr->zstream.msg);
277
278
 
279
            png_error(png_ptr, "zlib error");
280
      }
281
282
 
283
      if (!(png_ptr->zstream.avail_out))
284
      {
285
         /* Make sure the output array has room */
286
         if (comp->num_output_ptr >= comp->max_output_ptr)
287
         {
288
            int old_max;
289
290
 
291
            comp->max_output_ptr = comp->num_output_ptr + 4;
292
            if (comp->output_ptr != NULL)
293
            {
294
               png_bytepp old_ptr;
295
296
 
297
298
 
299
                   (png_alloc_size_t)
300
                   (comp->max_output_ptr * png_sizeof(png_charpp)));
301
302
 
303
                   * png_sizeof(png_charp));
304
305
 
306
            }
307
            else
308
               comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
309
                   (png_alloc_size_t)
310
                   (comp->max_output_ptr * png_sizeof(png_charp)));
311
         }
312
313
 
314
         comp->output_ptr[comp->num_output_ptr] =
315
             (png_bytep)png_malloc(png_ptr,
316
             (png_alloc_size_t)png_ptr->zbuf_size);
317
318
 
319
             png_ptr->zbuf_size);
320
321
 
322
323
 
324
         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
325
         png_ptr->zstream.next_out = png_ptr->zbuf;
326
      }
327
   /* Continue until we don't have any more to compress */
328
   } while (png_ptr->zstream.avail_in);
329
330
 
331
   do
332
   {
333
      /* Tell zlib we are finished */
334
      ret = deflate(&png_ptr->zstream, Z_FINISH);
335
336
 
337
      {
338
         /* Check to see if we need more room */
339
         if (!(png_ptr->zstream.avail_out))
340
         {
341
            /* Check to make sure our output array has room */
342
            if (comp->num_output_ptr >= comp->max_output_ptr)
343
            {
344
               int old_max;
345
346
 
347
               comp->max_output_ptr = comp->num_output_ptr + 4;
348
               if (comp->output_ptr != NULL)
349
               {
350
                  png_bytepp old_ptr;
351
352
 
353
354
 
355
                  comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
356
                      (png_alloc_size_t)(comp->max_output_ptr *
357
                      png_sizeof(png_charp)));
358
359
 
360
                      old_max * png_sizeof(png_charp));
361
362
 
363
               }
364
365
 
366
                  comp->output_ptr = (png_bytepp)png_malloc(png_ptr,
367
                      (png_alloc_size_t)(comp->max_output_ptr *
368
                      png_sizeof(png_charp)));
369
            }
370
371
 
372
            comp->output_ptr[comp->num_output_ptr] =
373
                (png_bytep)png_malloc(png_ptr,
374
                (png_alloc_size_t)png_ptr->zbuf_size);
375
376
 
377
                png_ptr->zbuf_size);
378
379
 
380
381
 
382
            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
383
            png_ptr->zstream.next_out = png_ptr->zbuf;
384
         }
385
      }
386
      else if (ret != Z_STREAM_END)
387
      {
388
         /* We got an error */
389
         if (png_ptr->zstream.msg != NULL)
390
            png_error(png_ptr, png_ptr->zstream.msg);
391
392
 
393
            png_error(png_ptr, "zlib error");
394
      }
395
   } while (ret != Z_STREAM_END);
396
397
 
398
   text_len = png_ptr->zbuf_size * comp->num_output_ptr;
399
400
 
401
      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
402
403
 
404
}
405
406
 
407
static void /* PRIVATE */
408
png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
409
{
410
   int i;
411
412
 
413
   if (comp->input)
414
   {
415
      png_write_chunk_data(png_ptr, comp->input, comp->input_len);
416
417
 
418
   }
419
420
 
421
   for (i = 0; i < comp->num_output_ptr; i++)
422
   {
423
      png_write_chunk_data(png_ptr, comp->output_ptr[i],
424
          (png_size_t)png_ptr->zbuf_size);
425
426
 
427
   }
428
429
 
430
      png_free(png_ptr, comp->output_ptr);
431
432
 
433
   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
434
      png_write_chunk_data(png_ptr, png_ptr->zbuf,
435
          (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
436
437
 
438
   deflateReset(&png_ptr->zstream);
439
   png_ptr->zstream.data_type = Z_BINARY;
440
}
441
#endif
442
443
 
444
 * information.  Note that the rest of this code depends upon this
445
 * information being correct.
446
 */
447
void /* PRIVATE */
448
png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
449
    int bit_depth, int color_type, int compression_type, int filter_type,
450
    int interlace_type)
451
{
452
   PNG_IHDR;
453
   int ret;
454
455
 
456
457
 
458
459
 
460
   switch (color_type)
461
   {
462
      case PNG_COLOR_TYPE_GRAY:
463
         switch (bit_depth)
464
         {
465
            case 1:
466
            case 2:
467
            case 4:
468
            case 8:
469
#ifdef PNG_WRITE_16BIT_SUPPORTED
470
            case 16:
471
#endif
472
               png_ptr->channels = 1; break;
473
474
 
475
               png_error(png_ptr,
476
                   "Invalid bit depth for grayscale image");
477
         }
478
         break;
479
480
 
481
#ifdef PNG_WRITE_16BIT_SUPPORTED
482
         if (bit_depth != 8 && bit_depth != 16)
483
#else
484
         if (bit_depth != 8)
485
#endif
486
            png_error(png_ptr, "Invalid bit depth for RGB image");
487
488
 
489
         break;
490
491
 
492
         switch (bit_depth)
493
         {
494
            case 1:
495
            case 2:
496
            case 4:
497
            case 8:
498
               png_ptr->channels = 1;
499
               break;
500
501
 
502
               png_error(png_ptr, "Invalid bit depth for paletted image");
503
         }
504
         break;
505
506
 
507
         if (bit_depth != 8 && bit_depth != 16)
508
            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
509
510
 
511
         break;
512
513
 
514
#ifdef PNG_WRITE_16BIT_SUPPORTED
515
         if (bit_depth != 8 && bit_depth != 16)
516
#else
517
         if (bit_depth != 8)
518
#endif
519
            png_error(png_ptr, "Invalid bit depth for RGBA image");
520
521
 
522
         break;
523
524
 
525
         png_error(png_ptr, "Invalid image color type specified");
526
   }
527
528
 
529
   {
530
      png_warning(png_ptr, "Invalid compression type specified");
531
      compression_type = PNG_COMPRESSION_TYPE_BASE;
532
   }
533
534
 
535
    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
536
    * 2. Libpng did not write a PNG signature (this filter_method is only
537
    *    used in PNG datastreams that are embedded in MNG datastreams) and
538
    * 3. The application called png_permit_mng_features with a mask that
539
    *    included PNG_FLAG_MNG_FILTER_64 and
540
    * 4. The filter_method is 64 and
541
    * 5. The color_type is RGB or RGBA
542
    */
543
   if (
544
#ifdef PNG_MNG_FEATURES_SUPPORTED
545
       !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
546
       ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
547
       (color_type == PNG_COLOR_TYPE_RGB ||
548
        color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
549
       (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
550
#endif
551
       filter_type != PNG_FILTER_TYPE_BASE)
552
   {
553
      png_warning(png_ptr, "Invalid filter type specified");
554
      filter_type = PNG_FILTER_TYPE_BASE;
555
   }
556
557
 
558
   if (interlace_type != PNG_INTERLACE_NONE &&
559
       interlace_type != PNG_INTERLACE_ADAM7)
560
   {
561
      png_warning(png_ptr, "Invalid interlace type specified");
562
      interlace_type = PNG_INTERLACE_ADAM7;
563
   }
564
#else
565
   interlace_type=PNG_INTERLACE_NONE;
566
#endif
567
568
 
569
   png_ptr->bit_depth = (png_byte)bit_depth;
570
   png_ptr->color_type = (png_byte)color_type;
571
   png_ptr->interlaced = (png_byte)interlace_type;
572
#ifdef PNG_MNG_FEATURES_SUPPORTED
573
   png_ptr->filter_type = (png_byte)filter_type;
574
#endif
575
   png_ptr->compression_type = (png_byte)compression_type;
576
   png_ptr->width = width;
577
   png_ptr->height = height;
578
579
 
580
   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
581
   /* Set the usr info, so any transformations can modify it */
582
   png_ptr->usr_width = png_ptr->width;
583
   png_ptr->usr_bit_depth = png_ptr->bit_depth;
584
   png_ptr->usr_channels = png_ptr->channels;
585
586
 
587
   png_save_uint_32(buf, width);
588
   png_save_uint_32(buf + 4, height);
589
   buf[8] = (png_byte)bit_depth;
590
   buf[9] = (png_byte)color_type;
591
   buf[10] = (png_byte)compression_type;
592
   buf[11] = (png_byte)filter_type;
593
   buf[12] = (png_byte)interlace_type;
594
595
 
596
   png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
597
598
 
599
   png_ptr->zstream.zalloc = png_zalloc;
600
   png_ptr->zstream.zfree = png_zfree;
601
   png_ptr->zstream.opaque = (voidpf)png_ptr;
602
603
 
604
   {
605
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
606
          png_ptr->bit_depth < 8)
607
         png_ptr->do_filter = PNG_FILTER_NONE;
608
609
 
610
         png_ptr->do_filter = PNG_ALL_FILTERS;
611
   }
612
613
 
614
   {
615
      if (png_ptr->do_filter != PNG_FILTER_NONE)
616
         png_ptr->zlib_strategy = Z_FILTERED;
617
618
 
619
         png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
620
   }
621
622
 
623
      png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
624
625
 
626
      png_ptr->zlib_mem_level = 8;
627
628
 
629
      png_ptr->zlib_window_bits = 15;
630
631
 
632
      png_ptr->zlib_method = 8;
633
634
 
635
       png_ptr->zlib_method, png_ptr->zlib_window_bits,
636
       png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
637
638
 
639
   {
640
      if (ret == Z_VERSION_ERROR)
641
         png_error(png_ptr,
642
            "zlib failed to initialize compressor -- version error");
643
644
 
645
         png_error(png_ptr,
646
             "zlib failed to initialize compressor -- stream error");
647
648
 
649
         png_error(png_ptr,
650
             "zlib failed to initialize compressor -- mem error");
651
652
 
653
   }
654
655
 
656
   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
657
   /* libpng is not interested in zstream.data_type, so set it
658
    * to a predefined value, to avoid its evaluation inside zlib
659
    */
660
   png_ptr->zstream.data_type = Z_BINARY;
661
662
 
663
}
664
665
 
666
 * correct order for PNG, so people can redefine it to any convenient
667
 * structure.
668
 */
669
void /* PRIVATE */
670
png_write_PLTE(png_structp png_ptr, png_const_colorp palette,
671
    png_uint_32 num_pal)
672
{
673
   PNG_PLTE;
674
   png_uint_32 i;
675
   png_const_colorp pal_ptr;
676
   png_byte buf[3];
677
678
 
679
680
 
681
#ifdef PNG_MNG_FEATURES_SUPPORTED
682
       !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
683
#endif
684
       num_pal == 0) || num_pal > 256)
685
   {
686
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
687
      {
688
         png_error(png_ptr, "Invalid number of colors in palette");
689
      }
690
691
 
692
      {
693
         png_warning(png_ptr, "Invalid number of colors in palette");
694
         return;
695
      }
696
   }
697
698
 
699
   {
700
      png_warning(png_ptr,
701
          "Ignoring request to write a PLTE chunk in grayscale PNG");
702
703
 
704
   }
705
706
 
707
   png_debug1(3, "num_palette = %d", png_ptr->num_palette);
708
709
 
710
#ifdef PNG_POINTER_INDEXING_SUPPORTED
711
712
 
713
   {
714
      buf[0] = pal_ptr->red;
715
      buf[1] = pal_ptr->green;
716
      buf[2] = pal_ptr->blue;
717
      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
718
   }
719
720
 
721
   /* This is a little slower but some buggy compilers need to do this
722
    * instead
723
    */
724
   pal_ptr=palette;
725
726
 
727
   {
728
      buf[0] = pal_ptr[i].red;
729
      buf[1] = pal_ptr[i].green;
730
      buf[2] = pal_ptr[i].blue;
731
      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
732
   }
733
734
 
735
   png_write_chunk_end(png_ptr);
736
   png_ptr->mode |= PNG_HAVE_PLTE;
737
}
738
739
 
740
void /* PRIVATE */
741
png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
742
{
743
   PNG_IDAT;
744
745
 
746
747
 
748
   /* This hack of the zlib stream is compliant to the stream specification. */
749
   if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
750
       png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
751
   {
752
      unsigned int z_cmf = data[0];  /* zlib compression method and flags */
753
      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
754
      {
755
         /* Avoid memory underflows and multiplication overflows.
756
          *
757
          * The conditions below are practically always satisfied;
758
          * however, they still must be checked.
759
          */
760
         if (length >= 2 &&
761
             png_ptr->height < 16384 && png_ptr->width < 16384)
762
         {
763
            png_uint_32 uncompressed_idat_size = png_ptr->height *
764
                ((png_ptr->width *
765
                png_ptr->channels * png_ptr->bit_depth + 15) >> 3);
766
            unsigned int z_cinfo = z_cmf >> 4;
767
            unsigned int half_z_window_size = 1 << (z_cinfo + 7);
768
            while (uncompressed_idat_size <= half_z_window_size &&
769
                half_z_window_size >= 256)
770
            {
771
               z_cinfo--;
772
               half_z_window_size >>= 1;
773
            }
774
775
 
776
777
 
778
            {
779
               int tmp;
780
               data[0] = (png_byte)z_cmf;
781
               tmp = data[1] & 0xe0;
782
               tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
783
               data[1] = (png_byte)tmp;
784
            }
785
         }
786
      }
787
788
 
789
         png_error(png_ptr,
790
             "Invalid zlib compression method or flags in IDAT");
791
   }
792
793
 
794
   png_ptr->mode |= PNG_HAVE_IDAT;
795
}
796
797
 
798
void /* PRIVATE */
799
png_write_IEND(png_structp png_ptr)
800
{
801
   PNG_IEND;
802
803
 
804
805
 
806
   png_ptr->mode |= PNG_HAVE_IEND;
807
}
808
809
 
810
/* Write a gAMA chunk */
811
void /* PRIVATE */
812
png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
813
{
814
   PNG_gAMA;
815
   png_byte buf[4];
816
817
 
818
819
 
820
   png_save_uint_32(buf, (png_uint_32)file_gamma);
821
   png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
822
}
823
#endif
824
825
 
826
/* Write a sRGB chunk */
827
void /* PRIVATE */
828
png_write_sRGB(png_structp png_ptr, int srgb_intent)
829
{
830
   PNG_sRGB;
831
   png_byte buf[1];
832
833
 
834
835
 
836
      png_warning(png_ptr,
837
          "Invalid sRGB rendering intent specified");
838
839
 
840
   png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
841
}
842
#endif
843
844
 
845
/* Write an iCCP chunk */
846
void /* PRIVATE */
847
png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
848
    png_const_charp profile, int profile_len)
849
{
850
   PNG_iCCP;
851
   png_size_t name_len;
852
   png_charp new_name;
853
   compression_state comp;
854
   int embedded_profile_len = 0;
855
856
 
857
858
 
859
   comp.max_output_ptr = 0;
860
   comp.output_ptr = NULL;
861
   comp.input = NULL;
862
   comp.input_len = 0;
863
864
 
865
      return;
866
867
 
868
      png_warning(png_ptr, "Unknown compression type in iCCP chunk");
869
870
 
871
      profile_len = 0;
872
873
 
874
      embedded_profile_len =
875
          ((*( (png_const_bytep)profile    ))<<24) |
876
          ((*( (png_const_bytep)profile + 1))<<16) |
877
          ((*( (png_const_bytep)profile + 2))<< 8) |
878
          ((*( (png_const_bytep)profile + 3))    );
879
880
 
881
   {
882
      png_warning(png_ptr,
883
          "Embedded profile length in iCCP chunk is negative");
884
885
 
886
      return;
887
   }
888
889
 
890
   {
891
      png_warning(png_ptr,
892
          "Embedded profile length too large in iCCP chunk");
893
894
 
895
      return;
896
   }
897
898
 
899
   {
900
      png_warning(png_ptr,
901
          "Truncating profile to actual length in iCCP chunk");
902
903
 
904
   }
905
906
 
907
      profile_len = png_text_compress(png_ptr, profile,
908
          (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp);
909
910
 
911
   png_write_chunk_start(png_ptr, png_iCCP,
912
       (png_uint_32)(name_len + profile_len + 2));
913
914
 
915
916
 
917
       (png_size_t)(name_len + 2));
918
919
 
920
      png_write_compressed_data_out(png_ptr, &comp);
921
922
 
923
   png_free(png_ptr, new_name);
924
}
925
#endif
926
927
 
928
/* Write a sPLT chunk */
929
void /* PRIVATE */
930
png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
931
{
932
   PNG_sPLT;
933
   png_size_t name_len;
934
   png_charp new_name;
935
   png_byte entrybuf[10];
936
   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
937
   png_size_t palette_size = entry_size * spalette->nentries;
938
   png_sPLT_entryp ep;
939
#ifndef PNG_POINTER_INDEXING_SUPPORTED
940
   int i;
941
#endif
942
943
 
944
945
 
946
      return;
947
948
 
949
   png_write_chunk_start(png_ptr, png_sPLT,
950
       (png_uint_32)(name_len + 2 + palette_size));
951
952
 
953
       (png_size_t)(name_len + 1));
954
955
 
956
957
 
958
#ifdef PNG_POINTER_INDEXING_SUPPORTED
959
   for (ep = spalette->entries; epentries + spalette->nentries; ep++)
960
   {
961
      if (spalette->depth == 8)
962
      {
963
         entrybuf[0] = (png_byte)ep->red;
964
         entrybuf[1] = (png_byte)ep->green;
965
         entrybuf[2] = (png_byte)ep->blue;
966
         entrybuf[3] = (png_byte)ep->alpha;
967
         png_save_uint_16(entrybuf + 4, ep->frequency);
968
      }
969
970
 
971
      {
972
         png_save_uint_16(entrybuf + 0, ep->red);
973
         png_save_uint_16(entrybuf + 2, ep->green);
974
         png_save_uint_16(entrybuf + 4, ep->blue);
975
         png_save_uint_16(entrybuf + 6, ep->alpha);
976
         png_save_uint_16(entrybuf + 8, ep->frequency);
977
      }
978
979
 
980
   }
981
#else
982
   ep=spalette->entries;
983
   for (i = 0; i>spalette->nentries; i++)
984
   {
985
      if (spalette->depth == 8)
986
      {
987
         entrybuf[0] = (png_byte)ep[i].red;
988
         entrybuf[1] = (png_byte)ep[i].green;
989
         entrybuf[2] = (png_byte)ep[i].blue;
990
         entrybuf[3] = (png_byte)ep[i].alpha;
991
         png_save_uint_16(entrybuf + 4, ep[i].frequency);
992
      }
993
994
 
995
      {
996
         png_save_uint_16(entrybuf + 0, ep[i].red);
997
         png_save_uint_16(entrybuf + 2, ep[i].green);
998
         png_save_uint_16(entrybuf + 4, ep[i].blue);
999
         png_save_uint_16(entrybuf + 6, ep[i].alpha);
1000
         png_save_uint_16(entrybuf + 8, ep[i].frequency);
1001
      }
1002
1003
 
1004
   }
1005
#endif
1006
1007
 
1008
   png_free(png_ptr, new_name);
1009
}
1010
#endif
1011
1012
 
1013
/* Write the sBIT chunk */
1014
void /* PRIVATE */
1015
png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type)
1016
{
1017
   PNG_sBIT;
1018
   png_byte buf[4];
1019
   png_size_t size;
1020
1021
 
1022
1023
 
1024
   if (color_type & PNG_COLOR_MASK_COLOR)
1025
   {
1026
      png_byte maxbits;
1027
1028
 
1029
          png_ptr->usr_bit_depth);
1030
1031
 
1032
          sbit->green == 0 || sbit->green > maxbits ||
1033
          sbit->blue == 0 || sbit->blue > maxbits)
1034
      {
1035
         png_warning(png_ptr, "Invalid sBIT depth specified");
1036
         return;
1037
      }
1038
1039
 
1040
      buf[1] = sbit->green;
1041
      buf[2] = sbit->blue;
1042
      size = 3;
1043
   }
1044
1045
 
1046
   {
1047
      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
1048
      {
1049
         png_warning(png_ptr, "Invalid sBIT depth specified");
1050
         return;
1051
      }
1052
1053
 
1054
      size = 1;
1055
   }
1056
1057
 
1058
   {
1059
      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
1060
      {
1061
         png_warning(png_ptr, "Invalid sBIT depth specified");
1062
         return;
1063
      }
1064
1065
 
1066
   }
1067
1068
 
1069
}
1070
#endif
1071
1072
 
1073
/* Write the cHRM chunk */
1074
void /* PRIVATE */
1075
png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
1076
    png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
1077
    png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
1078
    png_fixed_point blue_y)
1079
{
1080
   PNG_cHRM;
1081
   png_byte buf[32];
1082
1083
 
1084
1085
 
1086
#ifdef PNG_CHECK_cHRM_SUPPORTED
1087
   if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y,
1088
       green_x, green_y, blue_x, blue_y))
1089
#endif
1090
   {
1091
      png_save_uint_32(buf, (png_uint_32)white_x);
1092
      png_save_uint_32(buf + 4, (png_uint_32)white_y);
1093
1094
 
1095
      png_save_uint_32(buf + 12, (png_uint_32)red_y);
1096
1097
 
1098
      png_save_uint_32(buf + 20, (png_uint_32)green_y);
1099
1100
 
1101
      png_save_uint_32(buf + 28, (png_uint_32)blue_y);
1102
1103
 
1104
   }
1105
}
1106
#endif
1107
1108
 
1109
/* Write the tRNS chunk */
1110
void /* PRIVATE */
1111
png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
1112
    png_const_color_16p tran, int num_trans, int color_type)
1113
{
1114
   PNG_tRNS;
1115
   png_byte buf[6];
1116
1117
 
1118
1119
 
1120
   {
1121
      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
1122
      {
1123
         png_warning(png_ptr, "Invalid number of transparent colors specified");
1124
         return;
1125
      }
1126
1127
 
1128
      png_write_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans);
1129
   }
1130
1131
 
1132
   {
1133
      /* One 16 bit value */
1134
      if (tran->gray >= (1 << png_ptr->bit_depth))
1135
      {
1136
         png_warning(png_ptr,
1137
             "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
1138
1139
 
1140
      }
1141
1142
 
1143
      png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
1144
   }
1145
1146
 
1147
   {
1148
      /* Three 16 bit values */
1149
      png_save_uint_16(buf, tran->red);
1150
      png_save_uint_16(buf + 2, tran->green);
1151
      png_save_uint_16(buf + 4, tran->blue);
1152
#ifdef PNG_WRITE_16BIT_SUPPORTED
1153
      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1154
#else
1155
      if (buf[0] | buf[2] | buf[4])
1156
#endif
1157
      {
1158
         png_warning(png_ptr,
1159
           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
1160
         return;
1161
      }
1162
1163
 
1164
   }
1165
1166
 
1167
   {
1168
      png_warning(png_ptr, "Can't write tRNS with an alpha channel");
1169
   }
1170
}
1171
#endif
1172
1173
 
1174
/* Write the background chunk */
1175
void /* PRIVATE */
1176
png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
1177
{
1178
   PNG_bKGD;
1179
   png_byte buf[6];
1180
1181
 
1182
1183
 
1184
   {
1185
      if (
1186
#ifdef PNG_MNG_FEATURES_SUPPORTED
1187
          (png_ptr->num_palette ||
1188
          (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
1189
#endif
1190
         back->index >= png_ptr->num_palette)
1191
      {
1192
         png_warning(png_ptr, "Invalid background palette index");
1193
         return;
1194
      }
1195
1196
 
1197
      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
1198
   }
1199
1200
 
1201
   {
1202
      png_save_uint_16(buf, back->red);
1203
      png_save_uint_16(buf + 2, back->green);
1204
      png_save_uint_16(buf + 4, back->blue);
1205
#ifdef PNG_WRITE_16BIT_SUPPORTED
1206
      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1207
#else
1208
      if (buf[0] | buf[2] | buf[4])
1209
#endif
1210
      {
1211
         png_warning(png_ptr,
1212
             "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
1213
1214
 
1215
      }
1216
1217
 
1218
   }
1219
1220
 
1221
   {
1222
      if (back->gray >= (1 << png_ptr->bit_depth))
1223
      {
1224
         png_warning(png_ptr,
1225
             "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
1226
1227
 
1228
      }
1229
1230
 
1231
      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
1232
   }
1233
}
1234
#endif
1235
1236
 
1237
/* Write the histogram */
1238
void /* PRIVATE */
1239
png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist)
1240
{
1241
   PNG_hIST;
1242
   int i;
1243
   png_byte buf[3];
1244
1245
 
1246
1247
 
1248
   {
1249
      png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
1250
          png_ptr->num_palette);
1251
1252
 
1253
      return;
1254
   }
1255
1256
 
1257
1258
 
1259
   {
1260
      png_save_uint_16(buf, hist[i]);
1261
      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
1262
   }
1263
1264
 
1265
}
1266
#endif
1267
1268
 
1269
    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
1270
/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
1271
 * and if invalid, correct the keyword rather than discarding the entire
1272
 * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
1273
 * length, forbids leading or trailing whitespace, multiple internal spaces,
1274
 * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
1275
 *
1276
 * The new_key is allocated to hold the corrected keyword and must be freed
1277
 * by the calling routine.  This avoids problems with trying to write to
1278
 * static keywords without having to have duplicate copies of the strings.
1279
 */
1280
png_size_t /* PRIVATE */
1281
png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key)
1282
{
1283
   png_size_t key_len;
1284
   png_const_charp ikp;
1285
   png_charp kp, dp;
1286
   int kflag;
1287
   int kwarn=0;
1288
1289
 
1290
1291
 
1292
1293
 
1294
   {
1295
      png_warning(png_ptr, "zero length keyword");
1296
      return ((png_size_t)0);
1297
   }
1298
1299
 
1300
1301
 
1302
1303
 
1304
   {
1305
      png_warning(png_ptr, "Out of memory while procesing keyword");
1306
      return ((png_size_t)0);
1307
   }
1308
1309
 
1310
   for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++)
1311
   {
1312
      if ((png_byte)*ikp < 0x20 ||
1313
         ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1))
1314
      {
1315
#ifdef PNG_CONSOLE_IO_SUPPORTED
1316
         char msg[40];
1317
1318
 
1319
             "invalid keyword character 0x%02X", (png_byte)*ikp);
1320
         png_warning(png_ptr, msg);
1321
#else
1322
         png_warning(png_ptr, "invalid character in keyword");
1323
#endif
1324
         *dp = ' ';
1325
      }
1326
1327
 
1328
      {
1329
         *dp = *ikp;
1330
      }
1331
   }
1332
   *dp = '\0';
1333
1334
 
1335
   kp = *new_key + key_len - 1;
1336
   if (*kp == ' ')
1337
   {
1338
      png_warning(png_ptr, "trailing spaces removed from keyword");
1339
1340
 
1341
      {
1342
         *(kp--) = '\0';
1343
         key_len--;
1344
      }
1345
   }
1346
1347
 
1348
   kp = *new_key;
1349
   if (*kp == ' ')
1350
   {
1351
      png_warning(png_ptr, "leading spaces removed from keyword");
1352
1353
 
1354
      {
1355
         kp++;
1356
         key_len--;
1357
      }
1358
   }
1359
1360
 
1361
1362
 
1363
   for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
1364
   {
1365
      if (*kp == ' ' && kflag == 0)
1366
      {
1367
         *(dp++) = *kp;
1368
         kflag = 1;
1369
      }
1370
1371
 
1372
      {
1373
         key_len--;
1374
         kwarn = 1;
1375
      }
1376
1377
 
1378
      {
1379
         *(dp++) = *kp;
1380
         kflag = 0;
1381
      }
1382
   }
1383
   *dp = '\0';
1384
   if (kwarn)
1385
      png_warning(png_ptr, "extra interior spaces removed from keyword");
1386
1387
 
1388
   {
1389
      png_free(png_ptr, *new_key);
1390
      png_warning(png_ptr, "Zero length keyword");
1391
   }
1392
1393
 
1394
   {
1395
      png_warning(png_ptr, "keyword length must be 1 - 79 characters");
1396
      (*new_key)[79] = '\0';
1397
      key_len = 79;
1398
   }
1399
1400
 
1401
}
1402
#endif
1403
1404
 
1405
/* Write a tEXt chunk */
1406
void /* PRIVATE */
1407
png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
1408
    png_size_t text_len)
1409
{
1410
   PNG_tEXt;
1411
   png_size_t key_len;
1412
   png_charp new_key;
1413
1414
 
1415
1416
 
1417
      return;
1418
1419
 
1420
      text_len = 0;
1421
1422
 
1423
      text_len = png_strlen(text);
1424
1425
 
1426
   png_write_chunk_start(png_ptr, png_tEXt,
1427
       (png_uint_32)(key_len + text_len + 1));
1428
   /*
1429
    * We leave it to the application to meet PNG-1.0 requirements on the
1430
    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
1431
    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
1432
    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1433
    */
1434
   png_write_chunk_data(png_ptr, (png_bytep)new_key,
1435
       (png_size_t)(key_len + 1));
1436
1437
 
1438
      png_write_chunk_data(png_ptr, (png_const_bytep)text,
1439
          (png_size_t)text_len);
1440
1441
 
1442
   png_free(png_ptr, new_key);
1443
}
1444
#endif
1445
1446
 
1447
/* Write a compressed text chunk */
1448
void /* PRIVATE */
1449
png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
1450
    png_size_t text_len, int compression)
1451
{
1452
   PNG_zTXt;
1453
   png_size_t key_len;
1454
   png_byte buf;
1455
   png_charp new_key;
1456
   compression_state comp;
1457
1458
 
1459
1460
 
1461
   comp.max_output_ptr = 0;
1462
   comp.output_ptr = NULL;
1463
   comp.input = NULL;
1464
   comp.input_len = 0;
1465
1466
 
1467
   {
1468
      png_free(png_ptr, new_key);
1469
      return;
1470
   }
1471
1472
 
1473
   {
1474
      png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
1475
      png_free(png_ptr, new_key);
1476
      return;
1477
   }
1478
1479
 
1480
1481
 
1482
   text_len = png_text_compress(png_ptr, text, text_len, compression,
1483
       &comp);
1484
1485
 
1486
   png_write_chunk_start(png_ptr, png_zTXt,
1487
       (png_uint_32)(key_len+text_len + 2));
1488
1489
 
1490
   png_write_chunk_data(png_ptr, (png_bytep)new_key,
1491
       (png_size_t)(key_len + 1));
1492
1493
 
1494
1495
 
1496
1497
 
1498
   png_write_chunk_data(png_ptr, &buf, (png_size_t)1);
1499
1500
 
1501
   png_write_compressed_data_out(png_ptr, &comp);
1502
1503
 
1504
   png_write_chunk_end(png_ptr);
1505
}
1506
#endif
1507
1508
 
1509
/* Write an iTXt chunk */
1510
void /* PRIVATE */
1511
png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
1512
    png_const_charp lang, png_const_charp lang_key, png_const_charp text)
1513
{
1514
   PNG_iTXt;
1515
   png_size_t lang_len, key_len, lang_key_len, text_len;
1516
   png_charp new_lang;
1517
   png_charp new_key = NULL;
1518
   png_byte cbuf[2];
1519
   compression_state comp;
1520
1521
 
1522
1523
 
1524
   comp.max_output_ptr = 0;
1525
   comp.output_ptr = NULL;
1526
   comp.input = NULL;
1527
1528
 
1529
      return;
1530
1531
 
1532
   {
1533
      png_warning(png_ptr, "Empty language field in iTXt chunk");
1534
      new_lang = NULL;
1535
      lang_len = 0;
1536
   }
1537
1538
 
1539
      lang_key_len = 0;
1540
1541
 
1542
      lang_key_len = png_strlen(lang_key);
1543
1544
 
1545
      text_len = 0;
1546
1547
 
1548
      text_len = png_strlen(text);
1549
1550
 
1551
   text_len = png_text_compress(png_ptr, text, text_len, compression - 2,
1552
       &comp);
1553
1554
 
1555
 
1556
    * and the NULs after the key, lang, and lang_key parts
1557
    */
1558
1559
 
1560
        5 /* comp byte, comp flag, terminators for key, lang and lang_key */
1561
        + key_len
1562
        + lang_len
1563
        + lang_key_len
1564
        + text_len));
1565
1566
 
1567
    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
1568
    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
1569
    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1570
    */
1571
   png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1));
1572
1573
 
1574
   if (compression == PNG_ITXT_COMPRESSION_NONE ||
1575
       compression == PNG_TEXT_COMPRESSION_NONE)
1576
      cbuf[0] = 0;
1577
1578
 
1579
      cbuf[0] = 1;
1580
1581
 
1582
   cbuf[1] = 0;
1583
1584
 
1585
1586
 
1587
   png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf),
1588
       (png_size_t)(lang_len + 1));
1589
1590
 
1591
       (png_size_t)(lang_key_len + 1));
1592
1593
 
1594
1595
 
1596
1597
 
1598
   png_free(png_ptr, new_lang);
1599
}
1600
#endif
1601
1602
 
1603
/* Write the oFFs chunk */
1604
void /* PRIVATE */
1605
png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
1606
    int unit_type)
1607
{
1608
   PNG_oFFs;
1609
   png_byte buf[9];
1610
1611
 
1612
1613
 
1614
      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
1615
1616
 
1617
   png_save_int_32(buf + 4, y_offset);
1618
   buf[8] = (png_byte)unit_type;
1619
1620
 
1621
}
1622
#endif
1623
#ifdef PNG_WRITE_pCAL_SUPPORTED
1624
/* Write the pCAL chunk (described in the PNG extensions document) */
1625
void /* PRIVATE */
1626
png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
1627
    png_int_32 X1, int type, int nparams, png_const_charp units,
1628
    png_charpp params)
1629
{
1630
   PNG_pCAL;
1631
   png_size_t purpose_len, units_len, total_len;
1632
   png_uint_32p params_len;
1633
   png_byte buf[10];
1634
   png_charp new_purpose;
1635
   int i;
1636
1637
 
1638
1639
 
1640
      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1641
1642
 
1643
   png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
1644
   units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
1645
   png_debug1(3, "pCAL units length = %d", (int)units_len);
1646
   total_len = purpose_len + units_len + 10;
1647
1648
 
1649
       (png_alloc_size_t)(nparams * png_sizeof(png_uint_32)));
1650
1651
 
1652
    * null terminator for the last parameter.
1653
    */
1654
   for (i = 0; i < nparams; i++)
1655
   {
1656
      params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
1657
      png_debug2(3, "pCAL parameter %d length = %lu", i,
1658
          (unsigned long)params_len[i]);
1659
      total_len += (png_size_t)params_len[i];
1660
   }
1661
1662
 
1663
   png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
1664
   png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose,
1665
       (png_size_t)purpose_len);
1666
   png_save_int_32(buf, X0);
1667
   png_save_int_32(buf + 4, X1);
1668
   buf[8] = (png_byte)type;
1669
   buf[9] = (png_byte)nparams;
1670
   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
1671
   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
1672
1673
 
1674
1675
 
1676
   {
1677
      png_write_chunk_data(png_ptr, (png_const_bytep)params[i],
1678
          (png_size_t)params_len[i]);
1679
   }
1680
1681
 
1682
   png_write_chunk_end(png_ptr);
1683
}
1684
#endif
1685
1686
 
1687
/* Write the sCAL chunk */
1688
void /* PRIVATE */
1689
png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width,
1690
    png_const_charp height)
1691
{
1692
   PNG_sCAL;
1693
   png_byte buf[64];
1694
   png_size_t wlen, hlen, total_len;
1695
1696
 
1697
1698
 
1699
   hlen = png_strlen(height);
1700
   total_len = wlen + hlen + 2;
1701
1702
 
1703
   {
1704
      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
1705
      return;
1706
   }
1707
1708
 
1709
   png_memcpy(buf + 1, width, wlen + 1);      /* Append the '\0' here */
1710
   png_memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\0' here */
1711
1712
 
1713
   png_write_chunk(png_ptr, png_sCAL, buf, total_len);
1714
}
1715
#endif
1716
1717
 
1718
/* Write the pHYs chunk */
1719
void /* PRIVATE */
1720
png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
1721
    png_uint_32 y_pixels_per_unit,
1722
    int unit_type)
1723
{
1724
   PNG_pHYs;
1725
   png_byte buf[9];
1726
1727
 
1728
1729
 
1730
      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
1731
1732
 
1733
   png_save_uint_32(buf + 4, y_pixels_per_unit);
1734
   buf[8] = (png_byte)unit_type;
1735
1736
 
1737
}
1738
#endif
1739
1740
 
1741
/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
1742
 * or png_convert_from_time_t(), or fill in the structure yourself.
1743
 */
1744
void /* PRIVATE */
1745
png_write_tIME(png_structp png_ptr, png_const_timep mod_time)
1746
{
1747
   PNG_tIME;
1748
   png_byte buf[7];
1749
1750
 
1751
1752
 
1753
       mod_time->day    > 31 || mod_time->day    < 1 ||
1754
       mod_time->hour   > 23 || mod_time->second > 60)
1755
   {
1756
      png_warning(png_ptr, "Invalid time specified for tIME chunk");
1757
      return;
1758
   }
1759
1760
 
1761
   buf[2] = mod_time->month;
1762
   buf[3] = mod_time->day;
1763
   buf[4] = mod_time->hour;
1764
   buf[5] = mod_time->minute;
1765
   buf[6] = mod_time->second;
1766
1767
 
1768
}
1769
#endif
1770
1771
 
1772
void /* PRIVATE */
1773
png_write_start_row(png_structp png_ptr)
1774
{
1775
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1776
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1777
1778
 
1779
   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1780
1781
 
1782
   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1783
1784
 
1785
   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
1786
1787
 
1788
   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
1789
#endif
1790
1791
 
1792
1793
 
1794
1795
 
1796
       png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1);
1797
1798
 
1799
   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr,
1800
       (png_alloc_size_t)buf_size);
1801
1802
 
1803
1804
 
1805
   /* Set up filtering buffer, if using this filter */
1806
   if (png_ptr->do_filter & PNG_FILTER_SUB)
1807
   {
1808
      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
1809
1810
 
1811
   }
1812
1813
 
1814
   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
1815
   {
1816
      /* Set up previous row buffer */
1817
      png_ptr->prev_row = (png_bytep)png_calloc(png_ptr,
1818
          (png_alloc_size_t)buf_size);
1819
1820
 
1821
      {
1822
         png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
1823
            png_ptr->rowbytes + 1);
1824
1825
 
1826
      }
1827
1828
 
1829
      {
1830
         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
1831
             png_ptr->rowbytes + 1);
1832
1833
 
1834
      }
1835
1836
 
1837
      {
1838
         png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
1839
             png_ptr->rowbytes + 1);
1840
1841
 
1842
      }
1843
   }
1844
#endif /* PNG_WRITE_FILTER_SUPPORTED */
1845
1846
 
1847
   /* If interlaced, we need to set up width and height of pass */
1848
   if (png_ptr->interlaced)
1849
   {
1850
      if (!(png_ptr->transformations & PNG_INTERLACE))
1851
      {
1852
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
1853
             png_pass_ystart[0]) / png_pass_yinc[0];
1854
1855
 
1856
             png_pass_start[0]) / png_pass_inc[0];
1857
      }
1858
1859
 
1860
      {
1861
         png_ptr->num_rows = png_ptr->height;
1862
         png_ptr->usr_width = png_ptr->width;
1863
      }
1864
   }
1865
1866
 
1867
#endif
1868
   {
1869
      png_ptr->num_rows = png_ptr->height;
1870
      png_ptr->usr_width = png_ptr->width;
1871
   }
1872
1873
 
1874
   png_ptr->zstream.next_out = png_ptr->zbuf;
1875
}
1876
1877
 
1878
void /* PRIVATE */
1879
png_write_finish_row(png_structp png_ptr)
1880
{
1881
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1882
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1883
1884
 
1885
   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1886
1887
 
1888
   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1889
1890
 
1891
   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
1892
1893
 
1894
   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
1895
#endif
1896
1897
 
1898
1899
 
1900
1901
 
1902
   png_ptr->row_number++;
1903
1904
 
1905
   if (png_ptr->row_number < png_ptr->num_rows)
1906
      return;
1907
1908
 
1909
   /* If interlaced, go to next pass */
1910
   if (png_ptr->interlaced)
1911
   {
1912
      png_ptr->row_number = 0;
1913
      if (png_ptr->transformations & PNG_INTERLACE)
1914
      {
1915
         png_ptr->pass++;
1916
      }
1917
1918
 
1919
      {
1920
         /* Loop until we find a non-zero width or height pass */
1921
         do
1922
         {
1923
            png_ptr->pass++;
1924
1925
 
1926
               break;
1927
1928
 
1929
                png_pass_inc[png_ptr->pass] - 1 -
1930
                png_pass_start[png_ptr->pass]) /
1931
                png_pass_inc[png_ptr->pass];
1932
1933
 
1934
                png_pass_yinc[png_ptr->pass] - 1 -
1935
                png_pass_ystart[png_ptr->pass]) /
1936
                png_pass_yinc[png_ptr->pass];
1937
1938
 
1939
               break;
1940
1941
 
1942
1943
 
1944
1945
 
1946
      if (png_ptr->pass < 7)
1947
      {
1948
         if (png_ptr->prev_row != NULL)
1949
            png_memset(png_ptr->prev_row, 0,
1950
                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
1951
                png_ptr->usr_bit_depth, png_ptr->width)) + 1);
1952
1953
 
1954
      }
1955
   }
1956
#endif
1957
1958
 
1959
      to flush the compressor */
1960
   do
1961
   {
1962
      /* Tell the compressor we are done */
1963
      ret = deflate(&png_ptr->zstream, Z_FINISH);
1964
1965
 
1966
      if (ret == Z_OK)
1967
      {
1968
         /* Check to see if we need more room */
1969
         if (!(png_ptr->zstream.avail_out))
1970
         {
1971
            png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
1972
            png_ptr->zstream.next_out = png_ptr->zbuf;
1973
            png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1974
         }
1975
      }
1976
1977
 
1978
      {
1979
         if (png_ptr->zstream.msg != NULL)
1980
            png_error(png_ptr, png_ptr->zstream.msg);
1981
1982
 
1983
            png_error(png_ptr, "zlib error");
1984
      }
1985
   } while (ret != Z_STREAM_END);
1986
1987
 
1988
   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
1989
   {
1990
      png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
1991
          png_ptr->zstream.avail_out);
1992
   }
1993
1994
 
1995
   png_ptr->zstream.data_type = Z_BINARY;
1996
}
1997
1998
 
1999
/* Pick out the correct pixels for the interlace pass.
2000
 * The basic idea here is to go through the row with a source
2001
 * pointer and a destination pointer (sp and dp), and copy the
2002
 * correct pixels for the pass.  As the row gets compacted,
2003
 * sp will always be >= dp, so we should never overwrite anything.
2004
 * See the default: case for the easiest code to understand.
2005
 */
2006
void /* PRIVATE */
2007
png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
2008
{
2009
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2010
2011
 
2012
   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2013
2014
 
2015
   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2016
2017
 
2018
2019
 
2020
   if (pass < 6)
2021
   {
2022
      /* Each pixel depth is handled separately */
2023
      switch (row_info->pixel_depth)
2024
      {
2025
         case 1:
2026
         {
2027
            png_bytep sp;
2028
            png_bytep dp;
2029
            int shift;
2030
            int d;
2031
            int value;
2032
            png_uint_32 i;
2033
            png_uint_32 row_width = row_info->width;
2034
2035
 
2036
            d = 0;
2037
            shift = 7;
2038
2039
 
2040
               i += png_pass_inc[pass])
2041
            {
2042
               sp = row + (png_size_t)(i >> 3);
2043
               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
2044
               d |= (value << shift);
2045
2046
 
2047
               {
2048
                  shift = 7;
2049
                  *dp++ = (png_byte)d;
2050
                  d = 0;
2051
               }
2052
2053
 
2054
                  shift--;
2055
2056
 
2057
            if (shift != 7)
2058
               *dp = (png_byte)d;
2059
2060
 
2061
         }
2062
2063
 
2064
         {
2065
            png_bytep sp;
2066
            png_bytep dp;
2067
            int shift;
2068
            int d;
2069
            int value;
2070
            png_uint_32 i;
2071
            png_uint_32 row_width = row_info->width;
2072
2073
 
2074
            shift = 6;
2075
            d = 0;
2076
2077
 
2078
               i += png_pass_inc[pass])
2079
            {
2080
               sp = row + (png_size_t)(i >> 2);
2081
               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
2082
               d |= (value << shift);
2083
2084
 
2085
               {
2086
                  shift = 6;
2087
                  *dp++ = (png_byte)d;
2088
                  d = 0;
2089
               }
2090
2091
 
2092
                  shift -= 2;
2093
            }
2094
            if (shift != 6)
2095
               *dp = (png_byte)d;
2096
2097
 
2098
         }
2099
2100
 
2101
         {
2102
            png_bytep sp;
2103
            png_bytep dp;
2104
            int shift;
2105
            int d;
2106
            int value;
2107
            png_uint_32 i;
2108
            png_uint_32 row_width = row_info->width;
2109
2110
 
2111
            shift = 4;
2112
            d = 0;
2113
            for (i = png_pass_start[pass]; i < row_width;
2114
                i += png_pass_inc[pass])
2115
            {
2116
               sp = row + (png_size_t)(i >> 1);
2117
               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
2118
               d |= (value << shift);
2119
2120
 
2121
               {
2122
                  shift = 4;
2123
                  *dp++ = (png_byte)d;
2124
                  d = 0;
2125
               }
2126
2127
 
2128
                  shift -= 4;
2129
            }
2130
            if (shift != 4)
2131
               *dp = (png_byte)d;
2132
2133
 
2134
         }
2135
2136
 
2137
         {
2138
            png_bytep sp;
2139
            png_bytep dp;
2140
            png_uint_32 i;
2141
            png_uint_32 row_width = row_info->width;
2142
            png_size_t pixel_bytes;
2143
2144
 
2145
            dp = row;
2146
2147
 
2148
            pixel_bytes = (row_info->pixel_depth >> 3);
2149
2150
 
2151
            for (i = png_pass_start[pass]; i < row_width;
2152
               i += png_pass_inc[pass])
2153
            {
2154
               /* Find out where the original pixel is */
2155
               sp = row + (png_size_t)i * pixel_bytes;
2156
2157
 
2158
               if (dp != sp)
2159
                  png_memcpy(dp, sp, pixel_bytes);
2160
2161
 
2162
               dp += pixel_bytes;
2163
            }
2164
            break;
2165
         }
2166
      }
2167
      /* Set new row width */
2168
      row_info->width = (row_info->width +
2169
          png_pass_inc[pass] - 1 -
2170
          png_pass_start[pass]) /
2171
          png_pass_inc[pass];
2172
2173
 
2174
          row_info->width);
2175
   }
2176
}
2177
#endif
2178
2179
 
2180
 * been specified by the application, and then writes the row out with the
2181
 * chosen filter.
2182
 */
2183
#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
2184
#define PNG_HISHIFT 10
2185
#define PNG_LOMASK ((png_uint_32)0xffffL)
2186
#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
2187
void /* PRIVATE */
2188
png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
2189
{
2190
   png_bytep best_row;
2191
#ifdef PNG_WRITE_FILTER_SUPPORTED
2192
   png_bytep prev_row, row_buf;
2193
   png_uint_32 mins, bpp;
2194
   png_byte filter_to_do = png_ptr->do_filter;
2195
   png_size_t row_bytes = row_info->rowbytes;
2196
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2197
   int num_p_filters = (int)png_ptr->num_prev_filters;
2198
#endif
2199
2200
 
2201
2202
 
2203
  if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
2204
  {
2205
     /* These will never be selected so we need not test them. */
2206
     filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
2207
  }
2208
#endif
2209
2210
 
2211
   bpp = (row_info->pixel_depth + 7) >> 3;
2212
2213
 
2214
#endif
2215
   best_row = png_ptr->row_buf;
2216
#ifdef PNG_WRITE_FILTER_SUPPORTED
2217
   row_buf = best_row;
2218
   mins = PNG_MAXSUM;
2219
2220
 
2221
    * smallest value when summing the absolute values of the distances
2222
    * from zero, using anything >= 128 as negative numbers.  This is known
2223
    * as the "minimum sum of absolute differences" heuristic.  Other
2224
    * heuristics are the "weighted minimum sum of absolute differences"
2225
    * (experimental and can in theory improve compression), and the "zlib
2226
    * predictive" method (not implemented yet), which does test compressions
2227
    * of lines using different filter methods, and then chooses the
2228
    * (series of) filter(s) that give minimum compressed data size (VERY
2229
    * computationally expensive).
2230
    *
2231
    * GRR 980525:  consider also
2232
    *
2233
    *   (1) minimum sum of absolute differences from running average (i.e.,
2234
    *       keep running sum of non-absolute differences & count of bytes)
2235
    *       [track dispersion, too?  restart average if dispersion too large?]
2236
    *
2237
    *  (1b) minimum sum of absolute differences from sliding average, probably
2238
    *       with window size <= deflate window (usually 32K)
2239
    *
2240
    *   (2) minimum sum of squared differences from zero or running average
2241
    *       (i.e., ~ root-mean-square approach)
2242
    */
2243
2244
 
2245
 
2246
    * that has been chosen, as it doesn't actually do anything to the data.
2247
    */
2248
   if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE)
2249
   {
2250
      png_bytep rp;
2251
      png_uint_32 sum = 0;
2252
      png_size_t i;
2253
      int v;
2254
2255
 
2256
      {
2257
         v = *rp;
2258
         sum += (v < 128) ? v : 256 - v;
2259
      }
2260
2261
 
2262
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2263
      {
2264
         png_uint_32 sumhi, sumlo;
2265
         int j;
2266
         sumlo = sum & PNG_LOMASK;
2267
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
2268
2269
 
2270
         for (j = 0; j < num_p_filters; j++)
2271
         {
2272
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
2273
            {
2274
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2275
                   PNG_WEIGHT_SHIFT;
2276
2277
 
2278
                   PNG_WEIGHT_SHIFT;
2279
            }
2280
         }
2281
2282
 
2283
          * but it makes no sense to have a "cost" for the NONE filter, as
2284
          * it has the minimum possible computational cost - none).
2285
          */
2286
         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2287
             PNG_COST_SHIFT;
2288
2289
 
2290
             PNG_COST_SHIFT;
2291
2292
 
2293
            sum = PNG_MAXSUM;
2294
2295
 
2296
            sum = (sumhi << PNG_HISHIFT) + sumlo;
2297
      }
2298
#endif
2299
      mins = sum;
2300
   }
2301
2302
 
2303
   if (filter_to_do == PNG_FILTER_SUB)
2304
   /* It's the only filter so no testing is needed */
2305
   {
2306
      png_bytep rp, lp, dp;
2307
      png_size_t i;
2308
2309
 
2310
           i++, rp++, dp++)
2311
      {
2312
         *dp = *rp;
2313
      }
2314
2315
 
2316
         i++, rp++, lp++, dp++)
2317
      {
2318
         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2319
      }
2320
2321
 
2322
   }
2323
2324
 
2325
   {
2326
      png_bytep rp, dp, lp;
2327
      png_uint_32 sum = 0, lmins = mins;
2328
      png_size_t i;
2329
      int v;
2330
2331
 
2332
      /* We temporarily increase the "minimum sum" by the factor we
2333
       * would reduce the sum of this filter, so that we can do the
2334
       * early exit comparison without scaling the sum each time.
2335
       */
2336
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2337
      {
2338
         int j;
2339
         png_uint_32 lmhi, lmlo;
2340
         lmlo = lmins & PNG_LOMASK;
2341
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2342
2343
 
2344
         {
2345
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
2346
            {
2347
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2348
                   PNG_WEIGHT_SHIFT;
2349
2350
 
2351
                   PNG_WEIGHT_SHIFT;
2352
            }
2353
         }
2354
2355
 
2356
             PNG_COST_SHIFT;
2357
2358
 
2359
             PNG_COST_SHIFT;
2360
2361
 
2362
            lmins = PNG_MAXSUM;
2363
2364
 
2365
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
2366
      }
2367
#endif
2368
2369
 
2370
           i++, rp++, dp++)
2371
      {
2372
         v = *dp = *rp;
2373
2374
 
2375
      }
2376
2377
 
2378
         i++, rp++, lp++, dp++)
2379
      {
2380
         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
2381
2382
 
2383
2384
 
2385
            break;
2386
      }
2387
2388
 
2389
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2390
      {
2391
         int j;
2392
         png_uint_32 sumhi, sumlo;
2393
         sumlo = sum & PNG_LOMASK;
2394
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2395
2396
 
2397
         {
2398
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
2399
            {
2400
               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
2401
                   PNG_WEIGHT_SHIFT;
2402
2403
 
2404
                   PNG_WEIGHT_SHIFT;
2405
            }
2406
         }
2407
2408
 
2409
             PNG_COST_SHIFT;
2410
2411
 
2412
             PNG_COST_SHIFT;
2413
2414
 
2415
            sum = PNG_MAXSUM;
2416
2417
 
2418
            sum = (sumhi << PNG_HISHIFT) + sumlo;
2419
      }
2420
#endif
2421
2422
 
2423
      {
2424
         mins = sum;
2425
         best_row = png_ptr->sub_row;
2426
      }
2427
   }
2428
2429
 
2430
   if (filter_to_do == PNG_FILTER_UP)
2431
   {
2432
      png_bytep rp, dp, pp;
2433
      png_size_t i;
2434
2435
 
2436
          pp = prev_row + 1; i < row_bytes;
2437
          i++, rp++, pp++, dp++)
2438
      {
2439
         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
2440
      }
2441
2442
 
2443
   }
2444
2445
 
2446
   {
2447
      png_bytep rp, dp, pp;
2448
      png_uint_32 sum = 0, lmins = mins;
2449
      png_size_t i;
2450
      int v;
2451
2452
 
2453
 
2454
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2455
      {
2456
         int j;
2457
         png_uint_32 lmhi, lmlo;
2458
         lmlo = lmins & PNG_LOMASK;
2459
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2460
2461
 
2462
         {
2463
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
2464
            {
2465
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2466
                   PNG_WEIGHT_SHIFT;
2467
2468
 
2469
                   PNG_WEIGHT_SHIFT;
2470
            }
2471
         }
2472
2473
 
2474
             PNG_COST_SHIFT;
2475
2476
 
2477
             PNG_COST_SHIFT;
2478
2479
 
2480
            lmins = PNG_MAXSUM;
2481
2482
 
2483
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
2484
      }
2485
#endif
2486
2487
 
2488
          pp = prev_row + 1; i < row_bytes; i++)
2489
      {
2490
         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2491
2492
 
2493
2494
 
2495
            break;
2496
      }
2497
2498
 
2499
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2500
      {
2501
         int j;
2502
         png_uint_32 sumhi, sumlo;
2503
         sumlo = sum & PNG_LOMASK;
2504
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2505
2506
 
2507
         {
2508
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
2509
            {
2510
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2511
                   PNG_WEIGHT_SHIFT;
2512
2513
 
2514
                   PNG_WEIGHT_SHIFT;
2515
            }
2516
         }
2517
2518
 
2519
             PNG_COST_SHIFT;
2520
2521
 
2522
             PNG_COST_SHIFT;
2523
2524
 
2525
            sum = PNG_MAXSUM;
2526
2527
 
2528
            sum = (sumhi << PNG_HISHIFT) + sumlo;
2529
      }
2530
#endif
2531
2532
 
2533
      {
2534
         mins = sum;
2535
         best_row = png_ptr->up_row;
2536
      }
2537
   }
2538
2539
 
2540
   if (filter_to_do == PNG_FILTER_AVG)
2541
   {
2542
      png_bytep rp, dp, pp, lp;
2543
      png_uint_32 i;
2544
2545
 
2546
           pp = prev_row + 1; i < bpp; i++)
2547
      {
2548
         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2549
      }
2550
2551
 
2552
      {
2553
         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
2554
                 & 0xff);
2555
      }
2556
      best_row = png_ptr->avg_row;
2557
   }
2558
2559
 
2560
   {
2561
      png_bytep rp, dp, pp, lp;
2562
      png_uint_32 sum = 0, lmins = mins;
2563
      png_size_t i;
2564
      int v;
2565
2566
 
2567
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2568
      {
2569
         int j;
2570
         png_uint_32 lmhi, lmlo;
2571
         lmlo = lmins & PNG_LOMASK;
2572
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2573
2574
 
2575
         {
2576
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
2577
            {
2578
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2579
                   PNG_WEIGHT_SHIFT;
2580
2581
 
2582
                   PNG_WEIGHT_SHIFT;
2583
            }
2584
         }
2585
2586
 
2587
             PNG_COST_SHIFT;
2588
2589
 
2590
             PNG_COST_SHIFT;
2591
2592
 
2593
            lmins = PNG_MAXSUM;
2594
2595
 
2596
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
2597
      }
2598
#endif
2599
2600
 
2601
           pp = prev_row + 1; i < bpp; i++)
2602
      {
2603
         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2604
2605
 
2606
      }
2607
2608
 
2609
      {
2610
         v = *dp++ =
2611
             (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
2612
2613
 
2614
2615
 
2616
            break;
2617
      }
2618
2619
 
2620
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2621
      {
2622
         int j;
2623
         png_uint_32 sumhi, sumlo;
2624
         sumlo = sum & PNG_LOMASK;
2625
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2626
2627
 
2628
         {
2629
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
2630
            {
2631
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2632
                   PNG_WEIGHT_SHIFT;
2633
2634
 
2635
                   PNG_WEIGHT_SHIFT;
2636
            }
2637
         }
2638
2639
 
2640
             PNG_COST_SHIFT;
2641
2642
 
2643
             PNG_COST_SHIFT;
2644
2645
 
2646
            sum = PNG_MAXSUM;
2647
2648
 
2649
            sum = (sumhi << PNG_HISHIFT) + sumlo;
2650
      }
2651
#endif
2652
2653
 
2654
      {
2655
         mins = sum;
2656
         best_row = png_ptr->avg_row;
2657
      }
2658
   }
2659
2660
 
2661
   if (filter_to_do == PNG_FILTER_PAETH)
2662
   {
2663
      png_bytep rp, dp, pp, cp, lp;
2664
      png_size_t i;
2665
2666
 
2667
          pp = prev_row + 1; i < bpp; i++)
2668
      {
2669
         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2670
      }
2671
2672
 
2673
      {
2674
         int a, b, c, pa, pb, pc, p;
2675
2676
 
2677
         c = *cp++;
2678
         a = *lp++;
2679
2680
 
2681
         pc = a - c;
2682
2683
 
2684
         pa = abs(p);
2685
         pb = abs(pc);
2686
         pc = abs(p + pc);
2687
#else
2688
         pa = p < 0 ? -p : p;
2689
         pb = pc < 0 ? -pc : pc;
2690
         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2691
#endif
2692
2693
 
2694
2695
 
2696
      }
2697
      best_row = png_ptr->paeth_row;
2698
   }
2699
2700
 
2701
   {
2702
      png_bytep rp, dp, pp, cp, lp;
2703
      png_uint_32 sum = 0, lmins = mins;
2704
      png_size_t i;
2705
      int v;
2706
2707
 
2708
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2709
      {
2710
         int j;
2711
         png_uint_32 lmhi, lmlo;
2712
         lmlo = lmins & PNG_LOMASK;
2713
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
2714
2715
 
2716
         {
2717
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
2718
            {
2719
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2720
                   PNG_WEIGHT_SHIFT;
2721
2722
 
2723
                   PNG_WEIGHT_SHIFT;
2724
            }
2725
         }
2726
2727
 
2728
             PNG_COST_SHIFT;
2729
2730
 
2731
             PNG_COST_SHIFT;
2732
2733
 
2734
            lmins = PNG_MAXSUM;
2735
2736
 
2737
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
2738
      }
2739
#endif
2740
2741
 
2742
          pp = prev_row + 1; i < bpp; i++)
2743
      {
2744
         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2745
2746
 
2747
      }
2748
2749
 
2750
      {
2751
         int a, b, c, pa, pb, pc, p;
2752
2753
 
2754
         c = *cp++;
2755
         a = *lp++;
2756
2757
 
2758
         p = b - c;
2759
         pc = a - c;
2760
#ifdef PNG_USE_ABS
2761
         pa = abs(p);
2762
         pb = abs(pc);
2763
         pc = abs(p + pc);
2764
#else
2765
         pa = p < 0 ? -p : p;
2766
         pb = pc < 0 ? -pc : pc;
2767
         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2768
#endif
2769
         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2770
#else /* PNG_SLOW_PAETH */
2771
         p = a + b - c;
2772
         pa = abs(p - a);
2773
         pb = abs(p - b);
2774
         pc = abs(p - c);
2775
2776
 
2777
            p = a;
2778
2779
 
2780
            p = b;
2781
2782
 
2783
            p = c;
2784
#endif /* PNG_SLOW_PAETH */
2785
2786
 
2787
2788
 
2789
2790
 
2791
            break;
2792
      }
2793
2794
 
2795
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
2796
      {
2797
         int j;
2798
         png_uint_32 sumhi, sumlo;
2799
         sumlo = sum & PNG_LOMASK;
2800
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
2801
2802
 
2803
         {
2804
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
2805
            {
2806
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2807
                   PNG_WEIGHT_SHIFT;
2808
2809
 
2810
                   PNG_WEIGHT_SHIFT;
2811
            }
2812
         }
2813
2814
 
2815
             PNG_COST_SHIFT;
2816
2817
 
2818
             PNG_COST_SHIFT;
2819
2820
 
2821
            sum = PNG_MAXSUM;
2822
2823
 
2824
            sum = (sumhi << PNG_HISHIFT) + sumlo;
2825
      }
2826
#endif
2827
2828
 
2829
      {
2830
         best_row = png_ptr->paeth_row;
2831
      }
2832
   }
2833
#endif /* PNG_WRITE_FILTER_SUPPORTED */
2834
   /* Do the actual writing of the filtered row data from the chosen filter. */
2835
2836
 
2837
2838
 
2839
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2840
   /* Save the type of filter we picked this time for future calculations */
2841
   if (png_ptr->num_prev_filters > 0)
2842
   {
2843
      int j;
2844
2845
 
2846
      {
2847
         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
2848
      }
2849
2850
 
2851
   }
2852
#endif
2853
#endif /* PNG_WRITE_FILTER_SUPPORTED */
2854
}
2855
2856
 
2857
 
2858
void /* PRIVATE */
2859
png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
2860
{
2861
   png_size_t avail;
2862
2863
 
2864
2865
 
2866
   /* Set up the zlib input buffer */
2867
2868
 
2869
   png_ptr->zstream.avail_in = 0;
2870
   avail = png_ptr->row_info.rowbytes + 1;
2871
   /* Repeat until we have compressed all the data */
2872
   do
2873
   {
2874
      int ret; /* Return of zlib */
2875
2876
 
2877
       * bytes at one step, depending on the size of the zlib type 'uInt', the
2878
       * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h).
2879
       * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e.
2880
       * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a
2881
       * uInt.  ZLIB_IO_MAX can be safely reduced to cause zlib to be called
2882
       * with smaller chunks of data.
2883
       */
2884
      if (png_ptr->zstream.avail_in == 0)
2885
      {
2886
         if (avail > ZLIB_IO_MAX)
2887
         {
2888
            png_ptr->zstream.avail_in  = ZLIB_IO_MAX;
2889
            avail -= ZLIB_IO_MAX;
2890
         }
2891
2892
 
2893
         {
2894
            /* So this will fit in the available uInt space: */
2895
            png_ptr->zstream.avail_in = (uInt)avail;
2896
            avail = 0;
2897
         }
2898
      }
2899
2900
 
2901
      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
2902
2903
 
2904
      if (ret != Z_OK)
2905
      {
2906
         if (png_ptr->zstream.msg != NULL)
2907
            png_error(png_ptr, png_ptr->zstream.msg);
2908
2909
 
2910
            png_error(png_ptr, "zlib error");
2911
      }
2912
2913
 
2914
      if (!(png_ptr->zstream.avail_out))
2915
      {
2916
         /* Write the IDAT and reset the zlib output buffer */
2917
         png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
2918
         png_ptr->zstream.next_out = png_ptr->zbuf;
2919
         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
2920
      }
2921
   /* Repeat until all data has been compressed */
2922
   } while (avail > 0 || png_ptr->zstream.avail_in > 0);
2923
2924
 
2925
   if (png_ptr->prev_row != NULL)
2926
   {
2927
      png_bytep tptr;
2928
2929
 
2930
      png_ptr->prev_row = png_ptr->row_buf;
2931
      png_ptr->row_buf = tptr;
2932
   }
2933
2934
 
2935
   png_write_finish_row(png_ptr);
2936
2937
 
2938
   png_ptr->flush_rows++;
2939
2940
 
2941
       png_ptr->flush_rows >= png_ptr->flush_dist)
2942
   {
2943
      png_write_flush(png_ptr);
2944
   }
2945
#endif
2946
}
2947
#endif /* PNG_WRITE_SUPPORTED */
2948