pngwutil.c 87.4 KB
Newer Older
G
Guy Schalnat 已提交
1

A
Andreas Dilger 已提交
2
/* pngwutil.c - utilities to write a PNG file
3
 *
4
 * Last changed in libpng 1.6.0 [(PENDING RELEASE)]
5
 * Copyright (c) 1998-2012 Glenn Randers-Pehrson
6 7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8
 *
9
 * This code is released under the libpng license.
10
 * For conditions of distribution and use, see the disclaimer
11
 * and license in png.h
12
 */
A
Andreas Dilger 已提交
13

14
#include "pngpriv.h"
G
Guy Schalnat 已提交
15

16 17
#ifdef PNG_WRITE_SUPPORTED

18
#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
A
Andreas Dilger 已提交
19 20 21 22
/* Place a 32-bit number into a buffer in PNG byte order.  We work
 * with unsigned numbers for convenience, although one supported
 * ancillary chunk uses signed (two's complement) numbers.
 */
23
void PNGAPI
G
Guy Schalnat 已提交
24
png_save_uint_32(png_bytep buf, png_uint_32 i)
G
Guy Schalnat 已提交
25 26 27 28 29 30 31
{
   buf[0] = (png_byte)((i >> 24) & 0xff);
   buf[1] = (png_byte)((i >> 16) & 0xff);
   buf[2] = (png_byte)((i >> 8) & 0xff);
   buf[3] = (png_byte)(i & 0xff);
}

32
#ifdef PNG_SAVE_INT_32_SUPPORTED
A
Andreas Dilger 已提交
33
/* The png_save_int_32 function assumes integers are stored in two's
34
 * complement format.  If this isn't the case, then this routine needs to
G
[devel]  
Glenn Randers-Pehrson 已提交
35 36 37
 * be modified to write data in two's complement format.  Note that,
 * the following works correctly even if png_int_32 has more than 32 bits
 * (compare the more complex code required on read for sign extention.)
38
 */
39
void PNGAPI
A
Andreas Dilger 已提交
40
png_save_int_32(png_bytep buf, png_int_32 i)
G
Guy Schalnat 已提交
41 42 43 44 45 46
{
   buf[0] = (png_byte)((i >> 24) & 0xff);
   buf[1] = (png_byte)((i >> 16) & 0xff);
   buf[2] = (png_byte)((i >> 8) & 0xff);
   buf[3] = (png_byte)(i & 0xff);
}
47
#endif
G
Guy Schalnat 已提交
48

49 50 51 52
/* Place a 16-bit number into a buffer in PNG byte order.
 * The parameter is declared unsigned int, not png_uint_16,
 * just to avoid potential problems on pre-ANSI C compilers.
 */
53
void PNGAPI
54
png_save_uint_16(png_bytep buf, unsigned int i)
G
Guy Schalnat 已提交
55 56 57 58
{
   buf[0] = (png_byte)((i >> 8) & 0xff);
   buf[1] = (png_byte)(i & 0xff);
}
59
#endif
G
Guy Schalnat 已提交
60

61 62 63 64 65 66
/* Simple function to write the signature.  If we have already written
 * the magic bytes of the signature, or more likely, the PNG stream is
 * being embedded into another stream and doesn't need its own signature,
 * we should call png_set_sig_bytes() to tell libpng how many of the
 * bytes have already been written.
 */
67
void PNGAPI
68
png_write_sig(png_structrp png_ptr)
69 70
{
   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
71

72 73 74 75 76
#ifdef PNG_IO_STATE_SUPPORTED
   /* Inform the I/O callback that the signature is being written */
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
#endif

77
   /* Write the rest of the 8 byte signature */
78
   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
79
      (png_size_t)(8 - png_ptr->sig_bytes));
80

81
   if (png_ptr->sig_bytes < 3)
82 83 84
      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
}

A
Andreas Dilger 已提交
85
/* Write the start of a PNG chunk.  The type is the chunk type.
86 87 88
 * The total_length is the sum of the lengths of all the data you will be
 * passing in png_write_chunk_data().
 */
89
static void
90
png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name,
91
    png_uint_32 length)
G
Guy Schalnat 已提交
92
{
93 94
   png_byte buf[8];

95
#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
96 97 98
   PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
   png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
#endif
99 100 101 102

   if (png_ptr == NULL)
      return;

103 104 105 106 107 108 109
#ifdef PNG_IO_STATE_SUPPORTED
   /* Inform the I/O callback that the chunk header is being written.
    * PNG_IO_CHUNK_HDR requires a single I/O call.
    */
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
#endif

110
   /* Write the length and the chunk name */
A
Andreas Dilger 已提交
111
   png_save_uint_32(buf, length);
112 113
   png_save_uint_32(buf + 4, chunk_name);
   png_write_data(png_ptr, buf, 8);
114

115
   /* Put the chunk name into png_ptr->chunk_name */
116
   png_ptr->chunk_name = chunk_name;
117

118
   /* Reset the crc and run it over the chunk name */
G
Guy Schalnat 已提交
119
   png_reset_crc(png_ptr);
120

121
   png_calculate_crc(png_ptr, buf + 4, 4);
122 123 124 125 126 127 128

#ifdef PNG_IO_STATE_SUPPORTED
   /* Inform the I/O callback that chunk data will (possibly) be written.
    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
    */
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
#endif
G
Guy Schalnat 已提交
129 130
}

131
void PNGAPI
132
png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
133 134 135 136 137 138
    png_uint_32 length)
{
   png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
}

/* Write the data of a PNG chunk started with png_write_chunk_header().
139 140
 * Note that multiple calls to this function are allowed, and that the
 * sum of the lengths from these calls *must* add up to the total_length
141
 * given to png_write_chunk_header().
142
 */
143
void PNGAPI
144
png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
145
    png_size_t length)
G
Guy Schalnat 已提交
146
{
147 148 149
   /* Write the data, and run the CRC over it */
   if (png_ptr == NULL)
      return;
150

A
Andreas Dilger 已提交
151
   if (data != NULL && length > 0)
G
Guy Schalnat 已提交
152
   {
G
Guy Schalnat 已提交
153
      png_write_data(png_ptr, data, length);
154

155
      /* Update the CRC after writing the data,
156 157 158
       * in case that the user I/O routine alters it.
       */
      png_calculate_crc(png_ptr, data, length);
G
Guy Schalnat 已提交
159 160 161
   }
}

162
/* Finish a chunk started with png_write_chunk_header(). */
163
void PNGAPI
164
png_write_chunk_end(png_structrp png_ptr)
G
Guy Schalnat 已提交
165
{
A
Andreas Dilger 已提交
166 167
   png_byte buf[4];

168 169
   if (png_ptr == NULL) return;

170 171 172 173 174 175 176
#ifdef PNG_IO_STATE_SUPPORTED
   /* Inform the I/O callback that the chunk CRC is being written.
    * PNG_IO_CHUNK_CRC requires a single I/O function call.
    */
   png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
#endif

177
   /* Write the crc in a single operation */
A
Andreas Dilger 已提交
178 179
   png_save_uint_32(buf, png_ptr->crc);

180
   png_write_data(png_ptr, buf, (png_size_t)4);
G
Guy Schalnat 已提交
181 182
}

183 184 185 186 187 188 189 190 191 192
/* Write a PNG chunk all at once.  The type is an array of ASCII characters
 * representing the chunk name.  The array must be at least 4 bytes in
 * length, and does not need to be null terminated.  To be safe, pass the
 * pre-defined chunk names here, and if you need a new one, define it
 * where the others are defined.  The length is the length of the data.
 * All the data must be present.  If that is not possible, use the
 * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
 * functions instead.
 */
static void
193
png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
194 195 196 197 198 199
   png_const_bytep data, png_size_t length)
{
   if (png_ptr == NULL)
      return;

   /* On 64 bit architectures 'length' may not fit in a png_uint_32. */
200
   if (length > PNG_UINT_31_MAX)
201 202 203 204 205 206 207 208 209
      png_error(png_ptr, "length exceeds PNG maxima");

   png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
   png_write_chunk_data(png_ptr, data, length);
   png_write_chunk_end(png_ptr);
}

/* This is the API that calls the internal function above. */
void PNGAPI
210
png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
211 212 213 214 215 216
   png_const_bytep data, png_size_t length)
{
   png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
      length);
}

217 218 219 220 221 222
/* This is used below to find the size of an image to pass to png_deflate_claim,
 * so it only needs to be accurate if the size is less than 16384 bytes (the
 * point at which a lower LZ window size can be used.)
 */
static png_alloc_size_t
png_image_size(png_structrp png_ptr)
223
{
224 225 226 227 228 229
   /* Only return sizes up to the maximum of a png_uint_32, do this by limiting
    * the width and height used to 15 bits.
    */
   png_uint_32 h = png_ptr->height;

   if (png_ptr->rowbytes < 32768 && h < 32768)
230
   {
231
      if (png_ptr->interlaced)
232
      {
233 234 235 236 237 238 239
         /* Interlacing makes the image larger because of the replication of
          * both the filter byte and the padding to a byte boundary.
          */
         png_uint_32 w = png_ptr->width;
         unsigned int pd = png_ptr->pixel_depth;
         png_alloc_size_t cbBase;
         int pass;
240

241
         for (cbBase=0, pass=0; pass<=6; ++pass)
242
         {
243
            png_uint_32 pw = PNG_PASS_COLS(w, pass);
244

245 246
            if (pw > 0)
               cbBase += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);
247 248
         }

249
         return cbBase;
250 251
      }

252 253
      else
         return (png_ptr->rowbytes+1) * h;
254 255 256
   }

   else
257
      return 0xffffffffU;
258 259
}

260 261 262 263 264 265 266
#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
   /* This is the code to hack the first two bytes of the deflate stream (the
    * deflate header) to correct the windowBits value to match the actual data
    * size.  Note that the second argument is the *uncompressed* size but the
    * first argument is the *compressed* data (and it must be deflate
    * compressed.)
    */
267
static void
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
optimize_cmf(png_bytep data, png_alloc_size_t data_size)
{
   /* Optimize the CMF field in the zlib stream.  The resultant zlib stream is
    * still compliant to the stream specification.
    */
   if (data_size <= 16384) /* else windowBits must be 15 */
   {
      unsigned int z_cmf = data[0];  /* zlib compression method and flags */

      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
      {
         unsigned int z_cinfo;
         unsigned int half_z_window_size;

         z_cinfo = z_cmf >> 4;
         half_z_window_size = 1U << (z_cinfo + 7);

         if (data_size <= half_z_window_size) /* else no change */
         {
            unsigned int tmp;

            do
            {
               half_z_window_size >>= 1;
               --z_cinfo;
            }
            while (z_cinfo > 0 && data_size <= half_z_window_size);

            z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);

            data[0] = (png_byte)z_cmf;
            tmp = data[1] & 0xe0;
            tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
            data[1] = (png_byte)tmp;
         }
      }
   }
}
#else
#  define optimize_cmf(dp,dl) ((void)0)
#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */

/* Initialize the compressor for the appropriate type of compression. */
static int
png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
313
   png_alloc_size_t data_size)
314
{
315 316 317 318 319 320 321 322 323 324 325 326
   if (png_ptr->zowner != 0)
   {
      char msg[64];

      PNG_STRING_FROM_CHUNK(msg, owner);
      msg[4] = ':';
      msg[5] = ' ';
      PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner);
      /* So the message that results is "<chunk> using zstream"; this is an
       * internal error, but is very useful for debugging.  i18n requirements
       * are minimal.
       */
327
      (void)png_safecat(msg, (sizeof msg), 10, " using zstream");
328
#     if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
         png_warning(png_ptr, msg);

         /* Attempt sane error recovery */
         if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */
         {
            png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT");
            return Z_STREAM_ERROR;
         }

         png_ptr->zowner = 0;
#     else
         png_error(png_ptr, msg);
#     endif
   }

344
   {
345 346 347 348 349 350
      int level = png_ptr->zlib_level;
      int method = png_ptr->zlib_method;
      int windowBits = png_ptr->zlib_window_bits;
      int memLevel = png_ptr->zlib_mem_level;
      int strategy; /* set below */
      int ret; /* zlib return code */
351

352
      if (owner == png_IDAT)
353
      {
354 355
         if (png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)
            strategy = png_ptr->zlib_strategy;
356

357 358
         else if (png_ptr->do_filter != PNG_FILTER_NONE)
            strategy = Z_FILTERED;
359

360 361 362
         else
            strategy = Z_DEFAULT_STRATEGY;
      }
363

364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
      else
      {
#        ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
            level = png_ptr->zlib_text_level;
            method = png_ptr->zlib_text_method;
            windowBits = png_ptr->zlib_text_window_bits;
            memLevel = png_ptr->zlib_text_mem_level;
            strategy = png_ptr->zlib_text_strategy;
#        else
            /* If customization is not supported the values all come from the
             * IDAT values except for the strategy, which is fixed to the
             * default.  (This is the pre-1.6.0 behavior too, although it was
             * implemented in a very different way.)
             */
            strategy = Z_DEFAULT_STRATEGY;
#        endif
      }
381

382
      /* Adjust 'windowBits' down if larger than 'data_size'; to stop this
383 384 385 386 387
       * happening just pass 32768 as the data_size parameter.  Notice that zlib
       * requires an extra 262 bytes in the window in addition to the data to be
       * able to see the whole of the data, so if data_size+262 takes us to the
       * next windowBits size we need to fix up the value later.  (Because even
       * though deflate needs the extra window, inflate does not!)
388
       */
389
      if (data_size <= 16384)
390
      {
391 392 393 394 395 396
         /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to
          * work round a Microsoft Visual C misbehavior which, contrary to C-90,
          * widens the result of the following shift to 64-bits if (and,
          * apparently, only if) it is used in a test.
          */
         unsigned int half_window_size = 1U << (windowBits-1);
397

398
         while (data_size + 262 <= half_window_size)
399
         {
400 401
            half_window_size >>= 1;
            --windowBits;
402 403 404
         }
      }

405 406 407 408 409 410 411 412 413 414
      /* Check against the previous initialized values, if any. */
      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) &&
         (png_ptr->zlib_set_level != level ||
         png_ptr->zlib_set_method != method ||
         png_ptr->zlib_set_window_bits != windowBits ||
         png_ptr->zlib_set_mem_level != memLevel ||
         png_ptr->zlib_set_strategy != strategy))
      {
         if (deflateEnd(&png_ptr->zstream) != Z_OK)
            png_warning(png_ptr, "deflateEnd failed (ignored)");
415

416 417
         png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED;
      }
418

419 420 421 422 423 424 425 426
      /* For safety clear out the input and output pointers (currently zlib
       * doesn't use them on Init, but it might in the future).
       */
      png_ptr->zstream.next_in = NULL;
      png_ptr->zstream.avail_in = 0;
      png_ptr->zstream.next_out = NULL;
      png_ptr->zstream.avail_out = 0;

427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
      /* Now initialize if required, setting the new parameters, otherwise just
       * to a simple reset to the previous parameters.
       */
      if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
         ret = deflateReset(&png_ptr->zstream);

      else
      {
         ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
            memLevel, strategy);

         if (ret == Z_OK)
            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
      }

      /* The return code is from either deflateReset or deflateInit2; they have
       * pretty much the same set of error codes.
       */
      if (ret == Z_OK)
446
         png_ptr->zowner = owner;
447 448

      else
449
         png_zstream_error(png_ptr, ret);
450

451
      return ret;
452 453 454
   }
}

455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
/* Clean up (or trim) a linked list of compression buffers. */
void /* PRIVATE */
png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)
{
   png_compression_bufferp list = *listp;

   if (list != NULL)
   {
      *listp = NULL;

      do
      {
         png_compression_bufferp next = list->next;

         png_free(png_ptr, list);
         list = next;
      }
      while (list != NULL);
   }
}

476
#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
477
/* This pair of functions encapsulates the operation of (a) compressing a
478 479
 * text string, and (b) issuing it later as a series of chunk data writes.
 * The compression_state structure is shared context for these functions
480 481 482 483 484 485
 * set up by the caller to allow access to the relevant local variables.
 *
 * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size
 * temporary buffers.  From 1.6.0 it is retained in png_struct so that it will
 * be correctly freed in the event of a write error (previous implementations
 * just leaked memory.)
486 487 488
 */
typedef struct
{
489 490 491 492
   png_const_bytep      input;        /* The uncompressed input data */
   png_alloc_size_t     input_len;    /* Its length */
   png_uint_32          output_len;   /* Final compressed length */
   png_byte             output[1024]; /* First block of output */
493 494
} compression_state;

495 496 497
static void
png_text_compress_init(compression_state *comp, png_const_bytep input,
   png_alloc_size_t input_len)
498
{
499 500 501 502
   comp->input = input;
   comp->input_len = input_len;
   comp->output_len = 0;
}
503

504 505 506 507 508 509 510 511 512 513 514
/* Compress the data in the compression state input */
static int
png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
   compression_state *comp, png_uint_32 prefix_len)
{
   int ret;

   /* To find the length of the output it is necessary to first compress the
    * input, the result is buffered rather than using the two-pass algorithm
    * that is used on the inflate side; deflate is assumed to be slower and a
    * PNG writer is assumed to have more memory available than a PNG reader.
515
    *
516 517 518 519
    * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an
    * upper limit on the output size, but it is always bigger than the input
    * size so it is likely to be more efficient to use this linked-list
    * approach.
520
    */
521
   ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len);
522

523 524
   if (ret != Z_OK)
      return ret;
525

526 527 528 529 530 531
   /* Set up the compression buffers, we need a loop here to avoid overflowing a
    * uInt.  Use ZLIB_IO_MAX to limit the input.  The output is always limited
    * by the output buffer size, so there is no need to check that.  Since this
    * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits
    * in size.
    */
532
   {
533 534 535
      png_compression_bufferp *end = &png_ptr->zbuffer_list;
      png_alloc_size_t input_len = comp->input_len; /* may be zero! */
      png_uint_32 output_len;
536

537 538 539 540
      /* zlib updates these for us: */
      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input);
      png_ptr->zstream.avail_in = 0; /* Set below */
      png_ptr->zstream.next_out = comp->output;
541
      png_ptr->zstream.avail_out = (sizeof comp->output);
542

543
      output_len = png_ptr->zstream.avail_out;
544

545
      do
546
      {
547
         uInt avail_in = ZLIB_IO_MAX;
548

549 550
         if (avail_in > input_len)
            avail_in = (uInt)input_len;
551

552
         input_len -= avail_in;
553

554
         png_ptr->zstream.avail_in = avail_in;
555

556 557 558
         if (png_ptr->zstream.avail_out == 0)
         {
            png_compression_buffer *next;
559

560 561 562 563 564 565 566
            /* Chunk data is limited to 2^31 bytes in length, so the prefix
             * length must be counted here.
             */
            if (output_len + prefix_len > PNG_UINT_31_MAX)
            {
               ret = Z_MEM_ERROR;
               break;
567 568
            }

569 570 571 572 573
            /* Need a new (malloc'ed) buffer, but there may be one present
             * already.
             */
            next = *end;
            if (next == NULL)
574
            {
575 576
               next = png_voidcast(png_compression_bufferp, png_malloc_base
                  (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
577

578
               if (next == NULL)
579
               {
580 581
                  ret = Z_MEM_ERROR;
                  break;
582
               }
583

584 585 586
               /* Link in this buffer (so that it will be freed later) */
               next->next = NULL;
               *end = next;
587 588
            }

589 590 591
            png_ptr->zstream.next_out = next->output;
            png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
            output_len += png_ptr->zstream.avail_out;
592

593 594 595
            /* Move 'end' to the next buffer pointer. */
            end = &next->next;
         }
596

597 598 599
         /* Compress the data */
         ret = deflate(&png_ptr->zstream,
            input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
600

601 602 603 604 605
         /* Claw back input data that was not consumed (because avail_in is
          * reset above every time round the loop).
          */
         input_len += png_ptr->zstream.avail_in;
         png_ptr->zstream.avail_in = 0; /* safety */
606
      }
607
      while (ret == Z_OK);
608

609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
      /* There may be some space left in the last output buffer, this needs to
       * be subtracted from output_len.
       */
      output_len -= png_ptr->zstream.avail_out;
      png_ptr->zstream.avail_out = 0; /* safety */
      comp->output_len = output_len;

      /* Now double check the output length, put in a custom message if it is
       * too long.  Otherwise ensure the z_stream::msg pointer is set to
       * something.
       */
      if (output_len + prefix_len >= PNG_UINT_31_MAX)
      {
         png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long");
         ret = Z_MEM_ERROR;
624 625
      }

626 627
      else
         png_zstream_error(png_ptr, ret);
628

629 630 631 632 633 634 635 636 637 638
      /* Reset zlib for another zTXt/iTXt or image data */
      png_ptr->zowner = 0;

      /* The only success case is Z_STREAM_END, input_len must be 0, if not this
       * is an internal error.
       */
      if (ret == Z_STREAM_END && input_len == 0)
      {
         /* Fix up the deflate header, if required */
         optimize_cmf(comp->output, comp->input_len);
639

640 641 642 643 644 645 646 647 648 649
         /* But Z_OK is returned, not Z_STREAM_END; this allows the claim
          * function above to return Z_STREAM_END on an error (though it never
          * does in the current versions of zlib.)
          */
         return Z_OK;
      }

      else
         return ret;
   }
650 651
}

652
/* Ship the compressed text out via chunk writes */
653
static void
654
png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
655
{
656 657
   png_uint_32 output_len = comp->output_len;
   png_const_bytep output = comp->output;
658
   png_uint_32 avail = (sizeof comp->output);
659
   png_compression_buffer *next = png_ptr->zbuffer_list;
660

661
   for (;;)
662
   {
663 664
      if (avail > output_len)
         avail = output_len;
665

666
      png_write_chunk_data(png_ptr, output, avail);
667

668
      output_len -= avail;
669

670 671
      if (output_len == 0 || next == NULL)
         break;
672

673 674 675 676
      avail = png_ptr->zbuffer_size;
      output = next->output;
      next = next->next;
   }
677

678 679 680 681 682
   /* This is an internal error; 'next' must have been NULL! */
   if (output_len > 0)
      png_error(png_ptr, "error writing ancilliary chunked compressed data");
}
#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
683

684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702
#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
 * and if invalid, correct the keyword rather than discarding the entire
 * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
 * length, forbids leading or trailing whitespace, multiple internal spaces,
 * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
 *
 * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
 * trailing '\0').  If this routine returns 0 then there was no keyword, or a
 * valid one could not be generated, and the caller must png_error.
 */
static png_uint_32
png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
{
   png_const_charp orig_key = key;
   png_uint_32 key_len = 0;
   int bad_character = 0;
   int space = 1;
703

704
   png_debug(1, "in png_check_keyword");
705

706 707 708 709 710 711 712 713 714
   if (key == NULL)
   {
      *new_key = 0;
      return 0;
   }
   
   while (*key && key_len < 79)
   {
      png_byte ch = (png_byte)(0xff & *key++);
715

716 717
      if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
         *new_key++ = ch, ++key_len, space = 0;
718

719 720 721 722 723 724
      else if (!space)
      {
         /* A space or an invalid character when one wasn't seen immediately
          * before; output just a space.
          */
         *new_key++ = 32, ++key_len, space = 1;
725

726
         /* If the character was not a space then it is invalid. */
727 728
         if (ch != 32)
            bad_character = ch;
729 730
      }

731 732
      else if (!bad_character)
         bad_character = ch; /* just skip it, record the first error */
733 734
   }

735
   if (key_len > 0 && space) /* trailing space */
736
   {
737 738 739
      --key_len, --new_key;
      if (!bad_character)
         bad_character = 32;
740
   }
741

742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
   /* Terminate the keyword */
   *new_key = 0;

   if (key_len == 0)
      return 0;

   /* Try to only output one warning per keyword: */
   if (*key) /* keyword too long */
      png_warning(png_ptr, "keyword truncated");

   else if (bad_character)
   {
      PNG_WARNING_PARAMETERS(p)

      png_warning_parameter(p, 1, orig_key);
      png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
758

759 760
      png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
   }
761

762
   return key_len;
763
}
764
#endif
765

G
Guy Schalnat 已提交
766
/* Write the IHDR chunk, and update the png_struct with the necessary
767 768 769
 * information.  Note that the rest of this code depends upon this
 * information being correct.
 */
770
void /* PRIVATE */
771
png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
772 773
    int bit_depth, int color_type, int compression_type, int filter_type,
    int interlace_type)
G
Guy Schalnat 已提交
774
{
775
   png_byte buf[13]; /* Buffer to store the IHDR info */
G
Guy Schalnat 已提交
776

777
   png_debug(1, "in png_write_IHDR");
778

G
Guy Schalnat 已提交
779
   /* Check that we have valid input data from the application info */
G
Guy Schalnat 已提交
780 781
   switch (color_type)
   {
A
Andreas Dilger 已提交
782
      case PNG_COLOR_TYPE_GRAY:
G
Guy Schalnat 已提交
783 784 785 786 787 788
         switch (bit_depth)
         {
            case 1:
            case 2:
            case 4:
            case 8:
789
#ifdef PNG_WRITE_16BIT_SUPPORTED
790
            case 16:
791
#endif
792
               png_ptr->channels = 1; break;
793

794 795 796
            default:
               png_error(png_ptr,
                   "Invalid bit depth for grayscale image");
G
Guy Schalnat 已提交
797
         }
G
Guy Schalnat 已提交
798
         break;
799

A
Andreas Dilger 已提交
800
      case PNG_COLOR_TYPE_RGB:
801
#ifdef PNG_WRITE_16BIT_SUPPORTED
G
Guy Schalnat 已提交
802
         if (bit_depth != 8 && bit_depth != 16)
803 804 805
#else
         if (bit_depth != 8)
#endif
G
Guy Schalnat 已提交
806
            png_error(png_ptr, "Invalid bit depth for RGB image");
807

G
Guy Schalnat 已提交
808 809
         png_ptr->channels = 3;
         break;
810

A
Andreas Dilger 已提交
811
      case PNG_COLOR_TYPE_PALETTE:
G
Guy Schalnat 已提交
812 813 814 815 816
         switch (bit_depth)
         {
            case 1:
            case 2:
            case 4:
817 818 819
            case 8:
               png_ptr->channels = 1;
               break;
820

821 822
            default:
               png_error(png_ptr, "Invalid bit depth for paletted image");
G
Guy Schalnat 已提交
823 824
         }
         break;
825

A
Andreas Dilger 已提交
826
      case PNG_COLOR_TYPE_GRAY_ALPHA:
G
Guy Schalnat 已提交
827 828
         if (bit_depth != 8 && bit_depth != 16)
            png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
829

G
Guy Schalnat 已提交
830 831
         png_ptr->channels = 2;
         break;
832

A
Andreas Dilger 已提交
833
      case PNG_COLOR_TYPE_RGB_ALPHA:
834
#ifdef PNG_WRITE_16BIT_SUPPORTED
G
Guy Schalnat 已提交
835
         if (bit_depth != 8 && bit_depth != 16)
836 837 838
#else
         if (bit_depth != 8)
#endif
G
Guy Schalnat 已提交
839
            png_error(png_ptr, "Invalid bit depth for RGBA image");
840

G
Guy Schalnat 已提交
841 842
         png_ptr->channels = 4;
         break;
843

G
Guy Schalnat 已提交
844 845 846 847
      default:
         png_error(png_ptr, "Invalid image color type specified");
   }

A
Andreas Dilger 已提交
848
   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
G
Guy Schalnat 已提交
849 850
   {
      png_warning(png_ptr, "Invalid compression type specified");
A
Andreas Dilger 已提交
851
      compression_type = PNG_COMPRESSION_TYPE_BASE;
G
Guy Schalnat 已提交
852 853
   }

854 855 856 857 858 859 860 861 862
   /* Write filter_method 64 (intrapixel differencing) only if
    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
    * 2. Libpng did not write a PNG signature (this filter_method is only
    *    used in PNG datastreams that are embedded in MNG datastreams) and
    * 3. The application called png_permit_mng_features with a mask that
    *    included PNG_FLAG_MNG_FILTER_64 and
    * 4. The filter_method is 64 and
    * 5. The color_type is RGB or RGBA
    */
863
   if (
864
#ifdef PNG_MNG_FEATURES_SUPPORTED
865 866 867 868 869
       !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
       ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
       (color_type == PNG_COLOR_TYPE_RGB ||
        color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
       (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
870
#endif
871
       filter_type != PNG_FILTER_TYPE_BASE)
G
Guy Schalnat 已提交
872 873
   {
      png_warning(png_ptr, "Invalid filter type specified");
A
Andreas Dilger 已提交
874
      filter_type = PNG_FILTER_TYPE_BASE;
G
Guy Schalnat 已提交
875 876
   }

877
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
A
Andreas Dilger 已提交
878
   if (interlace_type != PNG_INTERLACE_NONE &&
879
       interlace_type != PNG_INTERLACE_ADAM7)
G
Guy Schalnat 已提交
880 881
   {
      png_warning(png_ptr, "Invalid interlace type specified");
A
Andreas Dilger 已提交
882
      interlace_type = PNG_INTERLACE_ADAM7;
G
Guy Schalnat 已提交
883
   }
884 885 886
#else
   interlace_type=PNG_INTERLACE_NONE;
#endif
G
Guy Schalnat 已提交
887

888
   /* Save the relevent information */
G
Guy Schalnat 已提交
889 890 891
   png_ptr->bit_depth = (png_byte)bit_depth;
   png_ptr->color_type = (png_byte)color_type;
   png_ptr->interlaced = (png_byte)interlace_type;
892
#ifdef PNG_MNG_FEATURES_SUPPORTED
893
   png_ptr->filter_type = (png_byte)filter_type;
894
#endif
895
   png_ptr->compression_type = (png_byte)compression_type;
G
Guy Schalnat 已提交
896 897 898
   png_ptr->width = width;
   png_ptr->height = height;

G
Guy Schalnat 已提交
899
   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
900
   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
901
   /* Set the usr info, so any transformations can modify it */
G
Guy Schalnat 已提交
902 903
   png_ptr->usr_width = png_ptr->width;
   png_ptr->usr_bit_depth = png_ptr->bit_depth;
G
Guy Schalnat 已提交
904 905
   png_ptr->usr_channels = png_ptr->channels;

906
   /* Pack the header information into the buffer */
G
Guy Schalnat 已提交
907 908 909 910 911 912 913
   png_save_uint_32(buf, width);
   png_save_uint_32(buf + 4, height);
   buf[8] = (png_byte)bit_depth;
   buf[9] = (png_byte)color_type;
   buf[10] = (png_byte)compression_type;
   buf[11] = (png_byte)filter_type;
   buf[12] = (png_byte)interlace_type;
G
Guy Schalnat 已提交
914

915
   /* Write the chunk */
916
   png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
G
Guy Schalnat 已提交
917

G
Guy Schalnat 已提交
918
   if (!(png_ptr->do_filter))
G
Guy Schalnat 已提交
919
   {
A
Andreas Dilger 已提交
920
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
921
          png_ptr->bit_depth < 8)
G
Guy Schalnat 已提交
922
         png_ptr->do_filter = PNG_FILTER_NONE;
923

G
Guy Schalnat 已提交
924
      else
G
Guy Schalnat 已提交
925
         png_ptr->do_filter = PNG_ALL_FILTERS;
G
Guy Schalnat 已提交
926
   }
927

928
   png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
G
Guy Schalnat 已提交
929 930
}

931
/* Write the palette.  We are careful not to trust png_color to be in the
932
 * correct order for PNG, so people can redefine it to any convenient
933 934
 * structure.
 */
935
void /* PRIVATE */
936
png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
937
    png_uint_32 num_pal)
G
Guy Schalnat 已提交
938
{
A
Andreas Dilger 已提交
939
   png_uint_32 i;
940
   png_const_colorp pal_ptr;
G
Guy Schalnat 已提交
941 942
   png_byte buf[3];

943
   png_debug(1, "in png_write_PLTE");
944

945
   if ((
946
#ifdef PNG_MNG_FEATURES_SUPPORTED
947
       !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
948
#endif
949
       num_pal == 0) || num_pal > 256)
950
   {
951 952 953 954
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      {
         png_error(png_ptr, "Invalid number of colors in palette");
      }
955

956 957 958 959 960
      else
      {
         png_warning(png_ptr, "Invalid number of colors in palette");
         return;
      }
961 962 963 964 965
   }

   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
   {
      png_warning(png_ptr,
966
          "Ignoring request to write a PLTE chunk in grayscale PNG");
967

968
      return;
G
Guy Schalnat 已提交
969 970
   }

A
Andreas Dilger 已提交
971
   png_ptr->num_palette = (png_uint_16)num_pal;
972
   png_debug1(3, "num_palette = %d", png_ptr->num_palette);
G
Guy Schalnat 已提交
973

974
   png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
975
#ifdef PNG_POINTER_INDEXING_SUPPORTED
976

A
Andreas Dilger 已提交
977
   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
G
Guy Schalnat 已提交
978 979 980 981
   {
      buf[0] = pal_ptr->red;
      buf[1] = pal_ptr->green;
      buf[2] = pal_ptr->blue;
982
      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
G
Guy Schalnat 已提交
983
   }
984

985
#else
986 987 988
   /* This is a little slower but some buggy compilers need to do this
    * instead
    */
989
   pal_ptr=palette;
990

991 992 993 994 995
   for (i = 0; i < num_pal; i++)
   {
      buf[0] = pal_ptr[i].red;
      buf[1] = pal_ptr[i].green;
      buf[2] = pal_ptr[i].blue;
996
      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
997
   }
998

999
#endif
G
Guy Schalnat 已提交
1000
   png_write_chunk_end(png_ptr);
G
Guy Schalnat 已提交
1001
   png_ptr->mode |= PNG_HAVE_PLTE;
G
Guy Schalnat 已提交
1002 1003
}

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
/* This is similar to png_text_compress, above, except that it does not require
 * all of the data at once and, instead of buffering the compressed result,
 * writes it as IDAT chunks.  Unlike png_text_compress it *can* png_error out
 * because it calls the write interface.  As a result it does its own error
 * reporting and does not return an error code.  In the event of error it will
 * just call png_error.  The input data length may exceed 32-bits.  The 'flush'
 * parameter is exactly the same as that to deflate, with the following
 * meanings:
 *
 * Z_NO_FLUSH: normal incremental output of compressed data
 * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush
 * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up
 *
 * The routine manages the acquire and release of the png_ptr->zstream by
 * checking and (at the end) clearing png_ptr->zowner, it does some sanity
 * checks on the 'mode' flags while doing this.
 */
1021
void /* PRIVATE */
1022 1023
png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
   png_alloc_size_t input_len, int flush)
G
Guy Schalnat 已提交
1024
{
1025 1026 1027 1028
   if (png_ptr->zowner != png_IDAT)
   {
      /* First time.   Ensure we have a temporary buffer for compression and
       * trim the buffer list if it has more than one entry to free memory.
1029 1030
       * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been
       * created at this point, but the check here is quick and safe.
1031 1032 1033 1034 1035 1036 1037
       */
      if (png_ptr->zbuffer_list == NULL)
      {
         png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
            png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
         png_ptr->zbuffer_list->next = NULL;
      }
1038

1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
      else
         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next);

      /* It is a terminal error if we can't claim the zstream. */
      if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK)
         png_error(png_ptr, png_ptr->zstream.msg);

      /* The output state is maintained in png_ptr->zstream, so it must be
       * initialized here after the claim.
       */
      png_ptr->zstream.next_out = png_ptr->zbuffer_list->output;
      png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
   }

   /* Now loop reading and writing until all the input is consumed or an error
    * terminates the operation.  The _out values are maintained across calls to
    * this function, but the input must be reset each time.
    */
   png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
   png_ptr->zstream.avail_in = 0; /* set below */
   for (;;)
1060
   {
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
      int ret;

      /* INPUT: from the row data */
      uInt avail = ZLIB_IO_MAX;

      if (avail > input_len)
         avail = (uInt)input_len; /* safe because of the check */

      png_ptr->zstream.avail_in = avail;
      input_len -= avail;

      ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush);

      /* Include as-yet unconsumed input */
      input_len += png_ptr->zstream.avail_in;
      png_ptr->zstream.avail_in = 0;

      /* OUTPUT: write complete IDAT chunks when avail_out drops to zero, note
       * that these two zstream fields are preserved across the calls, therefore
       * there is no need to set these up on entry to the loop.
1081
       */
1082 1083 1084 1085
      if (png_ptr->zstream.avail_out == 0)
      {
         png_bytep data = png_ptr->zbuffer_list->output;
         uInt size = png_ptr->zbuffer_size;
1086

1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
         /* Write an IDAT containing the data then reset the buffer.  The
          * first IDAT may need deflate header optimization.
          */
#        ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
            if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
               png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
               optimize_cmf(data, png_image_size(png_ptr));
#        endif

         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
         png_ptr->mode |= PNG_HAVE_IDAT;

         png_ptr->zstream.next_out = data;
         png_ptr->zstream.avail_out = size;

         /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with
          * the same flush parameter until it has finished output, for NO_FLUSH
          * it doesn't matter.
          */
         if (ret == Z_OK && flush != Z_NO_FLUSH)
            continue;
      }

      /* The order of these checks doesn't matter much; it just effect which
       * possible error might be detected if multiple things go wrong at once.
       */
      if (ret == Z_OK) /* most likely return code! */
1114
      {
1115 1116 1117
         /* If all the input has been consumed then just return.  If Z_FINISH
          * was used as the flush parameter something has gone wrong if we get
          * here.
1118
          */
1119
         if (input_len == 0)
1120
         {
1121 1122
            if (flush == Z_FINISH)
               png_error(png_ptr, "Z_OK on Z_FINISH with output space");
1123

1124 1125 1126
            return;
         }
      }
1127

1128 1129 1130 1131 1132 1133 1134
      else if (ret == Z_STREAM_END && flush == Z_FINISH)
      {
         /* This is the end of the IDAT data; any pending output must be
          * flushed.  For small PNG files we may still be at the beginning.
          */
         png_bytep data = png_ptr->zbuffer_list->output;
         uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out;
1135

1136 1137 1138 1139 1140
#        ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
            if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
               png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
               optimize_cmf(data, png_image_size(png_ptr));
#        endif
1141

1142 1143 1144 1145
         png_write_complete_chunk(png_ptr, png_IDAT, data, size);
         png_ptr->zstream.avail_out = 0;
         png_ptr->zstream.next_out = NULL;
         png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
1146

1147 1148
         png_ptr->zowner = 0; /* Release the stream */
         return;
1149
      }
1150

1151
      else
1152 1153 1154 1155 1156
      {
         /* This is an error condition. */
         png_zstream_error(png_ptr, ret);
         png_error(png_ptr, png_ptr->zstream.msg);
      }
1157
   }
G
Guy Schalnat 已提交
1158 1159
}

1160
/* Write an IEND chunk */
1161
void /* PRIVATE */
1162
png_write_IEND(png_structrp png_ptr)
G
Guy Schalnat 已提交
1163
{
1164
   png_debug(1, "in png_write_IEND");
1165

1166
   png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
A
Andreas Dilger 已提交
1167
   png_ptr->mode |= PNG_HAVE_IEND;
G
Guy Schalnat 已提交
1168 1169
}

1170
#ifdef PNG_WRITE_gAMA_SUPPORTED
1171
/* Write a gAMA chunk */
1172
void /* PRIVATE */
1173
png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
1174 1175 1176
{
   png_byte buf[4];

1177
   png_debug(1, "in png_write_gAMA");
1178

1179
   /* file_gamma is saved in 1/100,000ths */
1180
   png_save_uint_32(buf, (png_uint_32)file_gamma);
1181
   png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
1182 1183
}
#endif
G
Guy Schalnat 已提交
1184

1185
#ifdef PNG_WRITE_sRGB_SUPPORTED
1186
/* Write a sRGB chunk */
1187
void /* PRIVATE */
1188
png_write_sRGB(png_structrp png_ptr, int srgb_intent)
1189 1190 1191
{
   png_byte buf[1];

1192
   png_debug(1, "in png_write_sRGB");
1193

1194
   if (srgb_intent >= PNG_sRGB_INTENT_LAST)
1195 1196
      png_warning(png_ptr,
          "Invalid sRGB rendering intent specified");
1197

1198
   buf[0]=(png_byte)srgb_intent;
1199
   png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
1200 1201 1202
}
#endif

1203
#ifdef PNG_WRITE_iCCP_SUPPORTED
1204
/* Write an iCCP chunk */
1205
void /* PRIVATE */
1206 1207
png_write_iCCP(png_structrp png_ptr, png_const_charp name,
    png_const_bytep profile)
1208
{
1209
   png_uint_32 name_len;
1210
   png_uint_32 profile_len;
1211
   png_byte new_name[81]; /* 1 byte for the compression byte */
1212 1213
   compression_state comp;

1214
   png_debug(1, "in png_write_iCCP");
1215

1216 1217 1218
   /* These are all internal problems: the profile should have been checked
    * before when it was stored.
    */
1219
   if (profile == NULL)
1220 1221 1222
      png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */

   profile_len = png_get_uint_32(profile);
1223

1224 1225
   if (profile_len < 132)
      png_error(png_ptr, "ICC profile too short");
1226

1227
   if (profile_len & 0x03)
1228
      png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
1229

1230
   {
1231
      png_uint_32 embedded_profile_len = png_get_uint_32(profile);
1232

1233 1234 1235
      if (profile_len != embedded_profile_len)
         png_error(png_ptr, "Profile length does not match profile");
   }
1236

1237
   name_len = png_check_keyword(png_ptr, name, new_name);
1238

1239 1240
   if (name_len == 0)
      png_error(png_ptr, "iCCP: invalid keyword");
1241

1242
   new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE;
1243

1244 1245
   /* Make sure we include the NULL after the name and the compression type */
   ++name_len;
1246

1247
   png_text_compress_init(&comp, profile, profile_len);
1248

1249 1250 1251
   /* Allow for keyword terminator and compression byte */
   if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK)
      png_error(png_ptr, png_ptr->zstream.msg);
1252

1253
   png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len);
1254

1255
   png_write_chunk_data(png_ptr, new_name, name_len);
1256

1257
   png_write_compressed_data_out(png_ptr, &comp);
1258 1259 1260 1261 1262

   png_write_chunk_end(png_ptr);
}
#endif

1263
#ifdef PNG_WRITE_sPLT_SUPPORTED
1264
/* Write a sPLT chunk */
1265
void /* PRIVATE */
1266
png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
1267
{
1268 1269
   png_uint_32 name_len;
   png_byte new_name[80];
1270
   png_byte entrybuf[10];
1271 1272
   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
   png_size_t palette_size = entry_size * spalette->nentries;
1273
   png_sPLT_entryp ep;
1274
#ifndef PNG_POINTER_INDEXING_SUPPORTED
1275 1276
   int i;
#endif
1277

1278
   png_debug(1, "in png_write_sPLT");
1279

1280 1281 1282 1283
   name_len = png_check_keyword(png_ptr, spalette->name, new_name);

   if (name_len == 0)
      png_error(png_ptr, "sPLT: invalid keyword");
1284

1285
   /* Make sure we include the NULL after the name */
1286
   png_write_chunk_header(png_ptr, png_sPLT,
1287
       (png_uint_32)(name_len + 2 + palette_size));
1288

1289
   png_write_chunk_data(png_ptr, (png_bytep)new_name,
1290
       (png_size_t)(name_len + 1));
1291

1292
   png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
1293

1294
   /* Loop through each palette entry, writing appropriately */
1295
#ifdef PNG_POINTER_INDEXING_SUPPORTED
1296
   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
1297
   {
1298 1299
      if (spalette->depth == 8)
      {
1300 1301 1302 1303 1304
         entrybuf[0] = (png_byte)ep->red;
         entrybuf[1] = (png_byte)ep->green;
         entrybuf[2] = (png_byte)ep->blue;
         entrybuf[3] = (png_byte)ep->alpha;
         png_save_uint_16(entrybuf + 4, ep->frequency);
1305
      }
1306

1307 1308
      else
      {
1309 1310 1311 1312 1313
         png_save_uint_16(entrybuf + 0, ep->red);
         png_save_uint_16(entrybuf + 2, ep->green);
         png_save_uint_16(entrybuf + 4, ep->blue);
         png_save_uint_16(entrybuf + 6, ep->alpha);
         png_save_uint_16(entrybuf + 8, ep->frequency);
1314
      }
1315

1316
      png_write_chunk_data(png_ptr, entrybuf, entry_size);
1317
   }
1318 1319
#else
   ep=spalette->entries;
1320
   for (i = 0; i>spalette->nentries; i++)
1321
   {
1322 1323
      if (spalette->depth == 8)
      {
1324 1325 1326 1327 1328
         entrybuf[0] = (png_byte)ep[i].red;
         entrybuf[1] = (png_byte)ep[i].green;
         entrybuf[2] = (png_byte)ep[i].blue;
         entrybuf[3] = (png_byte)ep[i].alpha;
         png_save_uint_16(entrybuf + 4, ep[i].frequency);
1329
      }
1330

1331 1332
      else
      {
1333 1334 1335 1336 1337
         png_save_uint_16(entrybuf + 0, ep[i].red);
         png_save_uint_16(entrybuf + 2, ep[i].green);
         png_save_uint_16(entrybuf + 4, ep[i].blue);
         png_save_uint_16(entrybuf + 6, ep[i].alpha);
         png_save_uint_16(entrybuf + 8, ep[i].frequency);
1338
      }
1339

1340
      png_write_chunk_data(png_ptr, entrybuf, entry_size);
1341 1342
   }
#endif
1343 1344 1345 1346 1347

   png_write_chunk_end(png_ptr);
}
#endif

1348
#ifdef PNG_WRITE_sBIT_SUPPORTED
1349
/* Write the sBIT chunk */
1350
void /* PRIVATE */
1351
png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
G
Guy Schalnat 已提交
1352 1353
{
   png_byte buf[4];
A
Andreas Dilger 已提交
1354
   png_size_t size;
G
Guy Schalnat 已提交
1355

1356
   png_debug(1, "in png_write_sBIT");
1357

1358
   /* Make sure we don't depend upon the order of PNG_COLOR_8 */
G
Guy Schalnat 已提交
1359 1360
   if (color_type & PNG_COLOR_MASK_COLOR)
   {
1361
      png_byte maxbits;
G
Guy Schalnat 已提交
1362

1363
      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
1364
          png_ptr->usr_bit_depth);
1365

1366 1367
      if (sbit->red == 0 || sbit->red > maxbits ||
          sbit->green == 0 || sbit->green > maxbits ||
G
Guy Schalnat 已提交
1368 1369 1370 1371 1372
          sbit->blue == 0 || sbit->blue > maxbits)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1373

G
Guy Schalnat 已提交
1374 1375 1376 1377 1378
      buf[0] = sbit->red;
      buf[1] = sbit->green;
      buf[2] = sbit->blue;
      size = 3;
   }
1379

G
Guy Schalnat 已提交
1380 1381
   else
   {
G
Guy Schalnat 已提交
1382 1383 1384 1385 1386
      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1387

G
Guy Schalnat 已提交
1388 1389 1390 1391 1392 1393
      buf[0] = sbit->gray;
      size = 1;
   }

   if (color_type & PNG_COLOR_MASK_ALPHA)
   {
G
Guy Schalnat 已提交
1394 1395 1396 1397 1398
      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1399

G
Guy Schalnat 已提交
1400 1401 1402
      buf[size++] = sbit->alpha;
   }

1403
   png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
G
Guy Schalnat 已提交
1404
}
G
Guy Schalnat 已提交
1405
#endif
G
Guy Schalnat 已提交
1406

1407
#ifdef PNG_WRITE_cHRM_SUPPORTED
1408
/* Write the cHRM chunk */
1409
void /* PRIVATE */
1410
png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)
1411 1412 1413
{
   png_byte buf[32];

1414
   png_debug(1, "in png_write_cHRM");
1415

1416
   /* Each value is saved in 1/100,000ths */
1417 1418
   png_save_int_32(buf,      xy->whitex);
   png_save_int_32(buf +  4, xy->whitey);
1419

1420 1421
   png_save_int_32(buf +  8, xy->redx);
   png_save_int_32(buf + 12, xy->redy);
1422

1423 1424
   png_save_int_32(buf + 16, xy->greenx);
   png_save_int_32(buf + 20, xy->greeny);
1425

1426 1427
   png_save_int_32(buf + 24, xy->bluex);
   png_save_int_32(buf + 28, xy->bluey);
1428

1429
   png_write_complete_chunk(png_ptr, png_cHRM, buf, 32);
1430 1431
}
#endif
G
Guy Schalnat 已提交
1432

1433
#ifdef PNG_WRITE_tRNS_SUPPORTED
1434
/* Write the tRNS chunk */
1435
void /* PRIVATE */
1436
png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
1437
    png_const_color_16p tran, int num_trans, int color_type)
G
Guy Schalnat 已提交
1438 1439 1440
{
   png_byte buf[6];

1441
   png_debug(1, "in png_write_tRNS");
1442

G
Guy Schalnat 已提交
1443 1444
   if (color_type == PNG_COLOR_TYPE_PALETTE)
   {
1445
      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
G
Guy Schalnat 已提交
1446
      {
1447
         png_warning(png_ptr, "Invalid number of transparent colors specified");
G
Guy Schalnat 已提交
1448 1449
         return;
      }
1450

1451
      /* Write the chunk out as it is */
1452
      png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans);
G
Guy Schalnat 已提交
1453
   }
1454

G
Guy Schalnat 已提交
1455 1456
   else if (color_type == PNG_COLOR_TYPE_GRAY)
   {
1457
      /* One 16 bit value */
1458
      if (tran->gray >= (1 << png_ptr->bit_depth))
1459 1460
      {
         png_warning(png_ptr,
1461
             "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
1462

1463 1464
         return;
      }
1465

G
Guy Schalnat 已提交
1466
      png_save_uint_16(buf, tran->gray);
1467
      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1468
   }
1469

G
Guy Schalnat 已提交
1470 1471
   else if (color_type == PNG_COLOR_TYPE_RGB)
   {
1472
      /* Three 16 bit values */
G
Guy Schalnat 已提交
1473 1474 1475
      png_save_uint_16(buf, tran->red);
      png_save_uint_16(buf + 2, tran->green);
      png_save_uint_16(buf + 4, tran->blue);
1476
#ifdef PNG_WRITE_16BIT_SUPPORTED
1477
      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1478 1479 1480
#else
      if (buf[0] | buf[2] | buf[4])
#endif
1481 1482
      {
         png_warning(png_ptr,
1483
           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
1484 1485
         return;
      }
1486

1487
      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
G
Guy Schalnat 已提交
1488
   }
1489

G
Guy Schalnat 已提交
1490 1491
   else
   {
1492
      png_warning(png_ptr, "Can't write tRNS with an alpha channel");
G
Guy Schalnat 已提交
1493
   }
G
Guy Schalnat 已提交
1494
}
G
Guy Schalnat 已提交
1495
#endif
G
Guy Schalnat 已提交
1496

1497
#ifdef PNG_WRITE_bKGD_SUPPORTED
1498
/* Write the background chunk */
1499
void /* PRIVATE */
1500
png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
G
Guy Schalnat 已提交
1501 1502 1503
{
   png_byte buf[6];

1504
   png_debug(1, "in png_write_bKGD");
1505

G
Guy Schalnat 已提交
1506 1507
   if (color_type == PNG_COLOR_TYPE_PALETTE)
   {
1508
      if (
1509
#ifdef PNG_MNG_FEATURES_SUPPORTED
1510 1511
          (png_ptr->num_palette ||
          (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
1512
#endif
1513
         back->index >= png_ptr->num_palette)
G
Guy Schalnat 已提交
1514 1515 1516 1517
      {
         png_warning(png_ptr, "Invalid background palette index");
         return;
      }
1518

G
Guy Schalnat 已提交
1519
      buf[0] = back->index;
1520
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
G
Guy Schalnat 已提交
1521
   }
1522

G
Guy Schalnat 已提交
1523 1524 1525 1526 1527
   else if (color_type & PNG_COLOR_MASK_COLOR)
   {
      png_save_uint_16(buf, back->red);
      png_save_uint_16(buf + 2, back->green);
      png_save_uint_16(buf + 4, back->blue);
1528
#ifdef PNG_WRITE_16BIT_SUPPORTED
1529
      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1530 1531 1532
#else
      if (buf[0] | buf[2] | buf[4])
#endif
1533 1534
      {
         png_warning(png_ptr,
1535
             "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
1536

1537 1538
         return;
      }
1539

1540
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
G
Guy Schalnat 已提交
1541
   }
1542

G
Guy Schalnat 已提交
1543
   else
G
Guy Schalnat 已提交
1544
   {
1545
      if (back->gray >= (1 << png_ptr->bit_depth))
1546 1547
      {
         png_warning(png_ptr,
1548
             "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
1549

1550 1551
         return;
      }
1552

G
Guy Schalnat 已提交
1553
      png_save_uint_16(buf, back->gray);
1554
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1555 1556
   }
}
G
Guy Schalnat 已提交
1557
#endif
G
Guy Schalnat 已提交
1558

1559
#ifdef PNG_WRITE_hIST_SUPPORTED
1560
/* Write the histogram */
1561
void /* PRIVATE */
1562
png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
G
Guy Schalnat 已提交
1563
{
1564
   int i;
G
Guy Schalnat 已提交
1565 1566
   png_byte buf[3];

1567
   png_debug(1, "in png_write_hIST");
1568

1569
   if (num_hist > (int)png_ptr->num_palette)
G
Guy Schalnat 已提交
1570
   {
1571
      png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
1572
          png_ptr->num_palette);
1573

G
Guy Schalnat 已提交
1574 1575 1576 1577
      png_warning(png_ptr, "Invalid number of histogram entries specified");
      return;
   }

1578
   png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
1579

A
Andreas Dilger 已提交
1580
   for (i = 0; i < num_hist; i++)
G
Guy Schalnat 已提交
1581
   {
G
Guy Schalnat 已提交
1582
      png_save_uint_16(buf, hist[i]);
1583
      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1584
   }
1585

G
Guy Schalnat 已提交
1586 1587
   png_write_chunk_end(png_ptr);
}
G
Guy Schalnat 已提交
1588
#endif
G
Guy Schalnat 已提交
1589

1590
#ifdef PNG_WRITE_tEXt_SUPPORTED
1591
/* Write a tEXt chunk */
1592
void /* PRIVATE */
1593
png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
1594
    png_size_t text_len)
G
Guy Schalnat 已提交
1595
{
1596 1597
   png_uint_32 key_len;
   png_byte new_key[80];
A
Andreas Dilger 已提交
1598

1599
   png_debug(1, "in png_write_tEXt");
1600

1601 1602 1603 1604
   key_len = png_check_keyword(png_ptr, key, new_key);

   if (key_len == 0)
      png_error(png_ptr, "tEXt: invalid keyword");
G
Guy Schalnat 已提交
1605

A
Andreas Dilger 已提交
1606
   if (text == NULL || *text == '\0')
A
Andreas Dilger 已提交
1607
      text_len = 0;
1608

1609 1610
   else
      text_len = png_strlen(text);
A
Andreas Dilger 已提交
1611

1612 1613 1614
   if (text_len > PNG_UINT_31_MAX - (key_len+1))
      png_error(png_ptr, "tEXt: text too long");

1615
   /* Make sure we include the 0 after the key */
1616
   png_write_chunk_header(png_ptr, png_tEXt,
1617
       (png_uint_32)/*checked above*/(key_len + text_len + 1));
1618 1619 1620 1621
   /*
    * We leave it to the application to meet PNG-1.0 requirements on the
    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
1622
    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1623
    */
1624
   png_write_chunk_data(png_ptr, new_key, key_len + 1);
1625

A
Andreas Dilger 已提交
1626
   if (text_len)
1627
      png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);
A
Andreas Dilger 已提交
1628

G
Guy Schalnat 已提交
1629 1630
   png_write_chunk_end(png_ptr);
}
G
Guy Schalnat 已提交
1631
#endif
G
Guy Schalnat 已提交
1632

1633
#ifdef PNG_WRITE_zTXt_SUPPORTED
1634
/* Write a compressed text chunk */
1635
void /* PRIVATE */
1636
png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
1637
    png_size_t text_len, int compression)
G
Guy Schalnat 已提交
1638
{
1639 1640
   png_uint_32 key_len;
   png_byte new_key[81];
1641
   compression_state comp;
G
Guy Schalnat 已提交
1642

1643
   png_debug(1, "in png_write_zTXt");
1644
   PNG_UNUSED(text_len) /* Always use strlen */
A
Andreas Dilger 已提交
1645

1646
   if (compression == PNG_TEXT_COMPRESSION_NONE)
A
Andreas Dilger 已提交
1647
   {
1648
      png_write_tEXt(png_ptr, key, text, 0);
G
Guy Schalnat 已提交
1649
      return;
A
Andreas Dilger 已提交
1650
   }
A
Andreas Dilger 已提交
1651

1652 1653
   if (compression != PNG_TEXT_COMPRESSION_zTXt)
      png_error(png_ptr, "zTXt: invalid compression type");
A
Andreas Dilger 已提交
1654

1655
   key_len = png_check_keyword(png_ptr, key, new_key);
1656

1657 1658
   if (key_len == 0)
      png_error(png_ptr, "zTXt: invalid keyword");
G
Guy Schalnat 已提交
1659

1660 1661 1662
   /* Add the compression method and 1 for the keyword separator. */
   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
   ++key_len;
1663

1664 1665
   /* Compute the compressed data; do it now for the length */
   png_text_compress_init(&comp, (png_const_bytep)text,
1666
      text == NULL ? 0 : png_strlen(text));
1667

1668 1669
   if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
      png_error(png_ptr, png_ptr->zstream.msg);
1670

1671 1672
   /* Write start of chunk */
   png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len);
1673

1674 1675
   /* Write key */
   png_write_chunk_data(png_ptr, new_key, key_len);
1676

1677
   /* Write the compressed data */
1678
   png_write_compressed_data_out(png_ptr, &comp);
G
Guy Schalnat 已提交
1679

1680
   /* Close the chunk */
1681 1682 1683
   png_write_chunk_end(png_ptr);
}
#endif
G
Guy Schalnat 已提交
1684

1685
#ifdef PNG_WRITE_iTXt_SUPPORTED
1686
/* Write an iTXt chunk */
1687
void /* PRIVATE */
1688
png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
1689
    png_const_charp lang, png_const_charp lang_key, png_const_charp text)
1690
{
1691 1692 1693
   png_uint_32 key_len, prefix_len;
   png_size_t lang_len, lang_key_len;
   png_byte new_key[82];
1694
   compression_state comp;
G
Guy Schalnat 已提交
1695

1696
   png_debug(1, "in png_write_iTXt");
G
Guy Schalnat 已提交
1697

1698 1699 1700 1701
   key_len = png_check_keyword(png_ptr, key, new_key);
   
   if (key_len == 0)
      png_error(png_ptr, "iTXt: invalid keyword");
1702

1703 1704
   /* Set the compression flag */
   switch (compression)
1705
   {
1706 1707 1708 1709
      case PNG_ITXT_COMPRESSION_NONE:
      case PNG_TEXT_COMPRESSION_NONE:
         compression = new_key[++key_len] = 0; /* no compression */
         break;
G
Guy Schalnat 已提交
1710

1711 1712 1713 1714
      case PNG_TEXT_COMPRESSION_zTXt:
      case PNG_ITXT_COMPRESSION_zTXt:
         compression = new_key[++key_len] = 1; /* compressed */
         break;
1715

1716 1717 1718
      default:
         png_error(png_ptr, "iTXt: invalid compression");
   }
G
Guy Schalnat 已提交
1719

1720 1721
   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
   ++key_len; /* for the keywod separator */
G
Guy Schalnat 已提交
1722

1723
   /* We leave it to the application to meet PNG-1.0 requirements on the
1724
    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
1725 1726 1727 1728
    * any non-Latin-1 characters except for NEWLINE.  ISO PNG, however,
    * specifies that the text is UTF-8 and this really doesn't require any
    * checking.
    *
1729
    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1730 1731
    *
    * TODO: validate the language tag correctly (see the spec.)
1732
    */
1733
   if (lang == NULL) lang = ""; /* empty language is valid */
1734
   lang_len = png_strlen(lang)+1;
1735
   if (lang_key == NULL) lang_key = ""; /* may be empty */
1736
   lang_key_len = png_strlen(lang_key)+1;
1737 1738 1739 1740 1741 1742 1743
   if (text == NULL) text = ""; /* may be empty */

   prefix_len = key_len;
   if (lang_len > PNG_UINT_31_MAX-prefix_len)
      prefix_len = PNG_UINT_31_MAX;
   else
      prefix_len = (png_uint_32)(prefix_len + lang_len);
1744

1745 1746 1747 1748
   if (lang_key_len > PNG_UINT_31_MAX-prefix_len)
      prefix_len = PNG_UINT_31_MAX;
   else
      prefix_len = (png_uint_32)(prefix_len + lang_key_len);
1749

1750
   png_text_compress_init(&comp, (png_const_bytep)text, png_strlen(text));
1751

1752 1753 1754 1755 1756
   if (compression)
   {
      if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)
         png_error(png_ptr, png_ptr->zstream.msg);
   }
1757

1758 1759 1760 1761 1762
   else
   {
      if (comp.input_len > PNG_UINT_31_MAX-prefix_len)
         png_error(png_ptr, "iTXt: uncompressed text too long");
   }
1763

1764
   png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len);
1765

1766
   png_write_chunk_data(png_ptr, new_key, key_len);
1767

1768
   png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len);
G
Guy Schalnat 已提交
1769

1770 1771 1772 1773
   png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);

   if (compression)
      png_write_compressed_data_out(png_ptr, &comp);
1774

1775 1776 1777 1778
   else
      png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len);

   png_write_chunk_end(png_ptr);
G
Guy Schalnat 已提交
1779
}
G
Guy Schalnat 已提交
1780
#endif
G
Guy Schalnat 已提交
1781

1782
#ifdef PNG_WRITE_oFFs_SUPPORTED
1783
/* Write the oFFs chunk */
1784
void /* PRIVATE */
1785
png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
1786
    int unit_type)
G
Guy Schalnat 已提交
1787 1788 1789
{
   png_byte buf[9];

1790
   png_debug(1, "in png_write_oFFs");
1791

A
Andreas Dilger 已提交
1792 1793
   if (unit_type >= PNG_OFFSET_LAST)
      png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
G
Guy Schalnat 已提交
1794

1795 1796
   png_save_int_32(buf, x_offset);
   png_save_int_32(buf + 4, y_offset);
G
Guy Schalnat 已提交
1797
   buf[8] = (png_byte)unit_type;
G
Guy Schalnat 已提交
1798

1799
   png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
G
Guy Schalnat 已提交
1800
}
G
Guy Schalnat 已提交
1801
#endif
1802
#ifdef PNG_WRITE_pCAL_SUPPORTED
1803
/* Write the pCAL chunk (described in the PNG extensions document) */
1804
void /* PRIVATE */
1805
png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
1806 1807
    png_int_32 X1, int type, int nparams, png_const_charp units,
    png_charpp params)
A
Andreas Dilger 已提交
1808
{
1809 1810
   png_uint_32 purpose_len;
   png_size_t units_len, total_len;
1811
   png_size_tp params_len;
A
Andreas Dilger 已提交
1812
   png_byte buf[10];
1813
   png_byte new_purpose[80];
A
Andreas Dilger 已提交
1814 1815
   int i;

1816
   png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
1817

A
Andreas Dilger 已提交
1818
   if (type >= PNG_EQUATION_LAST)
1819 1820 1821 1822 1823 1824 1825 1826
      png_error(png_ptr, "Unrecognized equation type for pCAL chunk");

   purpose_len = png_check_keyword(png_ptr, purpose, new_purpose);

   if (purpose_len == 0)
      png_error(png_ptr, "pCAL: invalid keyword");
   
   ++purpose_len; /* terminator */
A
Andreas Dilger 已提交
1827

1828
   png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
A
Andreas Dilger 已提交
1829
   units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
1830
   png_debug1(3, "pCAL units length = %d", (int)units_len);
A
Andreas Dilger 已提交
1831 1832
   total_len = purpose_len + units_len + 10;

1833
   params_len = (png_size_tp)png_malloc(png_ptr,
1834
       (png_alloc_size_t)(nparams * (sizeof (png_size_t))));
A
Andreas Dilger 已提交
1835 1836

   /* Find the length of each parameter, making sure we don't count the
1837 1838
    * null terminator for the last parameter.
    */
A
Andreas Dilger 已提交
1839 1840 1841
   for (i = 0; i < nparams; i++)
   {
      params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
1842
      png_debug2(3, "pCAL parameter %d length = %lu", i,
1843
          (unsigned long)params_len[i]);
1844
      total_len += params_len[i];
A
Andreas Dilger 已提交
1845 1846
   }

1847
   png_debug1(3, "pCAL total length = %d", (int)total_len);
1848
   png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
1849
   png_write_chunk_data(png_ptr, new_purpose, purpose_len);
A
Andreas Dilger 已提交
1850 1851 1852 1853
   png_save_int_32(buf, X0);
   png_save_int_32(buf + 4, X1);
   buf[8] = (png_byte)type;
   buf[9] = (png_byte)nparams;
1854
   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
1855
   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
A
Andreas Dilger 已提交
1856 1857 1858

   for (i = 0; i < nparams; i++)
   {
1859
      png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
A
Andreas Dilger 已提交
1860 1861
   }

1862
   png_free(png_ptr, params_len);
A
Andreas Dilger 已提交
1863 1864 1865 1866
   png_write_chunk_end(png_ptr);
}
#endif

1867
#ifdef PNG_WRITE_sCAL_SUPPORTED
1868
/* Write the sCAL chunk */
1869
void /* PRIVATE */
1870
png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
1871
    png_const_charp height)
1872
{
1873 1874
   png_byte buf[64];
   png_size_t wlen, hlen, total_len;
1875

1876
   png_debug(1, "in png_write_sCAL_s");
1877

1878 1879 1880
   wlen = png_strlen(width);
   hlen = png_strlen(height);
   total_len = wlen + hlen + 2;
1881

1882 1883 1884 1885 1886
   if (total_len > 64)
   {
      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
      return;
   }
1887

1888
   buf[0] = (png_byte)unit;
1889 1890
   memcpy(buf + 1, width, wlen + 1);      /* Append the '\0' here */
   memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\0' here */
1891

1892
   png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
1893
   png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
1894 1895 1896
}
#endif

1897
#ifdef PNG_WRITE_pHYs_SUPPORTED
1898
/* Write the pHYs chunk */
1899
void /* PRIVATE */
1900
png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
1901 1902
    png_uint_32 y_pixels_per_unit,
    int unit_type)
G
Guy Schalnat 已提交
1903 1904 1905
{
   png_byte buf[9];

1906
   png_debug(1, "in png_write_pHYs");
1907

A
Andreas Dilger 已提交
1908 1909
   if (unit_type >= PNG_RESOLUTION_LAST)
      png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
G
Guy Schalnat 已提交
1910

A
Andreas Dilger 已提交
1911 1912
   png_save_uint_32(buf, x_pixels_per_unit);
   png_save_uint_32(buf + 4, y_pixels_per_unit);
G
Guy Schalnat 已提交
1913
   buf[8] = (png_byte)unit_type;
G
Guy Schalnat 已提交
1914

1915
   png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
G
Guy Schalnat 已提交
1916
}
G
Guy Schalnat 已提交
1917
#endif
G
Guy Schalnat 已提交
1918

1919
#ifdef PNG_WRITE_tIME_SUPPORTED
1920 1921 1922
/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
 * or png_convert_from_time_t(), or fill in the structure yourself.
 */
1923
void /* PRIVATE */
1924
png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
G
Guy Schalnat 已提交
1925 1926 1927
{
   png_byte buf[7];

1928
   png_debug(1, "in png_write_tIME");
1929

G
Guy Schalnat 已提交
1930 1931 1932 1933 1934 1935 1936 1937
   if (mod_time->month  > 12 || mod_time->month  < 1 ||
       mod_time->day    > 31 || mod_time->day    < 1 ||
       mod_time->hour   > 23 || mod_time->second > 60)
   {
      png_warning(png_ptr, "Invalid time specified for tIME chunk");
      return;
   }

G
Guy Schalnat 已提交
1938 1939 1940 1941 1942 1943 1944
   png_save_uint_16(buf, mod_time->year);
   buf[2] = mod_time->month;
   buf[3] = mod_time->day;
   buf[4] = mod_time->hour;
   buf[5] = mod_time->minute;
   buf[6] = mod_time->second;

1945
   png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
G
Guy Schalnat 已提交
1946
}
G
Guy Schalnat 已提交
1947
#endif
G
Guy Schalnat 已提交
1948

1949
/* Initializes the row writing capability of libpng */
1950
void /* PRIVATE */
1951
png_write_start_row(png_structrp png_ptr)
G
Guy Schalnat 已提交
1952
{
1953
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1954
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1955

1956
   /* Start of interlace block */
1957
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1958

1959
   /* Offset to next interlace block */
1960
   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1961

1962
   /* Start of interlace block in the y direction */
1963
   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
1964

1965
   /* Offset to next interlace block in the y direction */
1966
   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
1967
#endif
1968

1969 1970
   png_alloc_size_t buf_size;
   int usr_pixel_depth;
A
Andreas Dilger 已提交
1971

1972
   png_debug(1, "in png_write_start_row");
1973

1974 1975 1976 1977 1978 1979
   usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
   buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;

   /* 1.5.6: added to allow checking in the row write code. */
   png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
   png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
A
Andreas Dilger 已提交
1980

1981
   /* Set up row buffer */
1982
   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
1983

A
Andreas Dilger 已提交
1984
   png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
G
Guy Schalnat 已提交
1985

1986
#ifdef PNG_WRITE_FILTER_SUPPORTED
1987
   /* Set up filtering buffer, if using this filter */
G
Guy Schalnat 已提交
1988
   if (png_ptr->do_filter & PNG_FILTER_SUB)
G
Guy Schalnat 已提交
1989
   {
1990
      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
1991

A
Andreas Dilger 已提交
1992
      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
G
Guy Schalnat 已提交
1993 1994
   }

A
Andreas Dilger 已提交
1995
   /* We only need to keep the previous row if we are using one of these. */
G
Guy Schalnat 已提交
1996 1997
   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
   {
1998
      /* Set up previous row buffer */
1999
      png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
G
Guy Schalnat 已提交
2000 2001 2002

      if (png_ptr->do_filter & PNG_FILTER_UP)
      {
2003
         png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
2004
            png_ptr->rowbytes + 1);
2005

A
Andreas Dilger 已提交
2006
         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
G
Guy Schalnat 已提交
2007 2008 2009 2010
      }

      if (png_ptr->do_filter & PNG_FILTER_AVG)
      {
2011
         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
2012
             png_ptr->rowbytes + 1);
2013

A
Andreas Dilger 已提交
2014
         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
G
Guy Schalnat 已提交
2015 2016 2017 2018
      }

      if (png_ptr->do_filter & PNG_FILTER_PAETH)
      {
2019
         png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
2020
             png_ptr->rowbytes + 1);
2021

A
Andreas Dilger 已提交
2022
         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
G
Guy Schalnat 已提交
2023
      }
G
Guy Schalnat 已提交
2024
   }
2025
#endif /* PNG_WRITE_FILTER_SUPPORTED */
G
Guy Schalnat 已提交
2026

2027
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2028
   /* If interlaced, we need to set up width and height of pass */
G
Guy Schalnat 已提交
2029
   if (png_ptr->interlaced)
G
Guy Schalnat 已提交
2030 2031 2032 2033
   {
      if (!(png_ptr->transformations & PNG_INTERLACE))
      {
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2034
             png_pass_ystart[0]) / png_pass_yinc[0];
2035

A
Andreas Dilger 已提交
2036
         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
2037
             png_pass_start[0]) / png_pass_inc[0];
G
Guy Schalnat 已提交
2038
      }
2039

G
Guy Schalnat 已提交
2040 2041 2042 2043 2044 2045
      else
      {
         png_ptr->num_rows = png_ptr->height;
         png_ptr->usr_width = png_ptr->width;
      }
   }
2046

G
Guy Schalnat 已提交
2047
   else
2048
#endif
G
Guy Schalnat 已提交
2049
   {
G
Guy Schalnat 已提交
2050 2051 2052 2053 2054
      png_ptr->num_rows = png_ptr->height;
      png_ptr->usr_width = png_ptr->width;
   }
}

A
Andreas Dilger 已提交
2055
/* Internal use only.  Called when finished processing a row of data. */
2056
void /* PRIVATE */
2057
png_write_finish_row(png_structrp png_ptr)
G
Guy Schalnat 已提交
2058
{
2059
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2060
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2061

2062
   /* Start of interlace block */
2063
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2064

2065
   /* Offset to next interlace block */
2066
   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2067

2068
   /* Start of interlace block in the y direction */
2069
   static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2070

2071
   /* Offset to next interlace block in the y direction */
2072
   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2073
#endif
2074

2075
   png_debug(1, "in png_write_finish_row");
2076

2077
   /* Next row */
G
Guy Schalnat 已提交
2078
   png_ptr->row_number++;
G
Guy Schalnat 已提交
2079

2080
   /* See if we are done */
G
Guy Schalnat 已提交
2081
   if (png_ptr->row_number < png_ptr->num_rows)
G
Guy Schalnat 已提交
2082
      return;
G
Guy Schalnat 已提交
2083

2084
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2085
   /* If interlaced, go to next pass */
G
Guy Schalnat 已提交
2086 2087 2088 2089 2090 2091 2092
   if (png_ptr->interlaced)
   {
      png_ptr->row_number = 0;
      if (png_ptr->transformations & PNG_INTERLACE)
      {
         png_ptr->pass++;
      }
2093

G
Guy Schalnat 已提交
2094 2095
      else
      {
2096
         /* Loop until we find a non-zero width or height pass */
G
Guy Schalnat 已提交
2097 2098 2099
         do
         {
            png_ptr->pass++;
2100

G
Guy Schalnat 已提交
2101 2102
            if (png_ptr->pass >= 7)
               break;
2103

G
Guy Schalnat 已提交
2104
            png_ptr->usr_width = (png_ptr->width +
2105 2106 2107
                png_pass_inc[png_ptr->pass] - 1 -
                png_pass_start[png_ptr->pass]) /
                png_pass_inc[png_ptr->pass];
2108

G
Guy Schalnat 已提交
2109
            png_ptr->num_rows = (png_ptr->height +
2110 2111 2112
                png_pass_yinc[png_ptr->pass] - 1 -
                png_pass_ystart[png_ptr->pass]) /
                png_pass_yinc[png_ptr->pass];
2113

G
Guy Schalnat 已提交
2114 2115
            if (png_ptr->transformations & PNG_INTERLACE)
               break;
2116

G
Guy Schalnat 已提交
2117 2118 2119 2120
         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);

      }

2121
      /* Reset the row above the image for the next pass */
G
Guy Schalnat 已提交
2122
      if (png_ptr->pass < 7)
G
Guy Schalnat 已提交
2123
      {
A
Andreas Dilger 已提交
2124
         if (png_ptr->prev_row != NULL)
2125
            memset(png_ptr->prev_row, 0,
2126 2127
                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
                png_ptr->usr_bit_depth, png_ptr->width)) + 1);
2128

G
Guy Schalnat 已提交
2129
         return;
G
Guy Schalnat 已提交
2130
      }
G
Guy Schalnat 已提交
2131
   }
2132
#endif
G
Guy Schalnat 已提交
2133

2134
   /* If we get here, we've just written the last row, so we need
G
Guy Schalnat 已提交
2135
      to flush the compressor */
2136
   png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH);
G
Guy Schalnat 已提交
2137 2138
}

2139
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2140 2141 2142 2143 2144 2145 2146
/* Pick out the correct pixels for the interlace pass.
 * The basic idea here is to go through the row with a source
 * pointer and a destination pointer (sp and dp), and copy the
 * correct pixels for the pass.  As the row gets compacted,
 * sp will always be >= dp, so we should never overwrite anything.
 * See the default: case for the easiest code to understand.
 */
2147
void /* PRIVATE */
G
Guy Schalnat 已提交
2148
png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
G
Guy Schalnat 已提交
2149
{
2150
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2151

2152
   /* Start of interlace block */
2153
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2154

2155
   /* Offset to next interlace block */
2156
   static PNG_CONST png_byte  png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2157

2158
   png_debug(1, "in png_do_write_interlace");
2159

2160
   /* We don't have to do anything on the last pass (6) */
A
Andreas Dilger 已提交
2161
   if (pass < 6)
G
Guy Schalnat 已提交
2162
   {
2163
      /* Each pixel depth is handled separately */
G
Guy Schalnat 已提交
2164
      switch (row_info->pixel_depth)
G
Guy Schalnat 已提交
2165
      {
G
Guy Schalnat 已提交
2166 2167
         case 1:
         {
G
Guy Schalnat 已提交
2168 2169
            png_bytep sp;
            png_bytep dp;
G
Guy Schalnat 已提交
2170 2171 2172
            int shift;
            int d;
            int value;
2173 2174
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2175 2176 2177 2178

            dp = row;
            d = 0;
            shift = 7;
2179

2180
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2181 2182 2183
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 3);
2184
               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
G
Guy Schalnat 已提交
2185 2186 2187 2188 2189
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 7;
G
Guy Schalnat 已提交
2190
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2191 2192
                  d = 0;
               }
2193

G
Guy Schalnat 已提交
2194 2195 2196 2197 2198
               else
                  shift--;

            }
            if (shift != 7)
G
Guy Schalnat 已提交
2199
               *dp = (png_byte)d;
2200

G
Guy Schalnat 已提交
2201 2202
            break;
         }
2203

G
Guy Schalnat 已提交
2204
         case 2:
G
Guy Schalnat 已提交
2205
         {
G
Guy Schalnat 已提交
2206 2207
            png_bytep sp;
            png_bytep dp;
G
Guy Schalnat 已提交
2208 2209 2210
            int shift;
            int d;
            int value;
2211 2212
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2213 2214 2215 2216

            dp = row;
            shift = 6;
            d = 0;
2217

2218
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2219 2220 2221
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 2);
2222
               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
G
Guy Schalnat 已提交
2223 2224 2225 2226 2227
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 6;
G
Guy Schalnat 已提交
2228
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2229 2230
                  d = 0;
               }
2231

G
Guy Schalnat 已提交
2232 2233 2234 2235
               else
                  shift -= 2;
            }
            if (shift != 6)
2236 2237
               *dp = (png_byte)d;

G
Guy Schalnat 已提交
2238 2239
            break;
         }
2240

G
Guy Schalnat 已提交
2241 2242
         case 4:
         {
G
Guy Schalnat 已提交
2243 2244
            png_bytep sp;
            png_bytep dp;
G
Guy Schalnat 已提交
2245
            int shift;
G
Guy Schalnat 已提交
2246 2247
            int d;
            int value;
2248 2249
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2250 2251 2252 2253

            dp = row;
            shift = 4;
            d = 0;
2254
            for (i = png_pass_start[pass]; i < row_width;
2255
                i += png_pass_inc[pass])
G
Guy Schalnat 已提交
2256 2257
            {
               sp = row + (png_size_t)(i >> 1);
2258
               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
G
Guy Schalnat 已提交
2259 2260 2261 2262
               d |= (value << shift);

               if (shift == 0)
               {
G
Guy Schalnat 已提交
2263 2264
                  shift = 4;
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2265 2266
                  d = 0;
               }
2267

G
Guy Schalnat 已提交
2268 2269 2270 2271
               else
                  shift -= 4;
            }
            if (shift != 4)
G
Guy Schalnat 已提交
2272
               *dp = (png_byte)d;
2273

G
Guy Schalnat 已提交
2274 2275
            break;
         }
2276

G
Guy Schalnat 已提交
2277 2278
         default:
         {
G
Guy Schalnat 已提交
2279 2280
            png_bytep sp;
            png_bytep dp;
2281 2282
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
A
Andreas Dilger 已提交
2283
            png_size_t pixel_bytes;
G
Guy Schalnat 已提交
2284

2285
            /* Start at the beginning */
G
Guy Schalnat 已提交
2286
            dp = row;
2287

2288
            /* Find out how many bytes each pixel takes up */
G
Guy Schalnat 已提交
2289
            pixel_bytes = (row_info->pixel_depth >> 3);
2290 2291

            /* Loop through the row, only looking at the pixels that matter */
2292
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2293 2294
               i += png_pass_inc[pass])
            {
2295
               /* Find out where the original pixel is */
2296
               sp = row + (png_size_t)i * pixel_bytes;
2297

2298
               /* Move the pixel */
G
Guy Schalnat 已提交
2299
               if (dp != sp)
2300
                  memcpy(dp, sp, pixel_bytes);
2301

2302
               /* Next pixel */
G
Guy Schalnat 已提交
2303 2304
               dp += pixel_bytes;
            }
G
Guy Schalnat 已提交
2305
            break;
G
Guy Schalnat 已提交
2306 2307
         }
      }
2308
      /* Set new row width */
G
Guy Schalnat 已提交
2309
      row_info->width = (row_info->width +
2310 2311 2312
          png_pass_inc[pass] - 1 -
          png_pass_start[pass]) /
          png_pass_inc[pass];
2313

2314 2315
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
          row_info->width);
G
Guy Schalnat 已提交
2316 2317
   }
}
G
Guy Schalnat 已提交
2318
#endif
G
Guy Schalnat 已提交
2319

A
Andreas Dilger 已提交
2320 2321
/* This filters the row, chooses which filter to use, if it has not already
 * been specified by the application, and then writes the row out with the
2322 2323
 * chosen filter.
 */
2324
static void png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
2325
   png_size_t row_bytes);
2326

2327
#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
A
Andreas Dilger 已提交
2328
#define PNG_HISHIFT 10
2329 2330
#define PNG_LOMASK ((png_uint_32)0xffffL)
#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
2331
void /* PRIVATE */
2332
png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
G
Guy Schalnat 已提交
2333
{
2334
   png_bytep best_row;
2335
#ifdef PNG_WRITE_FILTER_SUPPORTED
2336
   png_bytep prev_row, row_buf;
A
Andreas Dilger 已提交
2337
   png_uint_32 mins, bpp;
2338
   png_byte filter_to_do = png_ptr->do_filter;
2339
   png_size_t row_bytes = row_info->rowbytes;
2340
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2341
   int num_p_filters = png_ptr->num_prev_filters;
2342
#endif
2343 2344 2345 2346

   png_debug(1, "in png_write_find_filter");

#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2347
  if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
2348
  {
2349 2350
     /* These will never be selected so we need not test them. */
     filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
2351
  }
2352
#endif
G
Guy Schalnat 已提交
2353

2354
   /* Find out how many bytes offset each pixel is */
2355
   bpp = (row_info->pixel_depth + 7) >> 3;
G
Guy Schalnat 已提交
2356 2357

   prev_row = png_ptr->prev_row;
2358 2359
#endif
   best_row = png_ptr->row_buf;
2360
#ifdef PNG_WRITE_FILTER_SUPPORTED
2361
   row_buf = best_row;
A
Andreas Dilger 已提交
2362 2363 2364 2365
   mins = PNG_MAXSUM;

   /* The prediction method we use is to find which method provides the
    * smallest value when summing the absolute values of the distances
2366
    * from zero, using anything >= 128 as negative numbers.  This is known
A
Andreas Dilger 已提交
2367
    * as the "minimum sum of absolute differences" heuristic.  Other
2368
    * heuristics are the "weighted minimum sum of absolute differences"
A
Andreas Dilger 已提交
2369
    * (experimental and can in theory improve compression), and the "zlib
2370 2371 2372
    * predictive" method (not implemented yet), which does test compressions
    * of lines using different filter methods, and then chooses the
    * (series of) filter(s) that give minimum compressed data size (VERY
A
Andreas Dilger 已提交
2373
    * computationally expensive).
2374 2375
    *
    * GRR 980525:  consider also
2376
    *
2377 2378 2379
    *   (1) minimum sum of absolute differences from running average (i.e.,
    *       keep running sum of non-absolute differences & count of bytes)
    *       [track dispersion, too?  restart average if dispersion too large?]
2380
    *
2381 2382
    *  (1b) minimum sum of absolute differences from sliding average, probably
    *       with window size <= deflate window (usually 32K)
2383
    *
2384 2385
    *   (2) minimum sum of squared differences from zero or running average
    *       (i.e., ~ root-mean-square approach)
A
Andreas Dilger 已提交
2386
    */
G
Guy Schalnat 已提交
2387

2388

G
Guy Schalnat 已提交
2389
   /* We don't need to test the 'no filter' case if this is the only filter
A
Andreas Dilger 已提交
2390 2391
    * that has been chosen, as it doesn't actually do anything to the data.
    */
2392
   if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE)
G
Guy Schalnat 已提交
2393
   {
G
Guy Schalnat 已提交
2394 2395
      png_bytep rp;
      png_uint_32 sum = 0;
2396
      png_size_t i;
A
Andreas Dilger 已提交
2397
      int v;
G
Guy Schalnat 已提交
2398

2399
      for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
G
Guy Schalnat 已提交
2400 2401 2402 2403
      {
         v = *rp;
         sum += (v < 128) ? v : 256 - v;
      }
A
Andreas Dilger 已提交
2404

2405
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2406 2407 2408
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
         png_uint_32 sumhi, sumlo;
2409
         int j;
A
Andreas Dilger 已提交
2410 2411 2412 2413
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */

         /* Reduce the sum if we match any of the previous rows */
2414
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2415
         {
2416
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
A
Andreas Dilger 已提交
2417
            {
2418
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2419
                   PNG_WEIGHT_SHIFT;
2420

2421
               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2422
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2423 2424 2425 2426 2427 2428 2429 2430
            }
         }

         /* Factor in the cost of this filter (this is here for completeness,
          * but it makes no sense to have a "cost" for the NONE filter, as
          * it has the minimum possible computational cost - none).
          */
         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2431
             PNG_COST_SHIFT;
2432

A
Andreas Dilger 已提交
2433
         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2434
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2435 2436 2437

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2438

A
Andreas Dilger 已提交
2439 2440 2441 2442
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
      }
#endif
G
Guy Schalnat 已提交
2443 2444
      mins = sum;
   }
G
Guy Schalnat 已提交
2445

2446
   /* Sub filter */
2447
   if (filter_to_do == PNG_FILTER_SUB)
2448
   /* It's the only filter so no testing is needed */
2449 2450
   {
      png_bytep rp, lp, dp;
2451
      png_size_t i;
2452

2453 2454 2455 2456 2457
      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
           i++, rp++, dp++)
      {
         *dp = *rp;
      }
2458

2459
      for (lp = row_buf + 1; i < row_bytes;
2460 2461 2462 2463
         i++, rp++, lp++, dp++)
      {
         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
      }
2464

2465 2466 2467 2468
      best_row = png_ptr->sub_row;
   }

   else if (filter_to_do & PNG_FILTER_SUB)
G
Guy Schalnat 已提交
2469 2470
   {
      png_bytep rp, dp, lp;
A
Andreas Dilger 已提交
2471
      png_uint_32 sum = 0, lmins = mins;
2472
      png_size_t i;
A
Andreas Dilger 已提交
2473 2474
      int v;

2475
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2476
      /* We temporarily increase the "minimum sum" by the factor we
A
Andreas Dilger 已提交
2477 2478 2479 2480 2481
       * would reduce the sum of this filter, so that we can do the
       * early exit comparison without scaling the sum each time.
       */
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2482
         int j;
A
Andreas Dilger 已提交
2483 2484 2485 2486
         png_uint_32 lmhi, lmlo;
         lmlo = lmins & PNG_LOMASK;
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;

2487
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2488
         {
2489
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
A
Andreas Dilger 已提交
2490
            {
2491
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2492
                   PNG_WEIGHT_SHIFT;
2493

2494
               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2495
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2496 2497 2498 2499
            }
         }

         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2500
             PNG_COST_SHIFT;
2501

A
Andreas Dilger 已提交
2502
         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2503
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2504 2505 2506

         if (lmhi > PNG_HIMASK)
            lmins = PNG_MAXSUM;
2507

A
Andreas Dilger 已提交
2508 2509 2510 2511
         else
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
      }
#endif
G
Guy Schalnat 已提交
2512

G
Guy Schalnat 已提交
2513 2514 2515 2516
      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
           i++, rp++, dp++)
      {
         v = *dp = *rp;
G
Guy Schalnat 已提交
2517

G
Guy Schalnat 已提交
2518 2519
         sum += (v < 128) ? v : 256 - v;
      }
2520

2521
      for (lp = row_buf + 1; i < row_bytes;
2522
         i++, rp++, lp++, dp++)
G
Guy Schalnat 已提交
2523 2524 2525 2526
      {
         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);

         sum += (v < 128) ? v : 256 - v;
A
Andreas Dilger 已提交
2527 2528 2529 2530 2531

         if (sum > lmins)  /* We are already worse, don't continue. */
            break;
      }

2532
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2533 2534
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2535
         int j;
A
Andreas Dilger 已提交
2536 2537 2538 2539
         png_uint_32 sumhi, sumlo;
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;

2540
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2541
         {
2542
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
A
Andreas Dilger 已提交
2543
            {
2544
               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
2545
                   PNG_WEIGHT_SHIFT;
2546

2547
               sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
2548
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2549 2550 2551 2552
            }
         }

         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2553
             PNG_COST_SHIFT;
2554

A
Andreas Dilger 已提交
2555
         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2556
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2557 2558 2559

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2560

A
Andreas Dilger 已提交
2561 2562
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
G
Guy Schalnat 已提交
2563
      }
A
Andreas Dilger 已提交
2564 2565
#endif

G
Guy Schalnat 已提交
2566 2567 2568 2569 2570
      if (sum < mins)
      {
         mins = sum;
         best_row = png_ptr->sub_row;
      }
G
Guy Schalnat 已提交
2571 2572
   }

2573
   /* Up filter */
2574 2575 2576
   if (filter_to_do == PNG_FILTER_UP)
   {
      png_bytep rp, dp, pp;
2577
      png_size_t i;
2578 2579

      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2580 2581
          pp = prev_row + 1; i < row_bytes;
          i++, rp++, pp++, dp++)
2582 2583 2584
      {
         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
      }
2585

2586 2587 2588 2589
      best_row = png_ptr->up_row;
   }

   else if (filter_to_do & PNG_FILTER_UP)
G
Guy Schalnat 已提交
2590 2591
   {
      png_bytep rp, dp, pp;
A
Andreas Dilger 已提交
2592
      png_uint_32 sum = 0, lmins = mins;
2593
      png_size_t i;
A
Andreas Dilger 已提交
2594 2595
      int v;

2596

2597
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2598 2599
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2600
         int j;
A
Andreas Dilger 已提交
2601 2602 2603 2604
         png_uint_32 lmhi, lmlo;
         lmlo = lmins & PNG_LOMASK;
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;

2605
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2606
         {
2607
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
A
Andreas Dilger 已提交
2608
            {
2609
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2610
                   PNG_WEIGHT_SHIFT;
2611

2612
               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2613
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2614 2615 2616 2617
            }
         }

         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2618
             PNG_COST_SHIFT;
2619

A
Andreas Dilger 已提交
2620
         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2621
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2622 2623 2624

         if (lmhi > PNG_HIMASK)
            lmins = PNG_MAXSUM;
2625

A
Andreas Dilger 已提交
2626 2627 2628 2629
         else
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
      }
#endif
G
Guy Schalnat 已提交
2630

G
Guy Schalnat 已提交
2631
      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2632
          pp = prev_row + 1; i < row_bytes; i++)
G
Guy Schalnat 已提交
2633
      {
2634
         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
G
Guy Schalnat 已提交
2635 2636

         sum += (v < 128) ? v : 256 - v;
A
Andreas Dilger 已提交
2637 2638 2639

         if (sum > lmins)  /* We are already worse, don't continue. */
            break;
G
Guy Schalnat 已提交
2640
      }
A
Andreas Dilger 已提交
2641

2642
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2643 2644
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2645
         int j;
A
Andreas Dilger 已提交
2646 2647 2648 2649
         png_uint_32 sumhi, sumlo;
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;

2650
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2651
         {
2652
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
A
Andreas Dilger 已提交
2653
            {
2654
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2655
                   PNG_WEIGHT_SHIFT;
2656

2657
               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2658
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2659 2660 2661 2662
            }
         }

         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2663
             PNG_COST_SHIFT;
2664

A
Andreas Dilger 已提交
2665
         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2666
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2667 2668 2669

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2670

A
Andreas Dilger 已提交
2671 2672 2673 2674 2675
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
      }
#endif

G
Guy Schalnat 已提交
2676 2677 2678 2679 2680 2681 2682
      if (sum < mins)
      {
         mins = sum;
         best_row = png_ptr->up_row;
      }
   }

2683
   /* Avg filter */
2684 2685 2686
   if (filter_to_do == PNG_FILTER_AVG)
   {
      png_bytep rp, dp, pp, lp;
2687
      png_uint_32 i;
2688

2689
      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2690
           pp = prev_row + 1; i < bpp; i++)
2691
      {
2692
         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2693
      }
2694

2695
      for (lp = row_buf + 1; i < row_bytes; i++)
2696
      {
2697 2698
         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
                 & 0xff);
2699 2700 2701 2702 2703
      }
      best_row = png_ptr->avg_row;
   }

   else if (filter_to_do & PNG_FILTER_AVG)
G
Guy Schalnat 已提交
2704
   {
G
Guy Schalnat 已提交
2705
      png_bytep rp, dp, pp, lp;
A
Andreas Dilger 已提交
2706
      png_uint_32 sum = 0, lmins = mins;
2707
      png_size_t i;
A
Andreas Dilger 已提交
2708 2709
      int v;

2710
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2711 2712
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2713
         int j;
A
Andreas Dilger 已提交
2714 2715 2716 2717
         png_uint_32 lmhi, lmlo;
         lmlo = lmins & PNG_LOMASK;
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;

2718
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2719
         {
2720
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
A
Andreas Dilger 已提交
2721
            {
2722
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2723
                   PNG_WEIGHT_SHIFT;
2724

2725
               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2726
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2727 2728 2729 2730
            }
         }

         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2731
             PNG_COST_SHIFT;
2732

A
Andreas Dilger 已提交
2733
         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2734
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2735 2736 2737

         if (lmhi > PNG_HIMASK)
            lmins = PNG_MAXSUM;
2738

A
Andreas Dilger 已提交
2739 2740 2741 2742
         else
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
      }
#endif
G
Guy Schalnat 已提交
2743

G
Guy Schalnat 已提交
2744
      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2745
           pp = prev_row + 1; i < bpp; i++)
G
Guy Schalnat 已提交
2746
      {
2747
         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
G
Guy Schalnat 已提交
2748

G
Guy Schalnat 已提交
2749 2750
         sum += (v < 128) ? v : 256 - v;
      }
2751

2752
      for (lp = row_buf + 1; i < row_bytes; i++)
G
Guy Schalnat 已提交
2753
      {
2754
         v = *dp++ =
2755
             (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
G
Guy Schalnat 已提交
2756

G
Guy Schalnat 已提交
2757
         sum += (v < 128) ? v : 256 - v;
A
Andreas Dilger 已提交
2758 2759 2760

         if (sum > lmins)  /* We are already worse, don't continue. */
            break;
G
Guy Schalnat 已提交
2761
      }
A
Andreas Dilger 已提交
2762

2763
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2764 2765
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2766
         int j;
A
Andreas Dilger 已提交
2767 2768 2769 2770
         png_uint_32 sumhi, sumlo;
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;

2771
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2772
         {
2773
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
A
Andreas Dilger 已提交
2774
            {
2775
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2776
                   PNG_WEIGHT_SHIFT;
2777

2778
               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2779
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2780 2781 2782 2783
            }
         }

         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2784
             PNG_COST_SHIFT;
2785

A
Andreas Dilger 已提交
2786
         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2787
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2788 2789 2790

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2791

A
Andreas Dilger 已提交
2792 2793 2794 2795 2796
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
      }
#endif

G
Guy Schalnat 已提交
2797 2798 2799 2800 2801 2802
      if (sum < mins)
      {
         mins = sum;
         best_row = png_ptr->avg_row;
      }
   }
G
Guy Schalnat 已提交
2803

A
Andreas Dilger 已提交
2804
   /* Paeth filter */
2805 2806 2807
   if (filter_to_do == PNG_FILTER_PAETH)
   {
      png_bytep rp, dp, pp, cp, lp;
2808
      png_size_t i;
2809

2810
      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2811
          pp = prev_row + 1; i < bpp; i++)
2812
      {
2813
         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2814 2815
      }

2816
      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
2817 2818 2819
      {
         int a, b, c, pa, pb, pc, p;

2820 2821 2822
         b = *pp++;
         c = *cp++;
         a = *lp++;
2823

2824 2825
         p = b - c;
         pc = a - c;
2826 2827

#ifdef PNG_USE_ABS
2828 2829 2830
         pa = abs(p);
         pb = abs(pc);
         pc = abs(p + pc);
2831
#else
2832 2833 2834
         pa = p < 0 ? -p : p;
         pb = pc < 0 ? -pc : pc;
         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2835 2836 2837 2838
#endif

         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;

2839
         *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
2840 2841 2842 2843 2844
      }
      best_row = png_ptr->paeth_row;
   }

   else if (filter_to_do & PNG_FILTER_PAETH)
G
Guy Schalnat 已提交
2845 2846
   {
      png_bytep rp, dp, pp, cp, lp;
A
Andreas Dilger 已提交
2847
      png_uint_32 sum = 0, lmins = mins;
2848
      png_size_t i;
A
Andreas Dilger 已提交
2849 2850
      int v;

2851
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2852 2853
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2854
         int j;
A
Andreas Dilger 已提交
2855 2856 2857 2858
         png_uint_32 lmhi, lmlo;
         lmlo = lmins & PNG_LOMASK;
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;

2859
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2860
         {
2861
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
A
Andreas Dilger 已提交
2862
            {
2863
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2864
                   PNG_WEIGHT_SHIFT;
2865

2866
               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2867
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2868 2869 2870 2871
            }
         }

         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2872
             PNG_COST_SHIFT;
2873

A
Andreas Dilger 已提交
2874
         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2875
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2876 2877 2878

         if (lmhi > PNG_HIMASK)
            lmins = PNG_MAXSUM;
2879

A
Andreas Dilger 已提交
2880 2881 2882 2883
         else
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
      }
#endif
G
Guy Schalnat 已提交
2884

G
Guy Schalnat 已提交
2885
      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2886
          pp = prev_row + 1; i < bpp; i++)
G
Guy Schalnat 已提交
2887
      {
2888
         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
G
Guy Schalnat 已提交
2889

G
Guy Schalnat 已提交
2890 2891
         sum += (v < 128) ? v : 256 - v;
      }
2892

2893
      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
G
Guy Schalnat 已提交
2894 2895
      {
         int a, b, c, pa, pb, pc, p;
G
Guy Schalnat 已提交
2896

2897 2898 2899
         b = *pp++;
         c = *cp++;
         a = *lp++;
2900 2901

#ifndef PNG_SLOW_PAETH
2902 2903
         p = b - c;
         pc = a - c;
2904
#ifdef PNG_USE_ABS
2905 2906 2907
         pa = abs(p);
         pb = abs(pc);
         pc = abs(p + pc);
2908
#else
2909 2910 2911
         pa = p < 0 ? -p : p;
         pb = pc < 0 ? -pc : pc;
         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2912 2913 2914
#endif
         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
#else /* PNG_SLOW_PAETH */
2915
         p = a + b - c;
2916 2917 2918
         pa = abs(p - a);
         pb = abs(p - b);
         pc = abs(p - c);
2919

G
Guy Schalnat 已提交
2920 2921
         if (pa <= pb && pa <= pc)
            p = a;
2922

G
Guy Schalnat 已提交
2923 2924
         else if (pb <= pc)
            p = b;
2925

G
Guy Schalnat 已提交
2926 2927
         else
            p = c;
2928
#endif /* PNG_SLOW_PAETH */
G
Guy Schalnat 已提交
2929

2930
         v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
G
Guy Schalnat 已提交
2931

G
Guy Schalnat 已提交
2932
         sum += (v < 128) ? v : 256 - v;
A
Andreas Dilger 已提交
2933 2934 2935

         if (sum > lmins)  /* We are already worse, don't continue. */
            break;
G
Guy Schalnat 已提交
2936
      }
A
Andreas Dilger 已提交
2937

2938
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2939 2940
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2941
         int j;
A
Andreas Dilger 已提交
2942 2943 2944 2945
         png_uint_32 sumhi, sumlo;
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;

2946
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2947
         {
2948
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
A
Andreas Dilger 已提交
2949
            {
2950
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2951
                   PNG_WEIGHT_SHIFT;
2952

2953
               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2954
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2955 2956 2957 2958
            }
         }

         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2959
             PNG_COST_SHIFT;
2960

A
Andreas Dilger 已提交
2961
         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2962
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2963 2964 2965

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2966

A
Andreas Dilger 已提交
2967 2968 2969 2970 2971
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
      }
#endif

G
Guy Schalnat 已提交
2972 2973 2974 2975
      if (sum < mins)
      {
         best_row = png_ptr->paeth_row;
      }
G
Guy Schalnat 已提交
2976
   }
2977
#endif /* PNG_WRITE_FILTER_SUPPORTED */
2978

2979 2980
   /* Do the actual writing of the filtered row data from the chosen filter. */
   png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
A
Andreas Dilger 已提交
2981

2982
#ifdef PNG_WRITE_FILTER_SUPPORTED
2983
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2984 2985 2986
   /* Save the type of filter we picked this time for future calculations */
   if (png_ptr->num_prev_filters > 0)
   {
2987
      int j;
2988

2989
      for (j = 1; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2990
      {
2991
         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
A
Andreas Dilger 已提交
2992
      }
2993

2994
      png_ptr->prev_filters[j] = best_row[0];
A
Andreas Dilger 已提交
2995 2996
   }
#endif
2997
#endif /* PNG_WRITE_FILTER_SUPPORTED */
G
Guy Schalnat 已提交
2998
}
G
Guy Schalnat 已提交
2999

G
Guy Schalnat 已提交
3000

A
Andreas Dilger 已提交
3001
/* Do the actual writing of a previously filtered row. */
3002
static void
3003
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
3004
   png_size_t full_row_length/*includes filter byte*/)
G
Guy Schalnat 已提交
3005
{
3006
   png_debug(1, "in png_write_filtered_row");
3007

3008
   png_debug1(2, "filter = %d", filtered_row[0]);
3009

3010
   png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
G
Guy Schalnat 已提交
3011

3012
   /* Swap the current and previous rows */
A
Andreas Dilger 已提交
3013
   if (png_ptr->prev_row != NULL)
G
Guy Schalnat 已提交
3014 3015 3016 3017 3018 3019 3020 3021
   {
      png_bytep tptr;

      tptr = png_ptr->prev_row;
      png_ptr->prev_row = png_ptr->row_buf;
      png_ptr->row_buf = tptr;
   }

3022
   /* Finish row - updates counters and flushes zlib if last row */
G
Guy Schalnat 已提交
3023
   png_write_finish_row(png_ptr);
G
Guy Schalnat 已提交
3024

3025
#ifdef PNG_WRITE_FLUSH_SUPPORTED
G
Guy Schalnat 已提交
3026 3027 3028 3029 3030 3031
   png_ptr->flush_rows++;

   if (png_ptr->flush_dist > 0 &&
       png_ptr->flush_rows >= png_ptr->flush_dist)
   {
      png_write_flush(png_ptr);
G
Guy Schalnat 已提交
3032
   }
3033
#endif
G
Guy Schalnat 已提交
3034
}
3035
#endif /* PNG_WRITE_SUPPORTED */