pngwutil.c 87.0 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.11 [June 5, 2014]
5
 * Copyright (c) 1998-2014 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 33 34 35
/* 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.
 */
36
void PNGAPI
37
png_save_uint_16(png_bytep buf, unsigned int i)
G
Guy Schalnat 已提交
38 39 40 41
{
   buf[0] = (png_byte)((i >> 8) & 0xff);
   buf[1] = (png_byte)(i & 0xff);
}
42
#endif
G
Guy Schalnat 已提交
43

44 45 46 47 48 49
/* 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.
 */
50
void PNGAPI
51
png_write_sig(png_structrp png_ptr)
52 53
{
   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
54

55 56 57 58 59
#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

60
   /* Write the rest of the 8 byte signature */
61
   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
62
      (png_size_t)(8 - png_ptr->sig_bytes));
63

64
   if (png_ptr->sig_bytes < 3)
65 66 67
      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
}

A
Andreas Dilger 已提交
68
/* Write the start of a PNG chunk.  The type is the chunk type.
69 70 71
 * The total_length is the sum of the lengths of all the data you will be
 * passing in png_write_chunk_data().
 */
72
static void
73
png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name,
74
    png_uint_32 length)
G
Guy Schalnat 已提交
75
{
76 77
   png_byte buf[8];

78
#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
79 80 81
   PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
   png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
#endif
82 83 84 85

   if (png_ptr == NULL)
      return;

86 87 88 89 90 91 92
#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

93
   /* Write the length and the chunk name */
A
Andreas Dilger 已提交
94
   png_save_uint_32(buf, length);
95 96
   png_save_uint_32(buf + 4, chunk_name);
   png_write_data(png_ptr, buf, 8);
97

98
   /* Put the chunk name into png_ptr->chunk_name */
99
   png_ptr->chunk_name = chunk_name;
100

101
   /* Reset the crc and run it over the chunk name */
G
Guy Schalnat 已提交
102
   png_reset_crc(png_ptr);
103

104
   png_calculate_crc(png_ptr, buf + 4, 4);
105 106 107 108 109 110 111

#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 已提交
112 113
}

114
void PNGAPI
115
png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
116 117 118 119 120 121
    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().
122 123
 * 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
124
 * given to png_write_chunk_header().
125
 */
126
void PNGAPI
127
png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
128
    png_size_t length)
G
Guy Schalnat 已提交
129
{
130 131 132
   /* Write the data, and run the CRC over it */
   if (png_ptr == NULL)
      return;
133

A
Andreas Dilger 已提交
134
   if (data != NULL && length > 0)
G
Guy Schalnat 已提交
135
   {
G
Guy Schalnat 已提交
136
      png_write_data(png_ptr, data, length);
137

138
      /* Update the CRC after writing the data,
139 140 141
       * in case that the user I/O routine alters it.
       */
      png_calculate_crc(png_ptr, data, length);
G
Guy Schalnat 已提交
142 143 144
   }
}

145
/* Finish a chunk started with png_write_chunk_header(). */
146
void PNGAPI
147
png_write_chunk_end(png_structrp png_ptr)
G
Guy Schalnat 已提交
148
{
A
Andreas Dilger 已提交
149 150
   png_byte buf[4];

151 152
   if (png_ptr == NULL) return;

153 154 155 156 157 158 159
#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

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

163
   png_write_data(png_ptr, buf, (png_size_t)4);
G
Guy Schalnat 已提交
164 165
}

166 167 168 169 170 171 172 173 174 175
/* 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
176
png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
177 178 179 180 181 182
   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. */
183
   if (length > PNG_UINT_31_MAX)
184 185 186 187 188 189 190 191 192
      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
193
png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
194 195 196 197 198 199
   png_const_bytep data, png_size_t length)
{
   png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
      length);
}

200 201 202 203 204 205
/* 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)
206
{
207 208 209 210 211 212
   /* 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)
213
   {
214
      if (png_ptr->interlaced)
215
      {
216 217 218 219 220 221 222
         /* 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 cb_base;
         int pass;
223

224
         for (cb_base=0, pass=0; pass<=6; ++pass)
225
         {
226
            png_uint_32 pw = PNG_PASS_COLS(w, pass);
227

228 229
            if (pw > 0)
               cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);
230 231
         }

232 233
         return cb_base;
      }
234

235 236 237
      else
         return (png_ptr->rowbytes+1) * h;
   }
238

239 240 241
   else
      return 0xffffffffU;
}
242

243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
#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.)
    */
static void
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 */
259

260 261 262 263
      if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
      {
         unsigned int z_cinfo;
         unsigned int half_z_window_size;
264

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

268 269 270 271 272 273 274 275
         if (data_size <= half_z_window_size) /* else no change */
         {
            unsigned int tmp;

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

279 280 281 282 283 284
            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;
285 286
         }
      }
287 288
   }
}
289 290 291
#else
#  define optimize_cmf(dp,dl) ((void)0)
#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
292

293 294 295 296
/* Initialize the compressor for the appropriate type of compression. */
static int
png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
   png_alloc_size_t data_size)
297
{
298
   if (png_ptr->zowner != 0)
299
   {
300
      char msg[64];
301

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
      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.
       */
      (void)png_safecat(msg, (sizeof msg), 10, " using zstream");
#     if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
         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
   }

   {
      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 */
334

335
      if (owner == png_IDAT)
336
      {
337 338
         if (png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)
            strategy = png_ptr->zlib_strategy;
339

340 341
         else if (png_ptr->do_filter != PNG_FILTER_NONE)
            strategy = PNG_Z_DEFAULT_STRATEGY;
342

343 344 345
         else
            strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY;
      }
346

347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
      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
      }
364

365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
      /* Adjust 'windowBits' down if larger than 'data_size'; to stop this
       * 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!)
       */
      if (data_size <= 16384)
      {
         /* 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);

         while (data_size + 262 <= half_window_size)
         {
            half_window_size >>= 1;
            --windowBits;
385
         }
386
      }
387

388 389 390 391 392 393 394 395 396 397
      /* 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)");
398

399 400
         png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED;
      }
401

402 403 404 405 406 407 408
      /* 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;
409

410 411 412 413 414 415 416 417 418 419 420 421 422
      /* 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;
423
      }
424 425 426 427 428 429 430 431 432 433 434

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

      else
         png_zstream_error(png_ptr, ret);

      return ret;
435
   }
436
}
437

438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
/* 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);
   }
457 458
}

459
#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
460
/* This pair of functions encapsulates the operation of (a) compressing a
461 462
 * text string, and (b) issuing it later as a series of chunk data writes.
 * The compression_state structure is shared context for these functions
463 464 465 466 467 468
 * 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.)
469 470 471
 */
typedef struct
{
472 473 474 475
   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 */
476 477
} compression_state;

478 479 480
static void
png_text_compress_init(compression_state *comp, png_const_bytep input,
   png_alloc_size_t input_len)
481
{
482 483 484 485
   comp->input = input;
   comp->input_len = input_len;
   comp->output_len = 0;
}
486

487 488 489 490 491 492
/* 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;
493

494 495 496 497
   /* 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.
498
    *
499 500 501 502
    * 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.
503
    */
504
   ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len);
505

506 507
   if (ret != Z_OK)
      return ret;
508

509 510 511 512 513 514
   /* 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.
    */
515
   {
516 517 518
      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;
519

520 521 522 523 524
      /* 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;
      png_ptr->zstream.avail_out = (sizeof comp->output);
525

526
      output_len = png_ptr->zstream.avail_out;
527

528
      do
529
      {
530
         uInt avail_in = ZLIB_IO_MAX;
531

532 533
         if (avail_in > input_len)
            avail_in = (uInt)input_len;
534

535
         input_len -= avail_in;
536

537
         png_ptr->zstream.avail_in = avail_in;
538

539 540 541
         if (png_ptr->zstream.avail_out == 0)
         {
            png_compression_buffer *next;
542

543 544 545 546 547 548 549
            /* 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;
550 551
            }

552 553 554 555 556
            /* Need a new (malloc'ed) buffer, but there may be one present
             * already.
             */
            next = *end;
            if (next == NULL)
557
            {
558 559
               next = png_voidcast(png_compression_bufferp, png_malloc_base
                  (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
560

561
               if (next == NULL)
562
               {
563 564
                  ret = Z_MEM_ERROR;
                  break;
565 566
               }

567 568 569
               /* Link in this buffer (so that it will be freed later) */
               next->next = NULL;
               *end = next;
570 571
            }

572 573 574
            png_ptr->zstream.next_out = next->output;
            png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
            output_len += png_ptr->zstream.avail_out;
575

576 577 578
            /* Move 'end' to the next buffer pointer. */
            end = &next->next;
         }
579

580 581 582
         /* Compress the data */
         ret = deflate(&png_ptr->zstream,
            input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
583

584 585 586 587 588
         /* 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 */
589
      }
590
      while (ret == Z_OK);
591

592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
      /* 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;
607 608
      }

609 610
      else
         png_zstream_error(png_ptr, ret);
611

612 613
      /* Reset zlib for another zTXt/iTXt or image data */
      png_ptr->zowner = 0;
614

615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
      /* 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);

         /* 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;
   }
633 634
}

635
/* Ship the compressed text out via chunk writes */
636
static void
637
png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
638
{
639 640 641 642
   png_uint_32 output_len = comp->output_len;
   png_const_bytep output = comp->output;
   png_uint_32 avail = (sizeof comp->output);
   png_compression_buffer *next = png_ptr->zbuffer_list;
643

644
   for (;;)
645
   {
646 647
      if (avail > output_len)
         avail = output_len;
648

649
      png_write_chunk_data(png_ptr, output, avail);
650

651
      output_len -= avail;
652

653 654
      if (output_len == 0 || next == NULL)
         break;
655

656 657 658 659
      avail = png_ptr->zbuffer_size;
      output = next->output;
      next = next->next;
   }
660

661 662 663 664 665
   /* This is an internal error; 'next' must have been NULL! */
   if (output_len > 0)
      png_error(png_ptr, "error writing ancillary chunked compressed data");
}
#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
666

667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
#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;
686

687
   png_debug(1, "in png_check_keyword");
688

689 690 691 692 693
   if (key == NULL)
   {
      *new_key = 0;
      return 0;
   }
694

695 696 697
   while (*key && key_len < 79)
   {
      png_byte ch = (png_byte)(0xff & *key++);
698

699 700
      if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
         *new_key++ = ch, ++key_len, space = 0;
701

702
      else if (space == 0)
703 704 705 706 707
      {
         /* A space or an invalid character when one wasn't seen immediately
          * before; output just a space.
          */
         *new_key++ = 32, ++key_len, space = 1;
708

709 710 711
         /* If the character was not a space then it is invalid. */
         if (ch != 32)
            bad_character = ch;
712 713
      }

714
      else if (bad_character == 0)
715
         bad_character = ch; /* just skip it, record the first error */
716 717
   }

718
   if (key_len > 0 && space) /* trailing space */
719
   {
720
      --key_len, --new_key;
721
      if (bad_character == 0)
722
         bad_character = 32;
723
   }
724

725 726
   /* Terminate the keyword */
   *new_key = 0;
727

728 729 730 731 732 733 734
   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");

735
   else if (bad_character != 0)
736 737 738 739 740 741 742 743
   {
      PNG_WARNING_PARAMETERS(p)

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

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

745
   return key_len;
746
}
747
#endif
748

G
Guy Schalnat 已提交
749
/* Write the IHDR chunk, and update the png_struct with the necessary
750 751 752
 * information.  Note that the rest of this code depends upon this
 * information being correct.
 */
753
void /* PRIVATE */
754
png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
755 756
    int bit_depth, int color_type, int compression_type, int filter_type,
    int interlace_type)
G
Guy Schalnat 已提交
757
{
758
   png_byte buf[13]; /* Buffer to store the IHDR info */
G
Guy Schalnat 已提交
759

760
   png_debug(1, "in png_write_IHDR");
761

G
Guy Schalnat 已提交
762
   /* Check that we have valid input data from the application info */
G
Guy Schalnat 已提交
763 764
   switch (color_type)
   {
A
Andreas Dilger 已提交
765
      case PNG_COLOR_TYPE_GRAY:
G
Guy Schalnat 已提交
766 767 768 769 770 771
         switch (bit_depth)
         {
            case 1:
            case 2:
            case 4:
            case 8:
772
#ifdef PNG_WRITE_16BIT_SUPPORTED
773
            case 16:
774
#endif
775
               png_ptr->channels = 1; break;
776

777 778 779
            default:
               png_error(png_ptr,
                   "Invalid bit depth for grayscale image");
G
Guy Schalnat 已提交
780
         }
G
Guy Schalnat 已提交
781
         break;
782

A
Andreas Dilger 已提交
783
      case PNG_COLOR_TYPE_RGB:
784
#ifdef PNG_WRITE_16BIT_SUPPORTED
G
Guy Schalnat 已提交
785
         if (bit_depth != 8 && bit_depth != 16)
786 787 788
#else
         if (bit_depth != 8)
#endif
G
Guy Schalnat 已提交
789
            png_error(png_ptr, "Invalid bit depth for RGB image");
790

G
Guy Schalnat 已提交
791 792
         png_ptr->channels = 3;
         break;
793

A
Andreas Dilger 已提交
794
      case PNG_COLOR_TYPE_PALETTE:
G
Guy Schalnat 已提交
795 796 797 798 799
         switch (bit_depth)
         {
            case 1:
            case 2:
            case 4:
800 801 802
            case 8:
               png_ptr->channels = 1;
               break;
803

804 805
            default:
               png_error(png_ptr, "Invalid bit depth for paletted image");
G
Guy Schalnat 已提交
806 807
         }
         break;
808

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

G
Guy Schalnat 已提交
813 814
         png_ptr->channels = 2;
         break;
815

A
Andreas Dilger 已提交
816
      case PNG_COLOR_TYPE_RGB_ALPHA:
817
#ifdef PNG_WRITE_16BIT_SUPPORTED
G
Guy Schalnat 已提交
818
         if (bit_depth != 8 && bit_depth != 16)
819 820 821
#else
         if (bit_depth != 8)
#endif
G
Guy Schalnat 已提交
822
            png_error(png_ptr, "Invalid bit depth for RGBA image");
823

G
Guy Schalnat 已提交
824 825
         png_ptr->channels = 4;
         break;
826

G
Guy Schalnat 已提交
827 828 829 830
      default:
         png_error(png_ptr, "Invalid image color type specified");
   }

A
Andreas Dilger 已提交
831
   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
G
Guy Schalnat 已提交
832 833
   {
      png_warning(png_ptr, "Invalid compression type specified");
A
Andreas Dilger 已提交
834
      compression_type = PNG_COMPRESSION_TYPE_BASE;
G
Guy Schalnat 已提交
835 836
   }

837 838 839 840 841 842 843 844 845
   /* 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
    */
846
   if (
847
#ifdef PNG_MNG_FEATURES_SUPPORTED
848 849 850 851 852
       !((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)) &&
853
#endif
854
       filter_type != PNG_FILTER_TYPE_BASE)
G
Guy Schalnat 已提交
855 856
   {
      png_warning(png_ptr, "Invalid filter type specified");
A
Andreas Dilger 已提交
857
      filter_type = PNG_FILTER_TYPE_BASE;
G
Guy Schalnat 已提交
858 859
   }

860
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
A
Andreas Dilger 已提交
861
   if (interlace_type != PNG_INTERLACE_NONE &&
862
       interlace_type != PNG_INTERLACE_ADAM7)
G
Guy Schalnat 已提交
863 864
   {
      png_warning(png_ptr, "Invalid interlace type specified");
A
Andreas Dilger 已提交
865
      interlace_type = PNG_INTERLACE_ADAM7;
G
Guy Schalnat 已提交
866
   }
867 868 869
#else
   interlace_type=PNG_INTERLACE_NONE;
#endif
G
Guy Schalnat 已提交
870

871
   /* Save the relevent information */
G
Guy Schalnat 已提交
872 873 874
   png_ptr->bit_depth = (png_byte)bit_depth;
   png_ptr->color_type = (png_byte)color_type;
   png_ptr->interlaced = (png_byte)interlace_type;
875
#ifdef PNG_MNG_FEATURES_SUPPORTED
876
   png_ptr->filter_type = (png_byte)filter_type;
877
#endif
878
   png_ptr->compression_type = (png_byte)compression_type;
G
Guy Schalnat 已提交
879 880 881
   png_ptr->width = width;
   png_ptr->height = height;

G
Guy Schalnat 已提交
882
   png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
883
   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
884
   /* Set the usr info, so any transformations can modify it */
G
Guy Schalnat 已提交
885 886
   png_ptr->usr_width = png_ptr->width;
   png_ptr->usr_bit_depth = png_ptr->bit_depth;
G
Guy Schalnat 已提交
887 888
   png_ptr->usr_channels = png_ptr->channels;

889
   /* Pack the header information into the buffer */
G
Guy Schalnat 已提交
890 891 892 893 894 895 896
   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 已提交
897

898
   /* Write the chunk */
899
   png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
G
Guy Schalnat 已提交
900

901
   if ((png_ptr->do_filter) == PNG_NO_FILTERS)
G
Guy Schalnat 已提交
902
   {
A
Andreas Dilger 已提交
903
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
904
          png_ptr->bit_depth < 8)
G
Guy Schalnat 已提交
905
         png_ptr->do_filter = PNG_FILTER_NONE;
906

G
Guy Schalnat 已提交
907
      else
G
Guy Schalnat 已提交
908
         png_ptr->do_filter = PNG_ALL_FILTERS;
G
Guy Schalnat 已提交
909
   }
910

911
   png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
G
Guy Schalnat 已提交
912 913
}

914
/* Write the palette.  We are careful not to trust png_color to be in the
915
 * correct order for PNG, so people can redefine it to any convenient
916 917
 * structure.
 */
918
void /* PRIVATE */
919
png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
920
    png_uint_32 num_pal)
G
Guy Schalnat 已提交
921
{
A
Andreas Dilger 已提交
922
   png_uint_32 i;
923
   png_const_colorp pal_ptr;
G
Guy Schalnat 已提交
924 925
   png_byte buf[3];

926
   png_debug(1, "in png_write_PLTE");
927

928
   if ((
929
#ifdef PNG_MNG_FEATURES_SUPPORTED
930
       !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
931
#endif
932
       num_pal == 0) || num_pal > 256)
933
   {
934 935 936 937
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
      {
         png_error(png_ptr, "Invalid number of colors in palette");
      }
938

939 940 941 942 943
      else
      {
         png_warning(png_ptr, "Invalid number of colors in palette");
         return;
      }
944 945 946 947 948
   }

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

951
      return;
G
Guy Schalnat 已提交
952 953
   }

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

957
   png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
958
#ifdef PNG_POINTER_INDEXING_SUPPORTED
959

A
Andreas Dilger 已提交
960
   for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
G
Guy Schalnat 已提交
961 962 963 964
   {
      buf[0] = pal_ptr->red;
      buf[1] = pal_ptr->green;
      buf[2] = pal_ptr->blue;
965
      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
G
Guy Schalnat 已提交
966
   }
967

968
#else
969 970 971
   /* This is a little slower but some buggy compilers need to do this
    * instead
    */
972
   pal_ptr=palette;
973

974 975 976 977 978
   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;
979
      png_write_chunk_data(png_ptr, buf, (png_size_t)3);
980
   }
981

982
#endif
G
Guy Schalnat 已提交
983
   png_write_chunk_end(png_ptr);
G
Guy Schalnat 已提交
984
   png_ptr->mode |= PNG_HAVE_PLTE;
G
Guy Schalnat 已提交
985 986
}

987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003
/* 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.
 */
1004
void /* PRIVATE */
1005 1006
png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
   png_alloc_size_t input_len, int flush)
G
Guy Schalnat 已提交
1007
{
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
   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.
       * 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.
       */
      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;
      }
1021

1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
      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 (;;)
1043
   {
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
      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.
1064
       */
1065 1066 1067 1068
      if (png_ptr->zstream.avail_out == 0)
      {
         png_bytep data = png_ptr->zbuffer_list->output;
         uInt size = png_ptr->zbuffer_size;
1069

1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
         /* 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! */
1097
      {
1098 1099 1100
         /* 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.
1101
          */
1102
         if (input_len == 0)
1103
         {
1104 1105
            if (flush == Z_FINISH)
               png_error(png_ptr, "Z_OK on Z_FINISH with output space");
1106

1107 1108 1109
            return;
         }
      }
1110

1111 1112 1113 1114 1115 1116 1117
      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;
1118

1119 1120 1121 1122 1123
#        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
1124

1125 1126 1127 1128
         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;
1129

1130 1131
         png_ptr->zowner = 0; /* Release the stream */
         return;
1132
      }
1133

1134
      else
1135 1136 1137 1138 1139
      {
         /* This is an error condition. */
         png_zstream_error(png_ptr, ret);
         png_error(png_ptr, png_ptr->zstream.msg);
      }
1140
   }
G
Guy Schalnat 已提交
1141 1142
}

1143
/* Write an IEND chunk */
1144
void /* PRIVATE */
1145
png_write_IEND(png_structrp png_ptr)
G
Guy Schalnat 已提交
1146
{
1147
   png_debug(1, "in png_write_IEND");
1148

1149
   png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
A
Andreas Dilger 已提交
1150
   png_ptr->mode |= PNG_HAVE_IEND;
G
Guy Schalnat 已提交
1151 1152
}

1153
#ifdef PNG_WRITE_gAMA_SUPPORTED
1154
/* Write a gAMA chunk */
1155
void /* PRIVATE */
1156
png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
1157 1158 1159
{
   png_byte buf[4];

1160
   png_debug(1, "in png_write_gAMA");
1161

1162
   /* file_gamma is saved in 1/100,000ths */
1163
   png_save_uint_32(buf, (png_uint_32)file_gamma);
1164
   png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
1165 1166
}
#endif
G
Guy Schalnat 已提交
1167

1168
#ifdef PNG_WRITE_sRGB_SUPPORTED
1169
/* Write a sRGB chunk */
1170
void /* PRIVATE */
1171
png_write_sRGB(png_structrp png_ptr, int srgb_intent)
1172 1173 1174
{
   png_byte buf[1];

1175
   png_debug(1, "in png_write_sRGB");
1176

1177
   if (srgb_intent >= PNG_sRGB_INTENT_LAST)
1178 1179
      png_warning(png_ptr,
          "Invalid sRGB rendering intent specified");
1180

1181
   buf[0]=(png_byte)srgb_intent;
1182
   png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
1183 1184 1185
}
#endif

1186
#ifdef PNG_WRITE_iCCP_SUPPORTED
1187
/* Write an iCCP chunk */
1188
void /* PRIVATE */
1189 1190
png_write_iCCP(png_structrp png_ptr, png_const_charp name,
    png_const_bytep profile)
1191
{
1192 1193 1194
   png_uint_32 name_len;
   png_uint_32 profile_len;
   png_byte new_name[81]; /* 1 byte for the compression byte */
1195
   compression_state comp;
1196
   png_uint_32 temp;
1197

1198
   png_debug(1, "in png_write_iCCP");
1199

1200 1201 1202
   /* These are all internal problems: the profile should have been checked
    * before when it was stored.
    */
1203
   if (profile == NULL)
1204
      png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
1205

1206
   profile_len = png_get_uint_32(profile);
1207

1208 1209
   if (profile_len < 132)
      png_error(png_ptr, "ICC profile too short");
1210

1211 1212
   temp = (png_uint_32) (*(profile+8));
   if (temp > 3 && (profile_len & 0x03))
1213
      png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
1214

1215
   {
1216
      png_uint_32 embedded_profile_len = png_get_uint_32(profile);
1217

1218 1219
      if (profile_len != embedded_profile_len)
         png_error(png_ptr, "Profile length does not match profile");
1220
   }
1221

1222
   name_len = png_check_keyword(png_ptr, name, new_name);
1223

1224 1225
   if (name_len == 0)
      png_error(png_ptr, "iCCP: invalid keyword");
1226

1227
   new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE;
1228

1229
   /* Make sure we include the NULL after the name and the compression type */
1230
   ++name_len;
1231

1232
   png_text_compress_init(&comp, profile, profile_len);
1233

1234 1235 1236
   /* 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);
1237

1238 1239 1240 1241 1242
   png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len);

   png_write_chunk_data(png_ptr, new_name, name_len);

   png_write_compressed_data_out(png_ptr, &comp);
1243 1244 1245 1246 1247

   png_write_chunk_end(png_ptr);
}
#endif

1248
#ifdef PNG_WRITE_sPLT_SUPPORTED
1249
/* Write a sPLT chunk */
1250
void /* PRIVATE */
1251
png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
1252
{
1253 1254
   png_uint_32 name_len;
   png_byte new_name[80];
1255
   png_byte entrybuf[10];
1256 1257
   png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
   png_size_t palette_size = entry_size * spalette->nentries;
1258
   png_sPLT_entryp ep;
1259
#ifndef PNG_POINTER_INDEXING_SUPPORTED
1260 1261
   int i;
#endif
1262

1263
   png_debug(1, "in png_write_sPLT");
1264

1265 1266 1267 1268
   name_len = png_check_keyword(png_ptr, spalette->name, new_name);

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

1270
   /* Make sure we include the NULL after the name */
1271
   png_write_chunk_header(png_ptr, png_sPLT,
1272
       (png_uint_32)(name_len + 2 + palette_size));
1273

1274
   png_write_chunk_data(png_ptr, (png_bytep)new_name,
1275
       (png_size_t)(name_len + 1));
1276

1277
   png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
1278

1279
   /* Loop through each palette entry, writing appropriately */
1280
#ifdef PNG_POINTER_INDEXING_SUPPORTED
1281
   for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
1282
   {
1283 1284
      if (spalette->depth == 8)
      {
1285 1286 1287 1288 1289
         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);
1290
      }
1291

1292 1293
      else
      {
1294 1295 1296 1297 1298
         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);
1299
      }
1300

1301
      png_write_chunk_data(png_ptr, entrybuf, entry_size);
1302
   }
1303 1304
#else
   ep=spalette->entries;
1305
   for (i = 0; i>spalette->nentries; i++)
1306
   {
1307 1308
      if (spalette->depth == 8)
      {
1309 1310 1311 1312 1313
         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);
1314
      }
1315

1316 1317
      else
      {
1318 1319 1320 1321 1322
         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);
1323
      }
1324

1325
      png_write_chunk_data(png_ptr, entrybuf, entry_size);
1326 1327
   }
#endif
1328 1329 1330 1331 1332

   png_write_chunk_end(png_ptr);
}
#endif

1333
#ifdef PNG_WRITE_sBIT_SUPPORTED
1334
/* Write the sBIT chunk */
1335
void /* PRIVATE */
1336
png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
G
Guy Schalnat 已提交
1337 1338
{
   png_byte buf[4];
A
Andreas Dilger 已提交
1339
   png_size_t size;
G
Guy Schalnat 已提交
1340

1341
   png_debug(1, "in png_write_sBIT");
1342

1343
   /* Make sure we don't depend upon the order of PNG_COLOR_8 */
G
Guy Schalnat 已提交
1344 1345
   if (color_type & PNG_COLOR_MASK_COLOR)
   {
1346
      png_byte maxbits;
G
Guy Schalnat 已提交
1347

1348
      maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
1349
          png_ptr->usr_bit_depth);
1350

1351 1352
      if (sbit->red == 0 || sbit->red > maxbits ||
          sbit->green == 0 || sbit->green > maxbits ||
G
Guy Schalnat 已提交
1353 1354 1355 1356 1357
          sbit->blue == 0 || sbit->blue > maxbits)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1358

G
Guy Schalnat 已提交
1359 1360 1361 1362 1363
      buf[0] = sbit->red;
      buf[1] = sbit->green;
      buf[2] = sbit->blue;
      size = 3;
   }
1364

G
Guy Schalnat 已提交
1365 1366
   else
   {
G
Guy Schalnat 已提交
1367 1368 1369 1370 1371
      if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1372

G
Guy Schalnat 已提交
1373 1374 1375 1376 1377 1378
      buf[0] = sbit->gray;
      size = 1;
   }

   if (color_type & PNG_COLOR_MASK_ALPHA)
   {
G
Guy Schalnat 已提交
1379 1380 1381 1382 1383
      if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
      {
         png_warning(png_ptr, "Invalid sBIT depth specified");
         return;
      }
1384

G
Guy Schalnat 已提交
1385 1386 1387
      buf[size++] = sbit->alpha;
   }

1388
   png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
G
Guy Schalnat 已提交
1389
}
G
Guy Schalnat 已提交
1390
#endif
G
Guy Schalnat 已提交
1391

1392
#ifdef PNG_WRITE_cHRM_SUPPORTED
1393
/* Write the cHRM chunk */
1394
void /* PRIVATE */
1395
png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)
1396 1397 1398
{
   png_byte buf[32];

1399
   png_debug(1, "in png_write_cHRM");
1400

1401
   /* Each value is saved in 1/100,000ths */
1402 1403
   png_save_int_32(buf,      xy->whitex);
   png_save_int_32(buf +  4, xy->whitey);
1404

1405 1406
   png_save_int_32(buf +  8, xy->redx);
   png_save_int_32(buf + 12, xy->redy);
1407

1408 1409
   png_save_int_32(buf + 16, xy->greenx);
   png_save_int_32(buf + 20, xy->greeny);
1410

1411 1412
   png_save_int_32(buf + 24, xy->bluex);
   png_save_int_32(buf + 28, xy->bluey);
1413

1414
   png_write_complete_chunk(png_ptr, png_cHRM, buf, 32);
1415 1416
}
#endif
G
Guy Schalnat 已提交
1417

1418
#ifdef PNG_WRITE_tRNS_SUPPORTED
1419
/* Write the tRNS chunk */
1420
void /* PRIVATE */
1421
png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
1422
    png_const_color_16p tran, int num_trans, int color_type)
G
Guy Schalnat 已提交
1423 1424 1425
{
   png_byte buf[6];

1426
   png_debug(1, "in png_write_tRNS");
1427

G
Guy Schalnat 已提交
1428 1429
   if (color_type == PNG_COLOR_TYPE_PALETTE)
   {
1430
      if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
G
Guy Schalnat 已提交
1431
      {
1432 1433
         png_app_warning(png_ptr,
             "Invalid number of transparent colors specified");
G
Guy Schalnat 已提交
1434 1435
         return;
      }
1436

1437
      /* Write the chunk out as it is */
1438 1439
      png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
         (png_size_t)num_trans);
G
Guy Schalnat 已提交
1440
   }
1441

G
Guy Schalnat 已提交
1442 1443
   else if (color_type == PNG_COLOR_TYPE_GRAY)
   {
1444
      /* One 16 bit value */
1445
      if (tran->gray >= (1 << png_ptr->bit_depth))
1446
      {
1447
         png_app_warning(png_ptr,
1448
             "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
1449

1450 1451
         return;
      }
1452

G
Guy Schalnat 已提交
1453
      png_save_uint_16(buf, tran->gray);
1454
      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1455
   }
1456

G
Guy Schalnat 已提交
1457 1458
   else if (color_type == PNG_COLOR_TYPE_RGB)
   {
1459
      /* Three 16 bit values */
G
Guy Schalnat 已提交
1460 1461 1462
      png_save_uint_16(buf, tran->red);
      png_save_uint_16(buf + 2, tran->green);
      png_save_uint_16(buf + 4, tran->blue);
1463
#ifdef PNG_WRITE_16BIT_SUPPORTED
1464
      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1465 1466 1467
#else
      if (buf[0] | buf[2] | buf[4])
#endif
1468
      {
1469
         png_app_warning(png_ptr,
1470
           "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
1471 1472
         return;
      }
1473

1474
      png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
G
Guy Schalnat 已提交
1475
   }
1476

G
Guy Schalnat 已提交
1477 1478
   else
   {
1479
      png_app_warning(png_ptr, "Can't write tRNS with an alpha channel");
G
Guy Schalnat 已提交
1480
   }
G
Guy Schalnat 已提交
1481
}
G
Guy Schalnat 已提交
1482
#endif
G
Guy Schalnat 已提交
1483

1484
#ifdef PNG_WRITE_bKGD_SUPPORTED
1485
/* Write the background chunk */
1486
void /* PRIVATE */
1487
png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
G
Guy Schalnat 已提交
1488 1489 1490
{
   png_byte buf[6];

1491
   png_debug(1, "in png_write_bKGD");
1492

G
Guy Schalnat 已提交
1493 1494
   if (color_type == PNG_COLOR_TYPE_PALETTE)
   {
1495
      if (
1496
#ifdef PNG_MNG_FEATURES_SUPPORTED
1497 1498
          (png_ptr->num_palette ||
          (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
1499
#endif
1500
         back->index >= png_ptr->num_palette)
G
Guy Schalnat 已提交
1501 1502 1503 1504
      {
         png_warning(png_ptr, "Invalid background palette index");
         return;
      }
1505

G
Guy Schalnat 已提交
1506
      buf[0] = back->index;
1507
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
G
Guy Schalnat 已提交
1508
   }
1509

G
Guy Schalnat 已提交
1510 1511 1512 1513 1514
   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);
1515
#ifdef PNG_WRITE_16BIT_SUPPORTED
1516
      if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
1517 1518 1519
#else
      if (buf[0] | buf[2] | buf[4])
#endif
1520 1521
      {
         png_warning(png_ptr,
1522
             "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
1523

1524 1525
         return;
      }
1526

1527
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
G
Guy Schalnat 已提交
1528
   }
1529

G
Guy Schalnat 已提交
1530
   else
G
Guy Schalnat 已提交
1531
   {
1532
      if (back->gray >= (1 << png_ptr->bit_depth))
1533 1534
      {
         png_warning(png_ptr,
1535
             "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
1536

1537 1538
         return;
      }
1539

G
Guy Schalnat 已提交
1540
      png_save_uint_16(buf, back->gray);
1541
      png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1542 1543
   }
}
G
Guy Schalnat 已提交
1544
#endif
G
Guy Schalnat 已提交
1545

1546
#ifdef PNG_WRITE_hIST_SUPPORTED
1547
/* Write the histogram */
1548
void /* PRIVATE */
1549
png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
G
Guy Schalnat 已提交
1550
{
1551
   int i;
G
Guy Schalnat 已提交
1552 1553
   png_byte buf[3];

1554
   png_debug(1, "in png_write_hIST");
1555

1556
   if (num_hist > (int)png_ptr->num_palette)
G
Guy Schalnat 已提交
1557
   {
1558
      png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
1559
          png_ptr->num_palette);
1560

G
Guy Schalnat 已提交
1561 1562 1563 1564
      png_warning(png_ptr, "Invalid number of histogram entries specified");
      return;
   }

1565
   png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
1566

A
Andreas Dilger 已提交
1567
   for (i = 0; i < num_hist; i++)
G
Guy Schalnat 已提交
1568
   {
G
Guy Schalnat 已提交
1569
      png_save_uint_16(buf, hist[i]);
1570
      png_write_chunk_data(png_ptr, buf, (png_size_t)2);
G
Guy Schalnat 已提交
1571
   }
1572

G
Guy Schalnat 已提交
1573 1574
   png_write_chunk_end(png_ptr);
}
G
Guy Schalnat 已提交
1575
#endif
G
Guy Schalnat 已提交
1576

1577
#ifdef PNG_WRITE_tEXt_SUPPORTED
1578
/* Write a tEXt chunk */
1579
void /* PRIVATE */
1580
png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
1581
    png_size_t text_len)
G
Guy Schalnat 已提交
1582
{
1583 1584
   png_uint_32 key_len;
   png_byte new_key[80];
A
Andreas Dilger 已提交
1585

1586
   png_debug(1, "in png_write_tEXt");
1587

1588 1589 1590 1591
   key_len = png_check_keyword(png_ptr, key, new_key);

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

A
Andreas Dilger 已提交
1593
   if (text == NULL || *text == '\0')
A
Andreas Dilger 已提交
1594
      text_len = 0;
1595

1596
   else
1597 1598 1599 1600
      text_len = strlen(text);

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

1602
   /* Make sure we include the 0 after the key */
1603
   png_write_chunk_header(png_ptr, png_tEXt,
1604
       (png_uint_32)/*checked above*/(key_len + text_len + 1));
1605 1606 1607 1608
   /*
    * 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.
1609
    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1610
    */
1611
   png_write_chunk_data(png_ptr, new_key, key_len + 1);
1612

1613
   if (text_len != 0)
1614
      png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);
A
Andreas Dilger 已提交
1615

G
Guy Schalnat 已提交
1616 1617
   png_write_chunk_end(png_ptr);
}
G
Guy Schalnat 已提交
1618
#endif
G
Guy Schalnat 已提交
1619

1620
#ifdef PNG_WRITE_zTXt_SUPPORTED
1621
/* Write a compressed text chunk */
1622
void /* PRIVATE */
1623
png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
1624
    png_size_t text_len, int compression)
G
Guy Schalnat 已提交
1625
{
1626 1627
   png_uint_32 key_len;
   png_byte new_key[81];
1628
   compression_state comp;
G
Guy Schalnat 已提交
1629

1630
   png_debug(1, "in png_write_zTXt");
1631
   PNG_UNUSED(text_len) /* Always use strlen */
A
Andreas Dilger 已提交
1632

1633
   if (compression == PNG_TEXT_COMPRESSION_NONE)
A
Andreas Dilger 已提交
1634
   {
1635
      png_write_tEXt(png_ptr, key, text, 0);
G
Guy Schalnat 已提交
1636
      return;
A
Andreas Dilger 已提交
1637
   }
A
Andreas Dilger 已提交
1638

1639 1640
   if (compression != PNG_TEXT_COMPRESSION_zTXt)
      png_error(png_ptr, "zTXt: invalid compression type");
G
Guy Schalnat 已提交
1641

1642
   key_len = png_check_keyword(png_ptr, key, new_key);
1643

1644 1645
   if (key_len == 0)
      png_error(png_ptr, "zTXt: invalid keyword");
1646

1647 1648 1649
   /* Add the compression method and 1 for the keyword separator. */
   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
   ++key_len;
1650

1651 1652 1653
   /* Compute the compressed data; do it now for the length */
   png_text_compress_init(&comp, (png_const_bytep)text,
      text == NULL ? 0 : strlen(text));
1654

1655 1656
   if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
      png_error(png_ptr, png_ptr->zstream.msg);
1657

1658 1659
   /* Write start of chunk */
   png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len);
1660

1661 1662
   /* Write key */
   png_write_chunk_data(png_ptr, new_key, key_len);
1663

1664
   /* Write the compressed data */
1665
   png_write_compressed_data_out(png_ptr, &comp);
G
Guy Schalnat 已提交
1666

1667
   /* Close the chunk */
1668 1669 1670
   png_write_chunk_end(png_ptr);
}
#endif
G
Guy Schalnat 已提交
1671

1672
#ifdef PNG_WRITE_iTXt_SUPPORTED
1673
/* Write an iTXt chunk */
1674
void /* PRIVATE */
1675
png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
1676
    png_const_charp lang, png_const_charp lang_key, png_const_charp text)
1677
{
1678 1679 1680
   png_uint_32 key_len, prefix_len;
   png_size_t lang_len, lang_key_len;
   png_byte new_key[82];
1681
   compression_state comp;
G
Guy Schalnat 已提交
1682

1683
   png_debug(1, "in png_write_iTXt");
G
Guy Schalnat 已提交
1684

1685
   key_len = png_check_keyword(png_ptr, key, new_key);
1686

1687 1688
   if (key_len == 0)
      png_error(png_ptr, "iTXt: invalid keyword");
1689

1690 1691
   /* Set the compression flag */
   switch (compression)
1692
   {
1693 1694 1695 1696
      case PNG_ITXT_COMPRESSION_NONE:
      case PNG_TEXT_COMPRESSION_NONE:
         compression = new_key[++key_len] = 0; /* no compression */
         break;
1697

1698 1699 1700 1701
      case PNG_TEXT_COMPRESSION_zTXt:
      case PNG_ITXT_COMPRESSION_zTXt:
         compression = new_key[++key_len] = 1; /* compressed */
         break;
1702

1703 1704 1705
      default:
         png_error(png_ptr, "iTXt: invalid compression");
   }
1706

1707 1708
   new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
   ++key_len; /* for the keywod separator */
1709

1710 1711
   /* 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
1712 1713 1714 1715
    * 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.
    *
1716
    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
1717 1718
    *
    * TODO: validate the language tag correctly (see the spec.)
1719
    */
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730
   if (lang == NULL) lang = ""; /* empty language is valid */
   lang_len = strlen(lang)+1;
   if (lang_key == NULL) lang_key = ""; /* may be empty */
   lang_key_len = strlen(lang_key)+1;
   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);
1731

1732 1733 1734 1735
   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);
G
Guy Schalnat 已提交
1736

1737
   png_text_compress_init(&comp, (png_const_bytep)text, strlen(text));
1738

1739
   if (compression != 0)
1740 1741 1742 1743
   {
      if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)
         png_error(png_ptr, png_ptr->zstream.msg);
   }
1744

1745 1746 1747 1748
   else
   {
      if (comp.input_len > PNG_UINT_31_MAX-prefix_len)
         png_error(png_ptr, "iTXt: uncompressed text too long");
1749 1750 1751

      /* So the string will fit in a chunk: */
      comp.output_len = (png_uint_32)/*SAFE*/comp.input_len;
1752
   }
1753

1754 1755
   png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len);

1756
   png_write_chunk_data(png_ptr, new_key, key_len);
1757

1758
   png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len);
1759

1760
   png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);
1761

1762
   if (compression != 0)
1763 1764 1765 1766 1767 1768
      png_write_compressed_data_out(png_ptr, &comp);

   else
      png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len);

   png_write_chunk_end(png_ptr);
G
Guy Schalnat 已提交
1769
}
G
Guy Schalnat 已提交
1770
#endif
G
Guy Schalnat 已提交
1771

1772
#ifdef PNG_WRITE_oFFs_SUPPORTED
1773
/* Write the oFFs chunk */
1774
void /* PRIVATE */
1775
png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
1776
    int unit_type)
G
Guy Schalnat 已提交
1777 1778 1779
{
   png_byte buf[9];

1780
   png_debug(1, "in png_write_oFFs");
1781

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

1785 1786
   png_save_int_32(buf, x_offset);
   png_save_int_32(buf + 4, y_offset);
G
Guy Schalnat 已提交
1787
   buf[8] = (png_byte)unit_type;
G
Guy Schalnat 已提交
1788

1789
   png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
G
Guy Schalnat 已提交
1790
}
G
Guy Schalnat 已提交
1791
#endif
1792
#ifdef PNG_WRITE_pCAL_SUPPORTED
1793
/* Write the pCAL chunk (described in the PNG extensions document) */
1794
void /* PRIVATE */
1795
png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
1796 1797
    png_int_32 X1, int type, int nparams, png_const_charp units,
    png_charpp params)
A
Andreas Dilger 已提交
1798
{
1799 1800
   png_uint_32 purpose_len;
   png_size_t units_len, total_len;
1801
   png_size_tp params_len;
A
Andreas Dilger 已提交
1802
   png_byte buf[10];
1803
   png_byte new_purpose[80];
A
Andreas Dilger 已提交
1804 1805
   int i;

1806
   png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
1807

A
Andreas Dilger 已提交
1808
   if (type >= PNG_EQUATION_LAST)
1809 1810 1811 1812 1813 1814 1815 1816
      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 已提交
1817

1818
   png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
1819
   units_len = strlen(units) + (nparams == 0 ? 0 : 1);
1820
   png_debug1(3, "pCAL units length = %d", (int)units_len);
A
Andreas Dilger 已提交
1821 1822
   total_len = purpose_len + units_len + 10;

1823
   params_len = (png_size_tp)png_malloc(png_ptr,
1824
       (png_alloc_size_t)(nparams * (sizeof (png_size_t))));
A
Andreas Dilger 已提交
1825 1826

   /* Find the length of each parameter, making sure we don't count the
1827 1828
    * null terminator for the last parameter.
    */
A
Andreas Dilger 已提交
1829 1830
   for (i = 0; i < nparams; i++)
   {
1831
      params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
1832
      png_debug2(3, "pCAL parameter %d length = %lu", i,
1833
          (unsigned long)params_len[i]);
1834
      total_len += params_len[i];
A
Andreas Dilger 已提交
1835 1836
   }

1837
   png_debug1(3, "pCAL total length = %d", (int)total_len);
1838
   png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
1839
   png_write_chunk_data(png_ptr, new_purpose, purpose_len);
A
Andreas Dilger 已提交
1840 1841 1842 1843
   png_save_int_32(buf, X0);
   png_save_int_32(buf + 4, X1);
   buf[8] = (png_byte)type;
   buf[9] = (png_byte)nparams;
1844
   png_write_chunk_data(png_ptr, buf, (png_size_t)10);
1845
   png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
A
Andreas Dilger 已提交
1846 1847 1848

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

1852
   png_free(png_ptr, params_len);
A
Andreas Dilger 已提交
1853 1854 1855 1856
   png_write_chunk_end(png_ptr);
}
#endif

1857
#ifdef PNG_WRITE_sCAL_SUPPORTED
1858
/* Write the sCAL chunk */
1859
void /* PRIVATE */
1860
png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
1861
    png_const_charp height)
1862
{
1863 1864
   png_byte buf[64];
   png_size_t wlen, hlen, total_len;
1865

1866
   png_debug(1, "in png_write_sCAL_s");
1867

1868 1869
   wlen = strlen(width);
   hlen = strlen(height);
1870
   total_len = wlen + hlen + 2;
1871

1872 1873 1874 1875 1876
   if (total_len > 64)
   {
      png_warning(png_ptr, "Can't write sCAL (buffer too small)");
      return;
   }
1877

1878
   buf[0] = (png_byte)unit;
1879 1880
   memcpy(buf + 1, width, wlen + 1);      /* Append the '\0' here */
   memcpy(buf + wlen + 2, height, hlen);  /* Do NOT append the '\0' here */
1881

1882
   png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
1883
   png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
1884 1885 1886
}
#endif

1887
#ifdef PNG_WRITE_pHYs_SUPPORTED
1888
/* Write the pHYs chunk */
1889
void /* PRIVATE */
1890
png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
1891 1892
    png_uint_32 y_pixels_per_unit,
    int unit_type)
G
Guy Schalnat 已提交
1893 1894 1895
{
   png_byte buf[9];

1896
   png_debug(1, "in png_write_pHYs");
1897

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

A
Andreas Dilger 已提交
1901 1902
   png_save_uint_32(buf, x_pixels_per_unit);
   png_save_uint_32(buf + 4, y_pixels_per_unit);
G
Guy Schalnat 已提交
1903
   buf[8] = (png_byte)unit_type;
G
Guy Schalnat 已提交
1904

1905
   png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
G
Guy Schalnat 已提交
1906
}
G
Guy Schalnat 已提交
1907
#endif
G
Guy Schalnat 已提交
1908

1909
#ifdef PNG_WRITE_tIME_SUPPORTED
1910 1911 1912
/* Write the tIME chunk.  Use either png_convert_from_struct_tm()
 * or png_convert_from_time_t(), or fill in the structure yourself.
 */
1913
void /* PRIVATE */
1914
png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
G
Guy Schalnat 已提交
1915 1916 1917
{
   png_byte buf[7];

1918
   png_debug(1, "in png_write_tIME");
1919

G
Guy Schalnat 已提交
1920 1921 1922 1923 1924 1925 1926 1927
   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 已提交
1928 1929 1930 1931 1932 1933 1934
   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;

1935
   png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
G
Guy Schalnat 已提交
1936
}
G
Guy Schalnat 已提交
1937
#endif
G
Guy Schalnat 已提交
1938

1939
/* Initializes the row writing capability of libpng */
1940
void /* PRIVATE */
1941
png_write_start_row(png_structrp png_ptr)
G
Guy Schalnat 已提交
1942
{
1943
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1944
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1945

1946
   /* Start of interlace block */
1947
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
1948

1949
   /* Offset to next interlace block */
1950
   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
1951

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

1955
   /* Offset to next interlace block in the y direction */
1956
   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
1957
#endif
1958

1959 1960
   png_alloc_size_t buf_size;
   int usr_pixel_depth;
A
Andreas Dilger 已提交
1961

1962
   png_debug(1, "in png_write_start_row");
1963

1964 1965 1966 1967 1968 1969
   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 已提交
1970

1971
   /* Set up row buffer */
1972
   png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
1973

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

1976
#ifdef PNG_WRITE_FILTER_SUPPORTED
1977
   /* Set up filtering buffer, if using this filter */
G
Guy Schalnat 已提交
1978
   if (png_ptr->do_filter & PNG_FILTER_SUB)
G
Guy Schalnat 已提交
1979
   {
1980
      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
1981

A
Andreas Dilger 已提交
1982
      png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
G
Guy Schalnat 已提交
1983 1984
   }

A
Andreas Dilger 已提交
1985
   /* We only need to keep the previous row if we are using one of these. */
G
Guy Schalnat 已提交
1986 1987
   if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
   {
1988
      /* Set up previous row buffer */
1989
      png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
G
Guy Schalnat 已提交
1990 1991 1992

      if (png_ptr->do_filter & PNG_FILTER_UP)
      {
1993
         png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
1994
            png_ptr->rowbytes + 1);
1995

A
Andreas Dilger 已提交
1996
         png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
G
Guy Schalnat 已提交
1997 1998 1999 2000
      }

      if (png_ptr->do_filter & PNG_FILTER_AVG)
      {
2001
         png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
2002
             png_ptr->rowbytes + 1);
2003

A
Andreas Dilger 已提交
2004
         png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
G
Guy Schalnat 已提交
2005 2006 2007 2008
      }

      if (png_ptr->do_filter & PNG_FILTER_PAETH)
      {
2009
         png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
2010
             png_ptr->rowbytes + 1);
2011

A
Andreas Dilger 已提交
2012
         png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
G
Guy Schalnat 已提交
2013
      }
G
Guy Schalnat 已提交
2014
   }
2015
#endif /* PNG_WRITE_FILTER_SUPPORTED */
G
Guy Schalnat 已提交
2016

2017
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2018
   /* If interlaced, we need to set up width and height of pass */
G
Guy Schalnat 已提交
2019
   if (png_ptr->interlaced)
G
Guy Schalnat 已提交
2020 2021 2022 2023
   {
      if (!(png_ptr->transformations & PNG_INTERLACE))
      {
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2024
             png_pass_ystart[0]) / png_pass_yinc[0];
2025

A
Andreas Dilger 已提交
2026
         png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
2027
             png_pass_start[0]) / png_pass_inc[0];
G
Guy Schalnat 已提交
2028
      }
2029

G
Guy Schalnat 已提交
2030 2031 2032 2033 2034 2035
      else
      {
         png_ptr->num_rows = png_ptr->height;
         png_ptr->usr_width = png_ptr->width;
      }
   }
2036

G
Guy Schalnat 已提交
2037
   else
2038
#endif
G
Guy Schalnat 已提交
2039
   {
G
Guy Schalnat 已提交
2040 2041 2042 2043 2044
      png_ptr->num_rows = png_ptr->height;
      png_ptr->usr_width = png_ptr->width;
   }
}

A
Andreas Dilger 已提交
2045
/* Internal use only.  Called when finished processing a row of data. */
2046
void /* PRIVATE */
2047
png_write_finish_row(png_structrp png_ptr)
G
Guy Schalnat 已提交
2048
{
2049
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2050
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2051

2052
   /* Start of interlace block */
2053
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2054

2055
   /* Offset to next interlace block */
2056
   static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2057

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

2061
   /* Offset to next interlace block in the y direction */
2062
   static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2063
#endif
2064

2065
   png_debug(1, "in png_write_finish_row");
2066

2067
   /* Next row */
G
Guy Schalnat 已提交
2068
   png_ptr->row_number++;
G
Guy Schalnat 已提交
2069

2070
   /* See if we are done */
G
Guy Schalnat 已提交
2071
   if (png_ptr->row_number < png_ptr->num_rows)
G
Guy Schalnat 已提交
2072
      return;
G
Guy Schalnat 已提交
2073

2074
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2075
   /* If interlaced, go to next pass */
G
Guy Schalnat 已提交
2076 2077 2078 2079 2080 2081 2082
   if (png_ptr->interlaced)
   {
      png_ptr->row_number = 0;
      if (png_ptr->transformations & PNG_INTERLACE)
      {
         png_ptr->pass++;
      }
2083

G
Guy Schalnat 已提交
2084 2085
      else
      {
2086
         /* Loop until we find a non-zero width or height pass */
G
Guy Schalnat 已提交
2087 2088 2089
         do
         {
            png_ptr->pass++;
2090

G
Guy Schalnat 已提交
2091 2092
            if (png_ptr->pass >= 7)
               break;
2093

G
Guy Schalnat 已提交
2094
            png_ptr->usr_width = (png_ptr->width +
2095 2096 2097
                png_pass_inc[png_ptr->pass] - 1 -
                png_pass_start[png_ptr->pass]) /
                png_pass_inc[png_ptr->pass];
2098

G
Guy Schalnat 已提交
2099
            png_ptr->num_rows = (png_ptr->height +
2100 2101 2102
                png_pass_yinc[png_ptr->pass] - 1 -
                png_pass_ystart[png_ptr->pass]) /
                png_pass_yinc[png_ptr->pass];
2103

G
Guy Schalnat 已提交
2104 2105
            if (png_ptr->transformations & PNG_INTERLACE)
               break;
2106

G
Guy Schalnat 已提交
2107 2108 2109 2110
         } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);

      }

2111
      /* Reset the row above the image for the next pass */
G
Guy Schalnat 已提交
2112
      if (png_ptr->pass < 7)
G
Guy Schalnat 已提交
2113
      {
A
Andreas Dilger 已提交
2114
         if (png_ptr->prev_row != NULL)
2115
            memset(png_ptr->prev_row, 0,
2116 2117
                (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
                png_ptr->usr_bit_depth, png_ptr->width)) + 1);
2118

G
Guy Schalnat 已提交
2119
         return;
G
Guy Schalnat 已提交
2120
      }
G
Guy Schalnat 已提交
2121
   }
2122
#endif
G
Guy Schalnat 已提交
2123

2124
   /* If we get here, we've just written the last row, so we need
G
Guy Schalnat 已提交
2125
      to flush the compressor */
2126
   png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH);
G
Guy Schalnat 已提交
2127 2128
}

2129
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
2130 2131 2132 2133 2134 2135 2136
/* 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.
 */
2137
void /* PRIVATE */
G
Guy Schalnat 已提交
2138
png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
G
Guy Schalnat 已提交
2139
{
2140
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2141

2142
   /* Start of interlace block */
2143
   static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2144

2145
   /* Offset to next interlace block */
2146
   static PNG_CONST png_byte  png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2147

2148
   png_debug(1, "in png_do_write_interlace");
2149

2150
   /* We don't have to do anything on the last pass (6) */
A
Andreas Dilger 已提交
2151
   if (pass < 6)
G
Guy Schalnat 已提交
2152
   {
2153
      /* Each pixel depth is handled separately */
G
Guy Schalnat 已提交
2154
      switch (row_info->pixel_depth)
G
Guy Schalnat 已提交
2155
      {
G
Guy Schalnat 已提交
2156 2157
         case 1:
         {
G
Guy Schalnat 已提交
2158 2159
            png_bytep sp;
            png_bytep dp;
G
Guy Schalnat 已提交
2160 2161 2162
            int shift;
            int d;
            int value;
2163 2164
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2165 2166 2167 2168

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

2170
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2171 2172 2173
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 3);
2174
               value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
G
Guy Schalnat 已提交
2175 2176 2177 2178 2179
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 7;
G
Guy Schalnat 已提交
2180
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2181 2182
                  d = 0;
               }
2183

G
Guy Schalnat 已提交
2184 2185 2186 2187 2188
               else
                  shift--;

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

G
Guy Schalnat 已提交
2191 2192
            break;
         }
2193

G
Guy Schalnat 已提交
2194
         case 2:
G
Guy Schalnat 已提交
2195
         {
G
Guy Schalnat 已提交
2196 2197
            png_bytep sp;
            png_bytep dp;
G
Guy Schalnat 已提交
2198 2199 2200
            int shift;
            int d;
            int value;
2201 2202
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2203 2204 2205 2206

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

2208
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2209 2210 2211
               i += png_pass_inc[pass])
            {
               sp = row + (png_size_t)(i >> 2);
2212
               value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
G
Guy Schalnat 已提交
2213 2214 2215 2216 2217
               d |= (value << shift);

               if (shift == 0)
               {
                  shift = 6;
G
Guy Schalnat 已提交
2218
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2219 2220
                  d = 0;
               }
2221

G
Guy Schalnat 已提交
2222 2223 2224 2225
               else
                  shift -= 2;
            }
            if (shift != 6)
2226 2227
               *dp = (png_byte)d;

G
Guy Schalnat 已提交
2228 2229
            break;
         }
2230

G
Guy Schalnat 已提交
2231 2232
         case 4:
         {
G
Guy Schalnat 已提交
2233 2234
            png_bytep sp;
            png_bytep dp;
G
Guy Schalnat 已提交
2235
            int shift;
G
Guy Schalnat 已提交
2236 2237
            int d;
            int value;
2238 2239
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
G
Guy Schalnat 已提交
2240 2241 2242 2243

            dp = row;
            shift = 4;
            d = 0;
2244
            for (i = png_pass_start[pass]; i < row_width;
2245
                i += png_pass_inc[pass])
G
Guy Schalnat 已提交
2246 2247
            {
               sp = row + (png_size_t)(i >> 1);
2248
               value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
G
Guy Schalnat 已提交
2249 2250 2251 2252
               d |= (value << shift);

               if (shift == 0)
               {
G
Guy Schalnat 已提交
2253 2254
                  shift = 4;
                  *dp++ = (png_byte)d;
G
Guy Schalnat 已提交
2255 2256
                  d = 0;
               }
2257

G
Guy Schalnat 已提交
2258 2259 2260 2261
               else
                  shift -= 4;
            }
            if (shift != 4)
G
Guy Schalnat 已提交
2262
               *dp = (png_byte)d;
2263

G
Guy Schalnat 已提交
2264 2265
            break;
         }
2266

G
Guy Schalnat 已提交
2267 2268
         default:
         {
G
Guy Schalnat 已提交
2269 2270
            png_bytep sp;
            png_bytep dp;
2271 2272
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;
A
Andreas Dilger 已提交
2273
            png_size_t pixel_bytes;
G
Guy Schalnat 已提交
2274

2275
            /* Start at the beginning */
G
Guy Schalnat 已提交
2276
            dp = row;
2277

2278
            /* Find out how many bytes each pixel takes up */
G
Guy Schalnat 已提交
2279
            pixel_bytes = (row_info->pixel_depth >> 3);
2280 2281

            /* Loop through the row, only looking at the pixels that matter */
2282
            for (i = png_pass_start[pass]; i < row_width;
G
Guy Schalnat 已提交
2283 2284
               i += png_pass_inc[pass])
            {
2285
               /* Find out where the original pixel is */
2286
               sp = row + (png_size_t)i * pixel_bytes;
2287

2288
               /* Move the pixel */
G
Guy Schalnat 已提交
2289
               if (dp != sp)
2290
                  memcpy(dp, sp, pixel_bytes);
2291

2292
               /* Next pixel */
G
Guy Schalnat 已提交
2293 2294
               dp += pixel_bytes;
            }
G
Guy Schalnat 已提交
2295
            break;
G
Guy Schalnat 已提交
2296 2297
         }
      }
2298
      /* Set new row width */
G
Guy Schalnat 已提交
2299
      row_info->width = (row_info->width +
2300 2301 2302
          png_pass_inc[pass] - 1 -
          png_pass_start[pass]) /
          png_pass_inc[pass];
2303

2304 2305
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
          row_info->width);
G
Guy Schalnat 已提交
2306 2307
   }
}
G
Guy Schalnat 已提交
2308
#endif
G
Guy Schalnat 已提交
2309

A
Andreas Dilger 已提交
2310 2311
/* 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
2312 2313
 * chosen filter.
 */
2314 2315
static void
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
2316
   png_size_t row_bytes);
2317

2318
#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
A
Andreas Dilger 已提交
2319
#define PNG_HISHIFT 10
2320 2321
#define PNG_LOMASK ((png_uint_32)0xffffL)
#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
2322
void /* PRIVATE */
2323
png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
G
Guy Schalnat 已提交
2324
{
2325
   png_bytep best_row;
2326
#ifdef PNG_WRITE_FILTER_SUPPORTED
2327
   png_bytep prev_row, row_buf;
A
Andreas Dilger 已提交
2328
   png_uint_32 mins, bpp;
2329
   png_byte filter_to_do = png_ptr->do_filter;
2330
   png_size_t row_bytes = row_info->rowbytes;
2331
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2332
   int num_p_filters = png_ptr->num_prev_filters;
2333
#endif
2334 2335 2336 2337

   png_debug(1, "in png_write_find_filter");

#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2338
  if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
2339
  {
2340 2341
     /* These will never be selected so we need not test them. */
     filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
2342
  }
2343
#endif
G
Guy Schalnat 已提交
2344

2345
   /* Find out how many bytes offset each pixel is */
2346
   bpp = (row_info->pixel_depth + 7) >> 3;
G
Guy Schalnat 已提交
2347 2348

   prev_row = png_ptr->prev_row;
2349 2350
#endif
   best_row = png_ptr->row_buf;
2351
#ifdef PNG_WRITE_FILTER_SUPPORTED
2352
   row_buf = best_row;
A
Andreas Dilger 已提交
2353 2354 2355 2356
   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
2357
    * from zero, using anything >= 128 as negative numbers.  This is known
A
Andreas Dilger 已提交
2358
    * as the "minimum sum of absolute differences" heuristic.  Other
2359
    * heuristics are the "weighted minimum sum of absolute differences"
A
Andreas Dilger 已提交
2360
    * (experimental and can in theory improve compression), and the "zlib
2361 2362 2363
    * 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 已提交
2364
    * computationally expensive).
2365 2366
    *
    * GRR 980525:  consider also
2367
    *
2368 2369 2370
    *   (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?]
2371
    *
2372 2373
    *  (1b) minimum sum of absolute differences from sliding average, probably
    *       with window size <= deflate window (usually 32K)
2374
    *
2375 2376
    *   (2) minimum sum of squared differences from zero or running average
    *       (i.e., ~ root-mean-square approach)
A
Andreas Dilger 已提交
2377
    */
G
Guy Schalnat 已提交
2378

2379

G
Guy Schalnat 已提交
2380
   /* We don't need to test the 'no filter' case if this is the only filter
A
Andreas Dilger 已提交
2381 2382
    * that has been chosen, as it doesn't actually do anything to the data.
    */
2383
   if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE)
G
Guy Schalnat 已提交
2384
   {
G
Guy Schalnat 已提交
2385 2386
      png_bytep rp;
      png_uint_32 sum = 0;
2387
      png_size_t i;
A
Andreas Dilger 已提交
2388
      int v;
G
Guy Schalnat 已提交
2389

2390
      for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
G
Guy Schalnat 已提交
2391 2392 2393 2394
      {
         v = *rp;
         sum += (v < 128) ? v : 256 - v;
      }
A
Andreas Dilger 已提交
2395

2396
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2397 2398 2399
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
         png_uint_32 sumhi, sumlo;
2400
         int j;
A
Andreas Dilger 已提交
2401 2402 2403 2404
         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 */
2405
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2406
         {
2407
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
A
Andreas Dilger 已提交
2408
            {
2409
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2410
                   PNG_WEIGHT_SHIFT;
2411

2412
               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2413
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2414 2415 2416 2417 2418 2419 2420 2421
            }
         }

         /* 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]) >>
2422
             PNG_COST_SHIFT;
2423

A
Andreas Dilger 已提交
2424
         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
2425
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2426 2427 2428

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2429

A
Andreas Dilger 已提交
2430 2431 2432 2433
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
      }
#endif
G
Guy Schalnat 已提交
2434 2435
      mins = sum;
   }
G
Guy Schalnat 已提交
2436

2437
   /* Sub filter */
2438
   if (filter_to_do == PNG_FILTER_SUB)
2439
   /* It's the only filter so no testing is needed */
2440 2441
   {
      png_bytep rp, lp, dp;
2442
      png_size_t i;
2443

2444 2445 2446 2447 2448
      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
           i++, rp++, dp++)
      {
         *dp = *rp;
      }
2449

2450
      for (lp = row_buf + 1; i < row_bytes;
2451 2452 2453 2454
         i++, rp++, lp++, dp++)
      {
         *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
      }
2455

2456 2457 2458 2459
      best_row = png_ptr->sub_row;
   }

   else if (filter_to_do & PNG_FILTER_SUB)
G
Guy Schalnat 已提交
2460 2461
   {
      png_bytep rp, dp, lp;
A
Andreas Dilger 已提交
2462
      png_uint_32 sum = 0, lmins = mins;
2463
      png_size_t i;
A
Andreas Dilger 已提交
2464 2465
      int v;

2466
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
2467
      /* We temporarily increase the "minimum sum" by the factor we
A
Andreas Dilger 已提交
2468 2469 2470 2471 2472
       * 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)
      {
2473
         int j;
A
Andreas Dilger 已提交
2474 2475 2476 2477
         png_uint_32 lmhi, lmlo;
         lmlo = lmins & PNG_LOMASK;
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;

2478
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2479
         {
2480
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
A
Andreas Dilger 已提交
2481
            {
2482
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2483
                   PNG_WEIGHT_SHIFT;
2484

2485
               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2486
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2487 2488 2489 2490
            }
         }

         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2491
             PNG_COST_SHIFT;
2492

A
Andreas Dilger 已提交
2493
         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2494
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2495 2496 2497

         if (lmhi > PNG_HIMASK)
            lmins = PNG_MAXSUM;
2498

A
Andreas Dilger 已提交
2499 2500 2501 2502
         else
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
      }
#endif
G
Guy Schalnat 已提交
2503

G
Guy Schalnat 已提交
2504 2505 2506 2507
      for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
           i++, rp++, dp++)
      {
         v = *dp = *rp;
G
Guy Schalnat 已提交
2508

G
Guy Schalnat 已提交
2509 2510
         sum += (v < 128) ? v : 256 - v;
      }
2511

2512
      for (lp = row_buf + 1; i < row_bytes;
2513
         i++, rp++, lp++, dp++)
G
Guy Schalnat 已提交
2514 2515 2516 2517
      {
         v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);

         sum += (v < 128) ? v : 256 - v;
A
Andreas Dilger 已提交
2518 2519 2520 2521 2522

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

2523
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2524 2525
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2526
         int j;
A
Andreas Dilger 已提交
2527 2528 2529 2530
         png_uint_32 sumhi, sumlo;
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;

2531
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2532
         {
2533
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
A
Andreas Dilger 已提交
2534
            {
2535
               sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
2536
                   PNG_WEIGHT_SHIFT;
2537

2538
               sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
2539
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2540 2541 2542 2543
            }
         }

         sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2544
             PNG_COST_SHIFT;
2545

A
Andreas Dilger 已提交
2546
         sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
2547
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2548 2549 2550

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2551

A
Andreas Dilger 已提交
2552 2553
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
G
Guy Schalnat 已提交
2554
      }
A
Andreas Dilger 已提交
2555 2556
#endif

G
Guy Schalnat 已提交
2557 2558 2559 2560 2561
      if (sum < mins)
      {
         mins = sum;
         best_row = png_ptr->sub_row;
      }
G
Guy Schalnat 已提交
2562 2563
   }

2564
   /* Up filter */
2565 2566 2567
   if (filter_to_do == PNG_FILTER_UP)
   {
      png_bytep rp, dp, pp;
2568
      png_size_t i;
2569 2570

      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2571 2572
          pp = prev_row + 1; i < row_bytes;
          i++, rp++, pp++, dp++)
2573 2574 2575
      {
         *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
      }
2576

2577 2578 2579 2580
      best_row = png_ptr->up_row;
   }

   else if (filter_to_do & PNG_FILTER_UP)
G
Guy Schalnat 已提交
2581 2582
   {
      png_bytep rp, dp, pp;
A
Andreas Dilger 已提交
2583
      png_uint_32 sum = 0, lmins = mins;
2584
      png_size_t i;
A
Andreas Dilger 已提交
2585 2586
      int v;

2587

2588
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2589 2590
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2591
         int j;
A
Andreas Dilger 已提交
2592 2593 2594 2595
         png_uint_32 lmhi, lmlo;
         lmlo = lmins & PNG_LOMASK;
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;

2596
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2597
         {
2598
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
A
Andreas Dilger 已提交
2599
            {
2600
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2601
                   PNG_WEIGHT_SHIFT;
2602

2603
               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2604
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2605 2606 2607 2608
            }
         }

         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2609
             PNG_COST_SHIFT;
2610

A
Andreas Dilger 已提交
2611
         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
2612
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2613 2614 2615

         if (lmhi > PNG_HIMASK)
            lmins = PNG_MAXSUM;
2616

A
Andreas Dilger 已提交
2617 2618 2619 2620
         else
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
      }
#endif
G
Guy Schalnat 已提交
2621

G
Guy Schalnat 已提交
2622
      for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
2623
          pp = prev_row + 1; i < row_bytes; i++)
G
Guy Schalnat 已提交
2624
      {
2625
         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
G
Guy Schalnat 已提交
2626 2627

         sum += (v < 128) ? v : 256 - v;
A
Andreas Dilger 已提交
2628 2629 2630

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

2633
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2634 2635
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2636
         int j;
A
Andreas Dilger 已提交
2637 2638 2639 2640
         png_uint_32 sumhi, sumlo;
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;

2641
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2642
         {
2643
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
A
Andreas Dilger 已提交
2644
            {
2645
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2646
                   PNG_WEIGHT_SHIFT;
2647

2648
               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2649
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2650 2651 2652 2653
            }
         }

         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2654
             PNG_COST_SHIFT;
2655

A
Andreas Dilger 已提交
2656
         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
2657
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2658 2659 2660

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2661

A
Andreas Dilger 已提交
2662 2663 2664 2665 2666
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
      }
#endif

G
Guy Schalnat 已提交
2667 2668 2669 2670 2671 2672 2673
      if (sum < mins)
      {
         mins = sum;
         best_row = png_ptr->up_row;
      }
   }

2674
   /* Avg filter */
2675 2676 2677
   if (filter_to_do == PNG_FILTER_AVG)
   {
      png_bytep rp, dp, pp, lp;
2678
      png_uint_32 i;
2679

2680
      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2681
           pp = prev_row + 1; i < bpp; i++)
2682
      {
2683
         *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
2684
      }
2685

2686
      for (lp = row_buf + 1; i < row_bytes; i++)
2687
      {
2688 2689
         *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
                 & 0xff);
2690 2691 2692 2693 2694
      }
      best_row = png_ptr->avg_row;
   }

   else if (filter_to_do & PNG_FILTER_AVG)
G
Guy Schalnat 已提交
2695
   {
G
Guy Schalnat 已提交
2696
      png_bytep rp, dp, pp, lp;
A
Andreas Dilger 已提交
2697
      png_uint_32 sum = 0, lmins = mins;
2698
      png_size_t i;
A
Andreas Dilger 已提交
2699 2700
      int v;

2701
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2702 2703
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2704
         int j;
A
Andreas Dilger 已提交
2705 2706 2707 2708
         png_uint_32 lmhi, lmlo;
         lmlo = lmins & PNG_LOMASK;
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;

2709
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2710
         {
2711
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
A
Andreas Dilger 已提交
2712
            {
2713
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2714
                   PNG_WEIGHT_SHIFT;
2715

2716
               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2717
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2718 2719 2720 2721
            }
         }

         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2722
             PNG_COST_SHIFT;
2723

A
Andreas Dilger 已提交
2724
         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
2725
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2726 2727 2728

         if (lmhi > PNG_HIMASK)
            lmins = PNG_MAXSUM;
2729

A
Andreas Dilger 已提交
2730 2731 2732 2733
         else
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
      }
#endif
G
Guy Schalnat 已提交
2734

G
Guy Schalnat 已提交
2735
      for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
2736
           pp = prev_row + 1; i < bpp; i++)
G
Guy Schalnat 已提交
2737
      {
2738
         v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
G
Guy Schalnat 已提交
2739

G
Guy Schalnat 已提交
2740 2741
         sum += (v < 128) ? v : 256 - v;
      }
2742

2743
      for (lp = row_buf + 1; i < row_bytes; i++)
G
Guy Schalnat 已提交
2744
      {
2745
         v = *dp++ =
2746
             (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
G
Guy Schalnat 已提交
2747

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

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

2754
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2755 2756
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2757
         int j;
A
Andreas Dilger 已提交
2758 2759 2760 2761
         png_uint_32 sumhi, sumlo;
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;

2762
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2763
         {
2764
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
A
Andreas Dilger 已提交
2765
            {
2766
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2767
                   PNG_WEIGHT_SHIFT;
2768

2769
               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2770
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2771 2772 2773 2774
            }
         }

         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2775
             PNG_COST_SHIFT;
2776

A
Andreas Dilger 已提交
2777
         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
2778
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2779 2780 2781

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2782

A
Andreas Dilger 已提交
2783 2784 2785 2786 2787
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
      }
#endif

G
Guy Schalnat 已提交
2788 2789 2790 2791 2792 2793
      if (sum < mins)
      {
         mins = sum;
         best_row = png_ptr->avg_row;
      }
   }
G
Guy Schalnat 已提交
2794

A
Andreas Dilger 已提交
2795
   /* Paeth filter */
2796 2797 2798
   if (filter_to_do == PNG_FILTER_PAETH)
   {
      png_bytep rp, dp, pp, cp, lp;
2799
      png_size_t i;
2800

2801
      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2802
          pp = prev_row + 1; i < bpp; i++)
2803
      {
2804
         *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
2805 2806
      }

2807
      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
2808 2809 2810
      {
         int a, b, c, pa, pb, pc, p;

2811 2812 2813
         b = *pp++;
         c = *cp++;
         a = *lp++;
2814

2815 2816
         p = b - c;
         pc = a - c;
2817 2818

#ifdef PNG_USE_ABS
2819 2820 2821
         pa = abs(p);
         pb = abs(pc);
         pc = abs(p + pc);
2822
#else
2823 2824 2825
         pa = p < 0 ? -p : p;
         pb = pc < 0 ? -pc : pc;
         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2826 2827 2828 2829
#endif

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

2830
         *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
2831 2832 2833 2834 2835
      }
      best_row = png_ptr->paeth_row;
   }

   else if (filter_to_do & PNG_FILTER_PAETH)
G
Guy Schalnat 已提交
2836 2837
   {
      png_bytep rp, dp, pp, cp, lp;
A
Andreas Dilger 已提交
2838
      png_uint_32 sum = 0, lmins = mins;
2839
      png_size_t i;
A
Andreas Dilger 已提交
2840 2841
      int v;

2842
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2843 2844
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2845
         int j;
A
Andreas Dilger 已提交
2846 2847 2848 2849
         png_uint_32 lmhi, lmlo;
         lmlo = lmins & PNG_LOMASK;
         lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;

2850
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2851
         {
2852
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
A
Andreas Dilger 已提交
2853
            {
2854
               lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
2855
                   PNG_WEIGHT_SHIFT;
2856

2857
               lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
2858
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2859 2860 2861 2862
            }
         }

         lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2863
             PNG_COST_SHIFT;
2864

A
Andreas Dilger 已提交
2865
         lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2866
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2867 2868 2869

         if (lmhi > PNG_HIMASK)
            lmins = PNG_MAXSUM;
2870

A
Andreas Dilger 已提交
2871 2872 2873 2874
         else
            lmins = (lmhi << PNG_HISHIFT) + lmlo;
      }
#endif
G
Guy Schalnat 已提交
2875

G
Guy Schalnat 已提交
2876
      for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
2877
          pp = prev_row + 1; i < bpp; i++)
G
Guy Schalnat 已提交
2878
      {
2879
         v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
G
Guy Schalnat 已提交
2880

G
Guy Schalnat 已提交
2881 2882
         sum += (v < 128) ? v : 256 - v;
      }
2883

2884
      for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
G
Guy Schalnat 已提交
2885 2886
      {
         int a, b, c, pa, pb, pc, p;
G
Guy Schalnat 已提交
2887

2888 2889 2890
         b = *pp++;
         c = *cp++;
         a = *lp++;
2891 2892

#ifndef PNG_SLOW_PAETH
2893 2894
         p = b - c;
         pc = a - c;
2895
#ifdef PNG_USE_ABS
2896 2897 2898
         pa = abs(p);
         pb = abs(pc);
         pc = abs(p + pc);
2899
#else
2900 2901 2902
         pa = p < 0 ? -p : p;
         pb = pc < 0 ? -pc : pc;
         pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2903 2904 2905
#endif
         p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
#else /* PNG_SLOW_PAETH */
2906
         p = a + b - c;
2907 2908 2909
         pa = abs(p - a);
         pb = abs(p - b);
         pc = abs(p - c);
2910

G
Guy Schalnat 已提交
2911 2912
         if (pa <= pb && pa <= pc)
            p = a;
2913

G
Guy Schalnat 已提交
2914 2915
         else if (pb <= pc)
            p = b;
2916

G
Guy Schalnat 已提交
2917 2918
         else
            p = c;
2919
#endif /* PNG_SLOW_PAETH */
G
Guy Schalnat 已提交
2920

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

G
Guy Schalnat 已提交
2923
         sum += (v < 128) ? v : 256 - v;
A
Andreas Dilger 已提交
2924 2925 2926

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

2929
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2930 2931
      if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
      {
2932
         int j;
A
Andreas Dilger 已提交
2933 2934 2935 2936
         png_uint_32 sumhi, sumlo;
         sumlo = sum & PNG_LOMASK;
         sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;

2937
         for (j = 0; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2938
         {
2939
            if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
A
Andreas Dilger 已提交
2940
            {
2941
               sumlo = (sumlo * png_ptr->filter_weights[j]) >>
2942
                   PNG_WEIGHT_SHIFT;
2943

2944
               sumhi = (sumhi * png_ptr->filter_weights[j]) >>
2945
                   PNG_WEIGHT_SHIFT;
A
Andreas Dilger 已提交
2946 2947 2948 2949
            }
         }

         sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2950
             PNG_COST_SHIFT;
2951

A
Andreas Dilger 已提交
2952
         sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
2953
             PNG_COST_SHIFT;
A
Andreas Dilger 已提交
2954 2955 2956

         if (sumhi > PNG_HIMASK)
            sum = PNG_MAXSUM;
2957

A
Andreas Dilger 已提交
2958 2959 2960 2961 2962
         else
            sum = (sumhi << PNG_HISHIFT) + sumlo;
      }
#endif

G
Guy Schalnat 已提交
2963 2964 2965 2966
      if (sum < mins)
      {
         best_row = png_ptr->paeth_row;
      }
G
Guy Schalnat 已提交
2967
   }
2968
#endif /* PNG_WRITE_FILTER_SUPPORTED */
2969

2970 2971
   /* 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 已提交
2972

2973
#ifdef PNG_WRITE_FILTER_SUPPORTED
2974
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
A
Andreas Dilger 已提交
2975 2976 2977
   /* Save the type of filter we picked this time for future calculations */
   if (png_ptr->num_prev_filters > 0)
   {
2978
      int j;
2979

2980
      for (j = 1; j < num_p_filters; j++)
A
Andreas Dilger 已提交
2981
      {
2982
         png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
A
Andreas Dilger 已提交
2983
      }
2984

2985
      png_ptr->prev_filters[j] = best_row[0];
A
Andreas Dilger 已提交
2986 2987
   }
#endif
2988
#endif /* PNG_WRITE_FILTER_SUPPORTED */
G
Guy Schalnat 已提交
2989
}
G
Guy Schalnat 已提交
2990

G
Guy Schalnat 已提交
2991

A
Andreas Dilger 已提交
2992
/* Do the actual writing of a previously filtered row. */
2993
static void
2994
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
2995
   png_size_t full_row_length/*includes filter byte*/)
G
Guy Schalnat 已提交
2996
{
2997
   png_debug(1, "in png_write_filtered_row");
2998

2999
   png_debug1(2, "filter = %d", filtered_row[0]);
3000

3001
   png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
G
Guy Schalnat 已提交
3002

3003
   /* Swap the current and previous rows */
A
Andreas Dilger 已提交
3004
   if (png_ptr->prev_row != NULL)
G
Guy Schalnat 已提交
3005 3006 3007 3008 3009 3010 3011 3012
   {
      png_bytep tptr;

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

3013
   /* Finish row - updates counters and flushes zlib if last row */
G
Guy Schalnat 已提交
3014
   png_write_finish_row(png_ptr);
G
Guy Schalnat 已提交
3015

3016
#ifdef PNG_WRITE_FLUSH_SUPPORTED
G
Guy Schalnat 已提交
3017 3018 3019 3020 3021 3022
   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 已提交
3023
   }
3024
#endif
G
Guy Schalnat 已提交
3025
}
3026
#endif /* PNG_WRITE_SUPPORTED */