Subversion Repositories Kolibri OS

Rev

Rev 1897 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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