From 04dc8e765c24ba7e0e49eb23cac81b53512f813b Mon Sep 17 00:00:00 2001 From: SekoiaTree Date: Thu, 15 May 2025 16:41:28 +0200 Subject: [PATCH] feat: changes to scripts, add some diffs --- part1/oss-fuzz.diff | 19 +- .../report/w_corpus/directory_view_index.html | 8 + part1/report/w_corpus/file_view_index.html | 286 ++++++++++++++++++ part1/report/w_corpus/index.html | 8 + part1/report/w_corpus/report.html | 146 +++++++++ .../oss-fuzz/libpng_read_fuzzer.cc.html | 1 + .../src/libpng/contrib/oss-fuzz/report.html | 146 +++++++++ .../w_corpus/src/libpng/contrib/report.html | 146 +++++++++ part1/report/w_corpus/src/libpng/png.c.html | 1 + part1/report/w_corpus/src/libpng/png.h.html | 1 + .../w_corpus/src/libpng/pngdebug.h.html | 1 + .../w_corpus/src/libpng/pngerror.c.html | 1 + .../report/w_corpus/src/libpng/pngget.c.html | 1 + .../w_corpus/src/libpng/pnglibconf.h.html | 1 + .../report/w_corpus/src/libpng/pngmem.c.html | 1 + .../w_corpus/src/libpng/pngprefix.h.html | 1 + .../report/w_corpus/src/libpng/pngpriv.h.html | 1 + .../report/w_corpus/src/libpng/pngread.c.html | 1 + .../report/w_corpus/src/libpng/pngrio.c.html | 1 + .../w_corpus/src/libpng/pngrtran.c.html | 1 + .../w_corpus/src/libpng/pngrutil.c.html | 1 + .../report/w_corpus/src/libpng/pngset.c.html | 1 + .../w_corpus/src/libpng/pngstruct.h.html | 1 + .../w_corpus/src/libpng/pngtrans.c.html | 1 + part1/report/w_corpus/src/libpng/report.html | 286 ++++++++++++++++++ part1/report/w_corpus/src/report.html | 146 +++++++++ part1/report/w_corpus/summary.json | 1 + part1/run.w_corpus.sh | 2 +- part1/run.w_o_corpus.sh | 2 +- part3/improve1/oss-fuzz.diff | 26 ++ part3/improve1/project.diff | 21 ++ part3/improve1/run.improve1.sh | 2 +- 32 files changed, 1256 insertions(+), 6 deletions(-) create mode 100644 part1/report/w_corpus/directory_view_index.html create mode 100644 part1/report/w_corpus/file_view_index.html create mode 100644 part1/report/w_corpus/index.html create mode 100644 part1/report/w_corpus/report.html create mode 100644 part1/report/w_corpus/src/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc.html create mode 100644 part1/report/w_corpus/src/libpng/contrib/oss-fuzz/report.html create mode 100644 part1/report/w_corpus/src/libpng/contrib/report.html create mode 100644 part1/report/w_corpus/src/libpng/png.c.html create mode 100644 part1/report/w_corpus/src/libpng/png.h.html create mode 100644 part1/report/w_corpus/src/libpng/pngdebug.h.html create mode 100644 part1/report/w_corpus/src/libpng/pngerror.c.html create mode 100644 part1/report/w_corpus/src/libpng/pngget.c.html create mode 100644 part1/report/w_corpus/src/libpng/pnglibconf.h.html create mode 100644 part1/report/w_corpus/src/libpng/pngmem.c.html create mode 100644 part1/report/w_corpus/src/libpng/pngprefix.h.html create mode 100644 part1/report/w_corpus/src/libpng/pngpriv.h.html create mode 100644 part1/report/w_corpus/src/libpng/pngread.c.html create mode 100644 part1/report/w_corpus/src/libpng/pngrio.c.html create mode 100644 part1/report/w_corpus/src/libpng/pngrtran.c.html create mode 100644 part1/report/w_corpus/src/libpng/pngrutil.c.html create mode 100644 part1/report/w_corpus/src/libpng/pngset.c.html create mode 100644 part1/report/w_corpus/src/libpng/pngstruct.h.html create mode 100644 part1/report/w_corpus/src/libpng/pngtrans.c.html create mode 100644 part1/report/w_corpus/src/libpng/report.html create mode 100644 part1/report/w_corpus/src/report.html create mode 100644 part1/report/w_corpus/summary.json create mode 100644 part3/improve1/oss-fuzz.diff create mode 100644 part3/improve1/project.diff diff --git a/part1/oss-fuzz.diff b/part1/oss-fuzz.diff index 0a4adaf..9812193 100644 --- a/part1/oss-fuzz.diff +++ b/part1/oss-fuzz.diff @@ -1,5 +1,18 @@ +diff --git a/infra/helper.py b/infra/helper.py +index edf073458..a595dbfbb 100755 +--- a/infra/helper.py ++++ b/infra/helper.py +@@ -1448,6 +1448,8 @@ def run_fuzzer(args): + '%s:/out' % args.project.out, + '-t', + BASE_RUNNER_IMAGE, ++ 'timeout', ++ '14400', + 'run_fuzzer', + args.fuzzer_name, + ] + args.fuzzer_args) diff --git a/projects/libpng/Dockerfile b/projects/libpng/Dockerfile -index 6f281cd55..aecae58ac 100644 +index 6f281cd55..3017d4404 100644 --- a/projects/libpng/Dockerfile +++ b/projects/libpng/Dockerfile @@ -19,6 +19,7 @@ RUN apt-get update && \ @@ -7,7 +20,7 @@ index 6f281cd55..aecae58ac 100644 RUN git clone --depth 1 https://github.com/madler/zlib.git -RUN git clone --depth 1 https://github.com/pnggroup/libpng.git -+RUN git clone --depth 1 --branch v1.6.48 https://github.com/pnggroup/libpng.git ++RUN git clone --depth 1 --branch BRANCH_TO_CHECKOUT https://github.com/SekoiaTree/libpng.git ++#FUZZ_SEED_DISABLE RUN sed -i 's/libpng_read_fuzzer_seed_corpus\.zip/libpng_read_fuzzer_seed_corpus.zip.disabled/g' $SRC/build.sh RUN cp libpng/contrib/oss-fuzz/build.sh $SRC -+RUN sed -i 's/libpng_read_fuzzer_seed_corpus\.zip/libpng_read_fuzzer_seed_corpus.zip.disabled/g' $SRC/build.sh WORKDIR libpng diff --git a/part1/report/w_corpus/directory_view_index.html b/part1/report/w_corpus/directory_view_index.html new file mode 100644 index 0000000..03cf5b6 --- /dev/null +++ b/part1/report/w_corpus/directory_view_index.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/part1/report/w_corpus/file_view_index.html b/part1/report/w_corpus/file_view_index.html new file mode 100644 index 0000000..7e9984b --- /dev/null +++ b/part1/report/w_corpus/file_view_index.html @@ -0,0 +1,286 @@ + + + + + + + + + + +

Coverage Report

+

+ View results by: + Directories + | Files +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Path + Line Coverage + + Function Coverage + + Region Coverage +
+
src/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc
+
+
 87.93% (102/116)
+
+
100.00% (5/5)
+
+
 59.33% (124/209)
+
+
src/libpng/png.c
+
+
 42.74% (727/1701)
+
+
 57.58% (38/66)
+
+
 42.13% (610/1448)
+
+
src/libpng/pngerror.c
+
+
 55.26% (210/380)
+
+
 70.37% (19/27)
+
+
 51.13% (158/309)
+
+
src/libpng/pngget.c
+
+
  3.50% (26/742)
+
+
  2.78% (2/72)
+
+
  3.00% (26/866)
+
+
src/libpng/pngmem.c
+
+
 79.28% (88/111)
+
+
 84.62% (11/13)
+
+
 75.96% (79/104)
+
+
src/libpng/pngread.c
+
+
 28.36% (638/2250)
+
+
 47.37% (18/38)
+
+
 27.80% (609/2191)
+
+
src/libpng/pngrio.c
+
+
 78.57% (11/14)
+
+
100.00% (2/2)
+
+
 70.00% (7/10)
+
+
src/libpng/pngrtran.c
+
+
 30.17% (1025/3397)
+
+
 52.08% (25/48)
+
+
 32.38% (694/2143)
+
+
src/libpng/pngrutil.c
+
+
 73.31% (1912/2608)
+
+
 93.22% (55/59)
+
+
 29.12% (1953/6707)
+
+
src/libpng/pngset.c
+
+
 53.03% (587/1107)
+
+
 48.98% (24/49)
+
+
 54.13% (511/944)
+
+
src/libpng/pngtrans.c
+
+
  8.67% (36/415)
+
+
 19.05% (4/21)
+
+
 12.01% (37/308)
+
+
Totals
+
+
 41.76% (5362/12841)
+
+
 50.75% (203/400)
+
+
 31.55% (4808/15239)
+
+ +
+ + \ No newline at end of file diff --git a/part1/report/w_corpus/index.html b/part1/report/w_corpus/index.html new file mode 100644 index 0000000..7eb689b --- /dev/null +++ b/part1/report/w_corpus/index.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/part1/report/w_corpus/report.html b/part1/report/w_corpus/report.html new file mode 100644 index 0000000..0e75a69 --- /dev/null +++ b/part1/report/w_corpus/report.html @@ -0,0 +1,146 @@ + + + + + + + + + + +

Coverage Report

+

+ View results by: + Directories + | Files +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Path + Line Coverage + + Function Coverage + + Region Coverage +
+
src/
+
+
 41.76% (5362/12841)
+
+
 50.75% (203/400)
+
+
 31.55% (4808/15239)
+
+
Totals
+
+
 41.76% (5362/12841)
+
+
 50.75% (203/400)
+
+
 31.55% (4808/15239)
+
+ +
+ + \ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc.html b/part1/report/w_corpus/src/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc.html new file mode 100644 index 0000000..ad868da --- /dev/null +++ b/part1/report/w_corpus/src/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc
Line
Count
Source (jump to first uncovered line)
1
// libpng_read_fuzzer.cc
2
// Copyright 2017-2018 Glenn Randers-Pehrson
3
// Copyright 2015 The Chromium Authors. All rights reserved.
4
// Use of this source code is governed by a BSD-style license that may
5
// be found in the LICENSE file https://cs.chromium.org/chromium/src/LICENSE
6
7
// The modifications in 2017 by Glenn Randers-Pehrson include
8
// 1. addition of a PNG_CLEANUP macro,
9
// 2. setting the option to ignore ADLER32 checksums,
10
// 3. adding "#include <string.h>" which is needed on some platforms
11
//    to provide memcpy().
12
// 4. adding read_end_info() and creating an end_info structure.
13
// 5. adding calls to png_set_*() transforms commonly used by browsers.
14
15
#include <stddef.h>
16
#include <stdint.h>
17
#include <stdlib.h>
18
#include <string.h>
19
20
#include <vector>
21
22
#define PNG_INTERNAL
23
#include "png.h"
24
25
#define PNG_CLEANUP \
26
1.80k
  if(png_handler.png_ptr) \
27
1.80k
  { \
28
1.80k
    if (png_handler.row_ptr) \
29
1.80k
      png_free(png_handler.png_ptr, png_handler.row_ptr); \
30
1.80k
    if (png_handler.end_info_ptr) \
31
1.80k
      png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\
32
1.80k
        &png_handler.end_info_ptr); \
33
1.80k
    else if (png_handler.info_ptr) \
34
0
      png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\
35
0
        nullptr); \
36
0
    else \
37
0
      png_destroy_read_struct(&png_handler.png_ptr, nullptr, nullptr); \
38
1.80k
    png_handler.png_ptr = nullptr; \
39
1.80k
    png_handler.row_ptr = nullptr; \
40
1.80k
    png_handler.info_ptr = nullptr; \
41
1.80k
    png_handler.end_info_ptr = nullptr; \
42
1.80k
  }
43
44
struct BufState {
45
  const uint8_t* data;
46
  size_t bytes_left;
47
};
48
49
struct PngObjectHandler {
50
  png_infop info_ptr = nullptr;
51
  png_structp png_ptr = nullptr;
52
  png_infop end_info_ptr = nullptr;
53
  png_voidp row_ptr = nullptr;
54
  BufState* buf_state = nullptr;
55
56
1.80k
  ~PngObjectHandler() {
57
1.80k
    if (row_ptr)
58
0
      png_free(png_ptr, row_ptr);
59
1.80k
    if (end_info_ptr)
60
0
      png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr);
61
1.80k
    else if (info_ptr)
62
0
      png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
63
1.80k
    else
64
1.80k
      png_destroy_read_struct(&png_ptr, nullptr, nullptr);
65
1.80k
    delete buf_state;
66
1.80k
  }
67
};
68
69
91.1k
void user_read_data(png_structp png_ptr, png_bytep data, size_t length) {
70
91.1k
  BufState* buf_state = static_cast<BufState*>(png_get_io_ptr(png_ptr));
71
91.1k
  if (length > buf_state->bytes_left) {
72
747
    png_error(png_ptr, "read error");
73
747
  }
74
90.4k
  memcpy(data, buf_state->data, length);
75
90.4k
  buf_state->bytes_left -= length;
76
90.4k
  buf_state->data += length;
77
90.4k
}
78
79
17.2k
void* limited_malloc(png_structp, png_alloc_size_t size) {
80
  // libpng may allocate large amounts of memory that the fuzzer reports as
81
  // an error. In order to silence these errors, make libpng fail when trying
82
  // to allocate a large amount. This allocator used to be in the Chromium
83
  // version of this fuzzer.
84
  // This number is chosen to match the default png_user_chunk_malloc_max.
85
17.2k
  if (size > 8000000)
86
2
    return nullptr;
87
88
17.2k
  return malloc(size);
89
17.2k
}
90
91
22.6k
void default_free(png_structp, png_voidp ptr) {
92
22.6k
  return free(ptr);
93
22.6k
}
94
95
static const int kPngHeaderSize = 8;
96
97
// Entry point for LibFuzzer.
98
// Roughly follows the libpng book example:
99
// http://www.libpng.org/pub/png/book/chapter13.html
100
1.80k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
101
1.80k
  if (size < kPngHeaderSize) {
102
1
    return 0;
103
1
  }
104
105
1.80k
  std::vector<unsigned char> v(data, data + size);
106
1.80k
  if (png_sig_cmp(v.data(), 0, kPngHeaderSize)) {
107
    // not a PNG.
108
1
    return 0;
109
1
  }
110
111
1.80k
  PngObjectHandler png_handler;
112
1.80k
  png_handler.png_ptr = nullptr;
113
1.80k
  png_handler.row_ptr = nullptr;
114
1.80k
  png_handler.info_ptr = nullptr;
115
1.80k
  png_handler.end_info_ptr = nullptr;
116
117
1.80k
  png_handler.png_ptr = png_create_read_struct
118
1.80k
    (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
119
1.80k
  if (!png_handler.png_ptr) {
120
0
    return 0;
121
0
  }
122
123
1.80k
  png_handler.info_ptr = png_create_info_struct(png_handler.png_ptr);
124
1.80k
  if (!png_handler.info_ptr) {
125
0
    PNG_CLEANUP
126
0
    return 0;
127
0
  }
128
129
1.80k
  png_handler.end_info_ptr = png_create_info_struct(png_handler.png_ptr);
130
1.80k
  if (!png_handler.end_info_ptr) {
131
0
    PNG_CLEANUP
132
0
    return 0;
133
0
  }
134
135
  // Use a custom allocator that fails for large allocations to avoid OOM.
136
1.80k
  png_set_mem_fn(png_handler.png_ptr, nullptr, limited_malloc, default_free);
137
138
1.80k
  png_set_crc_action(png_handler.png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
139
#ifdef PNG_IGNORE_ADLER32
140
  png_set_option(png_handler.png_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
141
#endif
142
143
  // Setting up reading from buffer.
144
1.80k
  png_handler.buf_state = new BufState();
145
1.80k
  png_handler.buf_state->data = data + kPngHeaderSize;
146
1.80k
  png_handler.buf_state->bytes_left = size - kPngHeaderSize;
147
1.80k
  png_set_read_fn(png_handler.png_ptr, png_handler.buf_state, user_read_data);
148
1.80k
  png_set_sig_bytes(png_handler.png_ptr, kPngHeaderSize);
149
150
1.80k
  if (setjmp(png_jmpbuf(png_handler.png_ptr))) {
151
830
    PNG_CLEANUP
152
830
    return 0;
153
830
  }
154
155
  // Reading.
156
970
  png_read_info(png_handler.png_ptr, png_handler.info_ptr);
157
158
  // reset error handler to put png_deleter into scope.
159
970
  if (setjmp(png_jmpbuf(png_handler.png_ptr))) {
160
544
    PNG_CLEANUP
161
544
    return 0;
162
544
  }
163
164
426
  png_uint_32 width, height;
165
426
  int bit_depth, color_type, interlace_type, compression_type;
166
426
  int filter_type;
167
168
426
  if (!png_get_IHDR(png_handler.png_ptr, png_handler.info_ptr, &width,
169
426
                    &height, &bit_depth, &color_type, &interlace_type,
170
426
                    &compression_type, &filter_type)) {
171
0
    PNG_CLEANUP
172
0
    return 0;
173
0
  }
174
175
  // This is going to be too slow.
176
970
  if (width && height > 100000000 / width) {
177
1
    PNG_CLEANUP
178
1
    return 0;
179
1
  }
180
181
  // Set several transforms that browsers typically use:
182
425
  png_set_gray_to_rgb(png_handler.png_ptr);
183
425
  png_set_expand(png_handler.png_ptr);
184
425
  png_set_packing(png_handler.png_ptr);
185
425
  png_set_scale_16(png_handler.png_ptr);
186
425
  png_set_tRNS_to_alpha(png_handler.png_ptr);
187
188
425
  int passes = png_set_interlace_handling(png_handler.png_ptr);
189
190
425
  png_read_update_info(png_handler.png_ptr, png_handler.info_ptr);
191
192
425
  png_handler.row_ptr = png_malloc(
193
425
      png_handler.png_ptr, png_get_rowbytes(png_handler.png_ptr,
194
425
                                            png_handler.info_ptr));
195
196
2.59k
  for (int pass = 0; pass < passes; ++pass) {
197
444k
    for (png_uint_32 y = 0; y < height; ++y) {
198
442k
      png_read_row(png_handler.png_ptr,
199
442k
                   static_cast<png_bytep>(png_handler.row_ptr), nullptr);
200
442k
    }
201
2.16k
  }
202
203
425
  png_read_end(png_handler.png_ptr, png_handler.end_info_ptr);
204
205
425
  PNG_CLEANUP
206
207
425
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
208
  // Simplified READ API
209
425
  png_image image;
210
425
  memset(&image, 0, (sizeof image));
211
425
  image.version = PNG_IMAGE_VERSION;
212
213
425
  if (!png_image_begin_read_from_memory(&image, data, size)) {
214
6
    return 0;
215
6
  }
216
217
419
  image.format = PNG_FORMAT_RGBA;
218
419
  std::vector<png_byte> buffer(PNG_IMAGE_SIZE(image));
219
419
  png_image_finish_read(&image, NULL, buffer.data(), 0, NULL);
220
419
#endif
221
222
419
  return 0;
223
425
}
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/contrib/oss-fuzz/report.html b/part1/report/w_corpus/src/libpng/contrib/oss-fuzz/report.html new file mode 100644 index 0000000..e4f2268 --- /dev/null +++ b/part1/report/w_corpus/src/libpng/contrib/oss-fuzz/report.html @@ -0,0 +1,146 @@ + + + + + + + + + + +

Coverage Report

+

+ View results by: + Directories + | Files +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Path + Line Coverage + + Function Coverage + + Region Coverage +
+
libpng_read_fuzzer.cc
+
+
 87.93% (102/116)
+
+
100.00% (5/5)
+
+
 59.33% (124/209)
+
+
Totals
+
+
 87.93% (102/116)
+
+
100.00% (5/5)
+
+
 59.33% (124/209)
+
+ +
+ + \ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/contrib/report.html b/part1/report/w_corpus/src/libpng/contrib/report.html new file mode 100644 index 0000000..e95a25d --- /dev/null +++ b/part1/report/w_corpus/src/libpng/contrib/report.html @@ -0,0 +1,146 @@ + + + + + + + + + + +

Coverage Report

+

+ View results by: + Directories + | Files +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Path + Line Coverage + + Function Coverage + + Region Coverage +
+
oss-fuzz/
+
+
 87.93% (102/116)
+
+
100.00% (5/5)
+
+
 59.33% (124/209)
+
+
Totals
+
+
 87.93% (102/116)
+
+
100.00% (5/5)
+
+
 59.33% (124/209)
+
+ +
+ + \ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/png.c.html b/part1/report/w_corpus/src/libpng/png.c.html new file mode 100644 index 0000000..ed5740e --- /dev/null +++ b/part1/report/w_corpus/src/libpng/png.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/png.c
Line
Count
Source (jump to first uncovered line)
1
/* png.c - location for general purpose libpng functions
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 */
12
13
#include "pngpriv.h"
14
15
/* Generate a compiler error if there is an old png.h in the search path. */
16
typedef png_libpng_version_1_6_48 Your_png_h_is_not_version_1_6_48;
17
18
/* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the
19
 * corresponding macro definitions.  This causes a compile time failure if
20
 * something is wrong but generates no code.
21
 *
22
 * (1) The first check is that the PNG_CHUNK(cHNK, index) 'index' values must
23
 * increment from 0 to the last value.
24
 */
25
#define PNG_CHUNK(cHNK, index) != (index) || ((index)+1)
26
27
#if 0 PNG_KNOWN_CHUNKS < 0
28
#  error PNG_KNOWN_CHUNKS chunk definitions are not in order
29
#endif
30
31
#undef PNG_CHUNK
32
33
/* (2) The chunk name macros, png_cHNK, must all be valid and defined.  Since
34
 * this is a preprocessor test undefined pp-tokens come out as zero and will
35
 * fail this test.
36
 */
37
#define PNG_CHUNK(cHNK, index) !PNG_CHUNK_NAME_VALID(png_ ## cHNK) ||
38
39
#if PNG_KNOWN_CHUNKS 0
40
#  error png_cHNK not defined for some known cHNK
41
#endif
42
43
#undef PNG_CHUNK
44
45
/* Tells libpng that we have already handled the first "num_bytes" bytes
46
 * of the PNG file signature.  If the PNG data is embedded into another
47
 * stream we can set num_bytes = 8 so that libpng will not attempt to read
48
 * or write any of the magic bytes before it starts on the IHDR.
49
 */
50
51
#ifdef PNG_READ_SUPPORTED
52
void PNGAPI
53
png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
54
1.80k
{
55
1.80k
   unsigned int nb = (unsigned int)num_bytes;
56
57
1.80k
   png_debug(1, "in png_set_sig_bytes");
58
59
1.80k
   if (png_ptr == NULL)
60
0
      return;
61
62
1.80k
   if (num_bytes < 0)
63
0
      nb = 0;
64
65
1.80k
   if (nb > 8)
66
0
      png_error(png_ptr, "Too many bytes for PNG signature");
67
68
1.80k
   png_ptr->sig_bytes = (png_byte)nb;
69
1.80k
}
70
71
/* Checks whether the supplied bytes match the PNG signature.  We allow
72
 * checking less than the full 8-byte signature so that those apps that
73
 * already read the first few bytes of a file to determine the file type
74
 * can simply check the remaining bytes for extra assurance.  Returns
75
 * an integer less than, equal to, or greater than zero if sig is found,
76
 * respectively, to be less than, to match, or be greater than the correct
77
 * PNG signature (this is the same behavior as strcmp, memcmp, etc).
78
 */
79
int PNGAPI
80
png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check)
81
2.22k
{
82
2.22k
   static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
83
84
2.22k
   if (num_to_check > 8)
85
0
      num_to_check = 8;
86
87
2.22k
   else if (num_to_check < 1)
88
0
      return -1;
89
90
2.22k
   if (start > 7)
91
0
      return -1;
92
93
2.22k
   if (start + num_to_check > 8)
94
0
      num_to_check = 8 - start;
95
96
2.22k
   return memcmp(&sig[start], &png_signature[start], num_to_check);
97
2.22k
}
98
99
#endif /* READ */
100
101
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
102
/* Function to allocate memory for zlib */
103
PNG_FUNCTION(voidpf /* PRIVATE */,
104
png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
105
2.79k
{
106
2.79k
   png_alloc_size_t num_bytes = size;
107
108
2.79k
   if (png_ptr == NULL)
109
0
      return NULL;
110
111
2.79k
   if (items >= (~(png_alloc_size_t)0)/size)
112
0
   {
113
0
      png_warning (png_voidcast(png_structrp, png_ptr),
114
0
          "Potential overflow in png_zalloc()");
115
0
      return NULL;
116
0
   }
117
118
2.79k
   num_bytes *= items;
119
2.79k
   return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
120
2.79k
}
121
122
/* Function to free memory for zlib */
123
void /* PRIVATE */
124
png_zfree(voidpf png_ptr, voidpf ptr)
125
2.79k
{
126
2.79k
   png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
127
2.79k
}
128
129
/* Reset the CRC variable to 32 bits of 1's.  Care must be taken
130
 * in case CRC is > 32 bits to leave the top bits 0.
131
 */
132
void /* PRIVATE */
133
png_reset_crc(png_structrp png_ptr)
134
37.5k
{
135
   /* The cast is safe because the crc is a 32-bit value. */
136
37.5k
   png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
137
37.5k
}
138
139
/* Calculate the CRC over a section of data.  We can only pass as
140
 * much data to this routine as the largest single buffer size.  We
141
 * also check that this data will actually be used before going to the
142
 * trouble of calculating it.
143
 */
144
void /* PRIVATE */
145
png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length)
146
74.9k
{
147
74.9k
   int need_crc = 1;
148
149
74.9k
   if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
150
63.8k
   {
151
63.8k
      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
152
63.8k
          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
153
52.0k
         need_crc = 0;
154
63.8k
   }
155
156
11.1k
   else /* critical */
157
11.1k
   {
158
11.1k
      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
159
8.66k
         need_crc = 0;
160
11.1k
   }
161
162
   /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
163
    * systems it is a 64-bit value.  crc32, however, returns 32 bits so the
164
    * following cast is safe.  'uInt' may be no more than 16 bits, so it is
165
    * necessary to perform a loop here.
166
    */
167
74.9k
   if (need_crc != 0 && length > 0)
168
14.2k
   {
169
14.2k
      uLong crc = png_ptr->crc; /* Should never issue a warning */
170
171
14.2k
      do
172
14.2k
      {
173
14.2k
         uInt safe_length = (uInt)length;
174
14.2k
#ifndef __COVERITY__
175
14.2k
         if (safe_length == 0)
176
0
            safe_length = (uInt)-1; /* evil, but safe */
177
14.2k
#endif
178
179
14.2k
         crc = crc32(crc, ptr, safe_length);
180
181
         /* The following should never issue compiler warnings; if they do the
182
          * target system has characteristics that will probably violate other
183
          * assumptions within the libpng code.
184
          */
185
14.2k
         ptr += safe_length;
186
14.2k
         length -= safe_length;
187
14.2k
      }
188
14.2k
      while (length > 0);
189
190
      /* And the following is always safe because the crc is only 32 bits. */
191
14.2k
      png_ptr->crc = (png_uint_32)crc;
192
14.2k
   }
193
74.9k
}
194
195
/* Check a user supplied version number, called from both read and write
196
 * functions that create a png_struct.
197
 */
198
int
199
png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
200
2.22k
{
201
   /* Libpng versions 1.0.0 and later are binary compatible if the version
202
    * string matches through the second '.'; we must recompile any
203
    * applications that use any older library version.
204
    */
205
206
2.22k
   if (user_png_ver != NULL)
207
2.22k
   {
208
2.22k
      int i = -1;
209
2.22k
      int found_dots = 0;
210
211
2.22k
      do
212
8.90k
      {
213
8.90k
         i++;
214
8.90k
         if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
215
0
            png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
216
8.90k
         if (user_png_ver[i] == '.')
217
4.45k
            found_dots++;
218
8.90k
      } while (found_dots < 2 && user_png_ver[i] != 0 &&
219
8.90k
            PNG_LIBPNG_VER_STRING[i] != 0);
220
2.22k
   }
221
222
0
   else
223
0
      png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
224
225
2.22k
   if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)
226
0
   {
227
0
#ifdef PNG_WARNINGS_SUPPORTED
228
0
      size_t pos = 0;
229
0
      char m[128];
230
231
0
      pos = png_safecat(m, (sizeof m), pos,
232
0
          "Application built with libpng-");
233
0
      pos = png_safecat(m, (sizeof m), pos, user_png_ver);
234
0
      pos = png_safecat(m, (sizeof m), pos, " but running with ");
235
0
      pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
236
0
      PNG_UNUSED(pos)
237
238
0
      png_warning(png_ptr, m);
239
0
#endif
240
241
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
242
      png_ptr->flags = 0;
243
#endif
244
245
0
      return 0;
246
0
   }
247
248
   /* Success return. */
249
2.22k
   return 1;
250
2.22k
}
251
252
/* Generic function to create a png_struct for either read or write - this
253
 * contains the common initialization.
254
 */
255
PNG_FUNCTION(png_structp /* PRIVATE */,
256
png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
257
    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
258
    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
259
2.22k
{
260
2.22k
   png_struct create_struct;
261
2.22k
#  ifdef PNG_SETJMP_SUPPORTED
262
2.22k
      jmp_buf create_jmp_buf;
263
2.22k
#  endif
264
265
   /* This temporary stack-allocated structure is used to provide a place to
266
    * build enough context to allow the user provided memory allocator (if any)
267
    * to be called.
268
    */
269
2.22k
   memset(&create_struct, 0, (sizeof create_struct));
270
271
2.22k
#  ifdef PNG_USER_LIMITS_SUPPORTED
272
2.22k
      create_struct.user_width_max = PNG_USER_WIDTH_MAX;
273
2.22k
      create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
274
275
2.22k
#     ifdef PNG_USER_CHUNK_CACHE_MAX
276
2.22k
      create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
277
2.22k
#     endif
278
279
2.22k
#     if PNG_USER_CHUNK_MALLOC_MAX > 0 /* default to compile-time limit */
280
2.22k
      create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
281
282
      /* No compile-time limit, so initialize to the system limit: */
283
#     elif defined PNG_MAX_MALLOC_64K /* legacy system limit */
284
      create_struct.user_chunk_malloc_max = 65536U;
285
286
#     else /* modern system limit SIZE_MAX (C99) */
287
      create_struct.user_chunk_malloc_max = PNG_SIZE_MAX;
288
#     endif
289
2.22k
#  endif
290
291
   /* The following two API calls simply set fields in png_struct, so it is safe
292
    * to do them now even though error handling is not yet set up.
293
    */
294
2.22k
#  ifdef PNG_USER_MEM_SUPPORTED
295
2.22k
      png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
296
#  else
297
      PNG_UNUSED(mem_ptr)
298
      PNG_UNUSED(malloc_fn)
299
      PNG_UNUSED(free_fn)
300
#  endif
301
302
   /* (*error_fn) can return control to the caller after the error_ptr is set,
303
    * this will result in a memory leak unless the error_fn does something
304
    * extremely sophisticated.  The design lacks merit but is implicit in the
305
    * API.
306
    */
307
2.22k
   png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
308
309
2.22k
#  ifdef PNG_SETJMP_SUPPORTED
310
2.22k
      if (!setjmp(create_jmp_buf))
311
2.22k
#  endif
312
2.22k
      {
313
2.22k
#  ifdef PNG_SETJMP_SUPPORTED
314
         /* Temporarily fake out the longjmp information until we have
315
          * successfully completed this function.  This only works if we have
316
          * setjmp() support compiled in, but it is safe - this stuff should
317
          * never happen.
318
          */
319
2.22k
         create_struct.jmp_buf_ptr = &create_jmp_buf;
320
2.22k
         create_struct.jmp_buf_size = 0; /*stack allocation*/
321
2.22k
         create_struct.longjmp_fn = longjmp;
322
2.22k
#  endif
323
         /* Call the general version checker (shared with read and write code):
324
          */
325
2.22k
         if (png_user_version_check(&create_struct, user_png_ver) != 0)
326
2.22k
         {
327
2.22k
            png_structrp png_ptr = png_voidcast(png_structrp,
328
2.22k
                png_malloc_warn(&create_struct, (sizeof *png_ptr)));
329
330
2.22k
            if (png_ptr != NULL)
331
2.22k
            {
332
               /* png_ptr->zstream holds a back-pointer to the png_struct, so
333
                * this can only be done now:
334
                */
335
2.22k
               create_struct.zstream.zalloc = png_zalloc;
336
2.22k
               create_struct.zstream.zfree = png_zfree;
337
2.22k
               create_struct.zstream.opaque = png_ptr;
338
339
2.22k
#              ifdef PNG_SETJMP_SUPPORTED
340
               /* Eliminate the local error handling: */
341
2.22k
               create_struct.jmp_buf_ptr = NULL;
342
2.22k
               create_struct.jmp_buf_size = 0;
343
2.22k
               create_struct.longjmp_fn = 0;
344
2.22k
#              endif
345
346
2.22k
               *png_ptr = create_struct;
347
348
               /* This is the successful return point */
349
2.22k
               return png_ptr;
350
2.22k
            }
351
2.22k
         }
352
2.22k
      }
353
354
   /* A longjmp because of a bug in the application storage allocator or a
355
    * simple failure to allocate the png_struct.
356
    */
357
0
   return NULL;
358
2.22k
}
359
360
/* Allocate the memory for an info_struct for the application. */
361
PNG_FUNCTION(png_infop,PNGAPI
362
png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
363
4.02k
{
364
4.02k
   png_inforp info_ptr;
365
366
4.02k
   png_debug(1, "in png_create_info_struct");
367
368
4.02k
   if (png_ptr == NULL)
369
0
      return NULL;
370
371
   /* Use the internal API that does not (or at least should not) error out, so
372
    * that this call always returns ok.  The application typically sets up the
373
    * error handling *after* creating the info_struct because this is the way it
374
    * has always been done in 'example.c'.
375
    */
376
4.02k
   info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
377
4.02k
       (sizeof *info_ptr)));
378
379
4.02k
   if (info_ptr != NULL)
380
4.02k
      memset(info_ptr, 0, (sizeof *info_ptr));
381
382
4.02k
   return info_ptr;
383
4.02k
}
384
385
/* This function frees the memory associated with a single info struct.
386
 * Normally, one would use either png_destroy_read_struct() or
387
 * png_destroy_write_struct() to free an info struct, but this may be
388
 * useful for some applications.  From libpng 1.6.0 this function is also used
389
 * internally to implement the png_info release part of the 'struct' destroy
390
 * APIs.  This ensures that all possible approaches free the same data (all of
391
 * it).
392
 */
393
void PNGAPI
394
png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
395
4.45k
{
396
4.45k
   png_inforp info_ptr = NULL;
397
398
4.45k
   png_debug(1, "in png_destroy_info_struct");
399
400
4.45k
   if (png_ptr == NULL)
401
0
      return;
402
403
4.45k
   if (info_ptr_ptr != NULL)
404
4.02k
      info_ptr = *info_ptr_ptr;
405
406
4.45k
   if (info_ptr != NULL)
407
4.02k
   {
408
      /* Do this first in case of an error below; if the app implements its own
409
       * memory management this can lead to png_free calling png_error, which
410
       * will abort this routine and return control to the app error handler.
411
       * An infinite loop may result if it then tries to free the same info
412
       * ptr.
413
       */
414
4.02k
      *info_ptr_ptr = NULL;
415
416
4.02k
      png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
417
4.02k
      memset(info_ptr, 0, (sizeof *info_ptr));
418
4.02k
      png_free(png_ptr, info_ptr);
419
4.02k
   }
420
4.45k
}
421
422
/* Initialize the info structure.  This is now an internal function (0.89)
423
 * and applications using it are urged to use png_create_info_struct()
424
 * instead.  Use deprecated in 1.6.0, internal use removed (used internally it
425
 * is just a memset).
426
 *
427
 * NOTE: it is almost inconceivable that this API is used because it bypasses
428
 * the user-memory mechanism and the user error handling/warning mechanisms in
429
 * those cases where it does anything other than a memset.
430
 */
431
PNG_FUNCTION(void,PNGAPI
432
png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size),
433
    PNG_DEPRECATED)
434
0
{
435
0
   png_inforp info_ptr = *ptr_ptr;
436
437
0
   png_debug(1, "in png_info_init_3");
438
439
0
   if (info_ptr == NULL)
440
0
      return;
441
442
0
   if ((sizeof (png_info)) > png_info_struct_size)
443
0
   {
444
0
      *ptr_ptr = NULL;
445
      /* The following line is why this API should not be used: */
446
0
      free(info_ptr);
447
0
      info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
448
0
          (sizeof *info_ptr)));
449
0
      if (info_ptr == NULL)
450
0
         return;
451
0
      *ptr_ptr = info_ptr;
452
0
   }
453
454
   /* Set everything to 0 */
455
0
   memset(info_ptr, 0, (sizeof *info_ptr));
456
0
}
457
458
void PNGAPI
459
png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
460
    int freer, png_uint_32 mask)
461
0
{
462
0
   png_debug(1, "in png_data_freer");
463
464
0
   if (png_ptr == NULL || info_ptr == NULL)
465
0
      return;
466
467
0
   if (freer == PNG_DESTROY_WILL_FREE_DATA)
468
0
      info_ptr->free_me |= mask;
469
470
0
   else if (freer == PNG_USER_WILL_FREE_DATA)
471
0
      info_ptr->free_me &= ~mask;
472
473
0
   else
474
0
      png_error(png_ptr, "Unknown freer parameter in png_data_freer");
475
0
}
476
477
void PNGAPI
478
png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
479
    int num)
480
5.01k
{
481
5.01k
   png_debug(1, "in png_free_data");
482
483
5.01k
   if (png_ptr == NULL || info_ptr == NULL)
484
0
      return;
485
486
5.01k
#ifdef PNG_TEXT_SUPPORTED
487
   /* Free text item num or (if num == -1) all text items */
488
5.01k
   if (info_ptr->text != NULL &&
489
5.01k
       ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
490
817
   {
491
817
      if (num != -1)
492
0
      {
493
0
         png_free(png_ptr, info_ptr->text[num].key);
494
0
         info_ptr->text[num].key = NULL;
495
0
      }
496
497
817
      else
498
817
      {
499
817
         int i;
500
501
6.21k
         for (i = 0; i < info_ptr->num_text; i++)
502
5.39k
            png_free(png_ptr, info_ptr->text[i].key);
503
504
817
         png_free(png_ptr, info_ptr->text);
505
817
         info_ptr->text = NULL;
506
817
         info_ptr->num_text = 0;
507
817
         info_ptr->max_text = 0;
508
817
      }
509
817
   }
510
5.01k
#endif
511
512
5.01k
#ifdef PNG_tRNS_SUPPORTED
513
   /* Free any tRNS entry */
514
5.01k
   if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
515
597
   {
516
597
      info_ptr->valid &= ~PNG_INFO_tRNS;
517
597
      png_free(png_ptr, info_ptr->trans_alpha);
518
597
      info_ptr->trans_alpha = NULL;
519
597
      info_ptr->num_trans = 0;
520
597
   }
521
5.01k
#endif
522
523
5.01k
#ifdef PNG_sCAL_SUPPORTED
524
   /* Free any sCAL entry */
525
5.01k
   if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)
526
84
   {
527
84
      png_free(png_ptr, info_ptr->scal_s_width);
528
84
      png_free(png_ptr, info_ptr->scal_s_height);
529
84
      info_ptr->scal_s_width = NULL;
530
84
      info_ptr->scal_s_height = NULL;
531
84
      info_ptr->valid &= ~PNG_INFO_sCAL;
532
84
   }
533
5.01k
#endif
534
535
5.01k
#ifdef PNG_pCAL_SUPPORTED
536
   /* Free any pCAL entry */
537
5.01k
   if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)
538
63
   {
539
63
      png_free(png_ptr, info_ptr->pcal_purpose);
540
63
      png_free(png_ptr, info_ptr->pcal_units);
541
63
      info_ptr->pcal_purpose = NULL;
542
63
      info_ptr->pcal_units = NULL;
543
544
63
      if (info_ptr->pcal_params != NULL)
545
63
         {
546
63
            int i;
547
548
189
            for (i = 0; i < info_ptr->pcal_nparams; i++)
549
126
               png_free(png_ptr, info_ptr->pcal_params[i]);
550
551
63
            png_free(png_ptr, info_ptr->pcal_params);
552
63
            info_ptr->pcal_params = NULL;
553
63
         }
554
63
      info_ptr->valid &= ~PNG_INFO_pCAL;
555
63
   }
556
5.01k
#endif
557
558
5.01k
#ifdef PNG_iCCP_SUPPORTED
559
   /* Free any profile entry */
560
5.01k
   if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)
561
0
   {
562
0
      png_free(png_ptr, info_ptr->iccp_name);
563
0
      png_free(png_ptr, info_ptr->iccp_profile);
564
0
      info_ptr->iccp_name = NULL;
565
0
      info_ptr->iccp_profile = NULL;
566
0
      info_ptr->valid &= ~PNG_INFO_iCCP;
567
0
   }
568
5.01k
#endif
569
570
5.01k
#ifdef PNG_sPLT_SUPPORTED
571
   /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
572
5.01k
   if (info_ptr->splt_palettes != NULL &&
573
5.01k
       ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
574
59
   {
575
59
      if (num != -1)
576
0
      {
577
0
         png_free(png_ptr, info_ptr->splt_palettes[num].name);
578
0
         png_free(png_ptr, info_ptr->splt_palettes[num].entries);
579
0
         info_ptr->splt_palettes[num].name = NULL;
580
0
         info_ptr->splt_palettes[num].entries = NULL;
581
0
      }
582
583
59
      else
584
59
      {
585
59
         int i;
586
587
460
         for (i = 0; i < info_ptr->splt_palettes_num; i++)
588
401
         {
589
401
            png_free(png_ptr, info_ptr->splt_palettes[i].name);
590
401
            png_free(png_ptr, info_ptr->splt_palettes[i].entries);
591
401
         }
592
593
59
         png_free(png_ptr, info_ptr->splt_palettes);
594
59
         info_ptr->splt_palettes = NULL;
595
59
         info_ptr->splt_palettes_num = 0;
596
59
         info_ptr->valid &= ~PNG_INFO_sPLT;
597
59
      }
598
59
   }
599
5.01k
#endif
600
601
5.01k
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
602
5.01k
   if (info_ptr->unknown_chunks != NULL &&
603
5.01k
       ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
604
0
   {
605
0
      if (num != -1)
606
0
      {
607
0
          png_free(png_ptr, info_ptr->unknown_chunks[num].data);
608
0
          info_ptr->unknown_chunks[num].data = NULL;
609
0
      }
610
611
0
      else
612
0
      {
613
0
         int i;
614
615
0
         for (i = 0; i < info_ptr->unknown_chunks_num; i++)
616
0
            png_free(png_ptr, info_ptr->unknown_chunks[i].data);
617
618
0
         png_free(png_ptr, info_ptr->unknown_chunks);
619
0
         info_ptr->unknown_chunks = NULL;
620
0
         info_ptr->unknown_chunks_num = 0;
621
0
      }
622
0
   }
623
5.01k
#endif
624
625
5.01k
#ifdef PNG_eXIf_SUPPORTED
626
   /* Free any eXIf entry */
627
5.01k
   if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0)
628
22
   {
629
22
      if (info_ptr->exif)
630
22
      {
631
22
         png_free(png_ptr, info_ptr->exif);
632
22
         info_ptr->exif = NULL;
633
22
      }
634
22
      info_ptr->valid &= ~PNG_INFO_eXIf;
635
22
   }
636
5.01k
#endif
637
638
5.01k
#ifdef PNG_hIST_SUPPORTED
639
   /* Free any hIST entry */
640
5.01k
   if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
641
0
   {
642
0
      png_free(png_ptr, info_ptr->hist);
643
0
      info_ptr->hist = NULL;
644
0
      info_ptr->valid &= ~PNG_INFO_hIST;
645
0
   }
646
5.01k
#endif
647
648
   /* Free any PLTE entry that was internally allocated */
649
5.01k
   if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
650
369
   {
651
369
      png_free(png_ptr, info_ptr->palette);
652
369
      info_ptr->palette = NULL;
653
369
      info_ptr->valid &= ~PNG_INFO_PLTE;
654
369
      info_ptr->num_palette = 0;
655
369
   }
656
657
5.01k
#ifdef PNG_INFO_IMAGE_SUPPORTED
658
   /* Free any image bits attached to the info structure */
659
5.01k
   if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
660
0
   {
661
0
      if (info_ptr->row_pointers != NULL)
662
0
      {
663
0
         png_uint_32 row;
664
0
         for (row = 0; row < info_ptr->height; row++)
665
0
            png_free(png_ptr, info_ptr->row_pointers[row]);
666
667
0
         png_free(png_ptr, info_ptr->row_pointers);
668
0
         info_ptr->row_pointers = NULL;
669
0
      }
670
0
      info_ptr->valid &= ~PNG_INFO_IDAT;
671
0
   }
672
5.01k
#endif
673
674
5.01k
   if (num != -1)
675
988
      mask &= ~PNG_FREE_MUL;
676
677
5.01k
   info_ptr->free_me &= ~mask;
678
5.01k
}
679
#endif /* READ || WRITE */
680
681
/* This function returns a pointer to the io_ptr associated with the user
682
 * functions.  The application should free any memory associated with this
683
 * pointer before png_write_destroy() or png_read_destroy() are called.
684
 */
685
png_voidp PNGAPI
686
png_get_io_ptr(png_const_structrp png_ptr)
687
91.1k
{
688
91.1k
   if (png_ptr == NULL)
689
0
      return NULL;
690
691
91.1k
   return png_ptr->io_ptr;
692
91.1k
}
693
694
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
695
#  ifdef PNG_STDIO_SUPPORTED
696
/* Initialize the default input/output functions for the PNG file.  If you
697
 * use your own read or write routines, you can call either png_set_read_fn()
698
 * or png_set_write_fn() instead of png_init_io().  If you have defined
699
 * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
700
 * function of your own because "FILE *" isn't necessarily available.
701
 */
702
void PNGAPI
703
png_init_io(png_structrp png_ptr, FILE *fp)
704
{
705
   png_debug(1, "in png_init_io");
706
707
   if (png_ptr == NULL)
708
      return;
709
710
   png_ptr->io_ptr = (png_voidp)fp;
711
}
712
#  endif
713
714
#  ifdef PNG_SAVE_INT_32_SUPPORTED
715
/* PNG signed integers are saved in 32-bit 2's complement format.  ANSI C-90
716
 * defines a cast of a signed integer to an unsigned integer either to preserve
717
 * the value, if it is positive, or to calculate:
718
 *
719
 *     (UNSIGNED_MAX+1) + integer
720
 *
721
 * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
722
 * negative integral value is added the result will be an unsigned value
723
 * corresponding to the 2's complement representation.
724
 */
725
void PNGAPI
726
png_save_int_32(png_bytep buf, png_int_32 i)
727
{
728
   png_save_uint_32(buf, (png_uint_32)i);
729
}
730
#  endif
731
732
#  ifdef PNG_TIME_RFC1123_SUPPORTED
733
/* Convert the supplied time into an RFC 1123 string suitable for use in
734
 * a "Creation Time" or other text-based time string.
735
 */
736
int PNGAPI
737
png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
738
0
{
739
0
   static const char short_months[12][4] =
740
0
        {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
741
0
         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
742
743
0
   if (out == NULL)
744
0
      return 0;
745
746
0
   if (ptime->year > 9999 /* RFC1123 limitation */ ||
747
0
       ptime->month == 0    ||  ptime->month > 12  ||
748
0
       ptime->day   == 0    ||  ptime->day   > 31  ||
749
0
       ptime->hour  > 23    ||  ptime->minute > 59 ||
750
0
       ptime->second > 60)
751
0
      return 0;
752
753
0
   {
754
0
      size_t pos = 0;
755
0
      char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */
756
757
0
#     define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
758
0
#     define APPEND_NUMBER(format, value)\
759
0
         APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
760
0
#     define APPEND(ch) if (pos < 28) out[pos++] = (ch)
761
762
0
      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
763
0
      APPEND(' ');
764
0
      APPEND_STRING(short_months[(ptime->month - 1)]);
765
0
      APPEND(' ');
766
0
      APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
767
0
      APPEND(' ');
768
0
      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
769
0
      APPEND(':');
770
0
      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
771
0
      APPEND(':');
772
0
      APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
773
0
      APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
774
0
      PNG_UNUSED (pos)
775
776
0
#     undef APPEND
777
0
#     undef APPEND_NUMBER
778
0
#     undef APPEND_STRING
779
0
   }
780
781
0
   return 1;
782
0
}
783
784
#    if PNG_LIBPNG_VER < 10700
785
/* To do: remove the following from libpng-1.7 */
786
/* Original API that uses a private buffer in png_struct.
787
 * Deprecated because it causes png_struct to carry a spurious temporary
788
 * buffer (png_struct::time_buffer), better to have the caller pass this in.
789
 */
790
png_const_charp PNGAPI
791
png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
792
0
{
793
0
   if (png_ptr != NULL)
794
0
   {
795
      /* The only failure above if png_ptr != NULL is from an invalid ptime */
796
0
      if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0)
797
0
         png_warning(png_ptr, "Ignoring invalid time value");
798
799
0
      else
800
0
         return png_ptr->time_buffer;
801
0
   }
802
803
0
   return NULL;
804
0
}
805
#    endif /* LIBPNG_VER < 10700 */
806
#  endif /* TIME_RFC1123 */
807
808
#endif /* READ || WRITE */
809
810
png_const_charp PNGAPI
811
png_get_copyright(png_const_structrp png_ptr)
812
0
{
813
0
   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
814
#ifdef PNG_STRING_COPYRIGHT
815
   return PNG_STRING_COPYRIGHT
816
#else
817
0
   return PNG_STRING_NEWLINE \
818
0
      "libpng version 1.6.48" PNG_STRING_NEWLINE \
819
0
      "Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \
820
0
      "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
821
0
      PNG_STRING_NEWLINE \
822
0
      "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
823
0
      "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
824
0
      PNG_STRING_NEWLINE;
825
0
#endif
826
0
}
827
828
/* The following return the library version as a short string in the
829
 * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
830
 * used with your application, print out PNG_LIBPNG_VER_STRING, which
831
 * is defined in png.h.
832
 * Note: now there is no difference between png_get_libpng_ver() and
833
 * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
834
 * it is guaranteed that png.c uses the correct version of png.h.
835
 */
836
png_const_charp PNGAPI
837
png_get_libpng_ver(png_const_structrp png_ptr)
838
0
{
839
   /* Version of *.c files used when building libpng */
840
0
   return png_get_header_ver(png_ptr);
841
0
}
842
843
png_const_charp PNGAPI
844
png_get_header_ver(png_const_structrp png_ptr)
845
0
{
846
   /* Version of *.h files used when building libpng */
847
0
   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
848
0
   return PNG_LIBPNG_VER_STRING;
849
0
}
850
851
png_const_charp PNGAPI
852
png_get_header_version(png_const_structrp png_ptr)
853
0
{
854
   /* Returns longer string containing both version and date */
855
0
   PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
856
0
#ifdef __STDC__
857
0
   return PNG_HEADER_VERSION_STRING
858
#  ifndef PNG_READ_SUPPORTED
859
      " (NO READ SUPPORT)"
860
#  endif
861
0
      PNG_STRING_NEWLINE;
862
#else
863
   return PNG_HEADER_VERSION_STRING;
864
#endif
865
0
}
866
867
#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
868
/* NOTE: this routine is not used internally! */
869
/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
870
 * large of png_color.  This lets grayscale images be treated as
871
 * paletted.  Most useful for gamma correction and simplification
872
 * of code.  This API is not used internally.
873
 */
874
void PNGAPI
875
png_build_grayscale_palette(int bit_depth, png_colorp palette)
876
0
{
877
0
   int num_palette;
878
0
   int color_inc;
879
0
   int i;
880
0
   int v;
881
882
0
   png_debug(1, "in png_do_build_grayscale_palette");
883
884
0
   if (palette == NULL)
885
0
      return;
886
887
0
   switch (bit_depth)
888
0
   {
889
0
      case 1:
890
0
         num_palette = 2;
891
0
         color_inc = 0xff;
892
0
         break;
893
894
0
      case 2:
895
0
         num_palette = 4;
896
0
         color_inc = 0x55;
897
0
         break;
898
899
0
      case 4:
900
0
         num_palette = 16;
901
0
         color_inc = 0x11;
902
0
         break;
903
904
0
      case 8:
905
0
         num_palette = 256;
906
0
         color_inc = 1;
907
0
         break;
908
909
0
      default:
910
0
         num_palette = 0;
911
0
         color_inc = 0;
912
0
         break;
913
0
   }
914
915
0
   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
916
0
   {
917
0
      palette[i].red = (png_byte)(v & 0xff);
918
0
      palette[i].green = (png_byte)(v & 0xff);
919
0
      palette[i].blue = (png_byte)(v & 0xff);
920
0
   }
921
0
}
922
#endif
923
924
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
925
int PNGAPI
926
png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
927
35.2k
{
928
   /* Check chunk_name and return "keep" value if it's on the list, else 0 */
929
35.2k
   png_const_bytep p, p_end;
930
931
35.2k
   if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
932
35.2k
      return PNG_HANDLE_CHUNK_AS_DEFAULT;
933
934
0
   p_end = png_ptr->chunk_list;
935
0
   p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
936
937
   /* The code is the fifth byte after each four byte string.  Historically this
938
    * code was always searched from the end of the list, this is no longer
939
    * necessary because the 'set' routine handles duplicate entries correctly.
940
    */
941
0
   do /* num_chunk_list > 0, so at least one */
942
0
   {
943
0
      p -= 5;
944
945
0
      if (memcmp(chunk_name, p, 4) == 0)
946
0
         return p[4];
947
0
   }
948
0
   while (p > p_end);
949
950
   /* This means that known chunks should be processed and unknown chunks should
951
    * be handled according to the value of png_ptr->unknown_default; this can be
952
    * confusing because, as a result, there are two levels of defaulting for
953
    * unknown chunks.
954
    */
955
0
   return PNG_HANDLE_CHUNK_AS_DEFAULT;
956
0
}
957
958
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
959
   defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
960
int /* PRIVATE */
961
png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
962
35.2k
{
963
35.2k
   png_byte chunk_string[5];
964
965
35.2k
   PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
966
35.2k
   return png_handle_as_unknown(png_ptr, chunk_string);
967
35.2k
}
968
#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
969
#endif /* SET_UNKNOWN_CHUNKS */
970
971
#ifdef PNG_READ_SUPPORTED
972
/* This function, added to libpng-1.0.6g, is untested. */
973
int PNGAPI
974
png_reset_zstream(png_structrp png_ptr)
975
0
{
976
0
   if (png_ptr == NULL)
977
0
      return Z_STREAM_ERROR;
978
979
   /* WARNING: this resets the window bits to the maximum! */
980
0
   return inflateReset(&png_ptr->zstream);
981
0
}
982
#endif /* READ */
983
984
/* This function was added to libpng-1.0.7 */
985
png_uint_32 PNGAPI
986
png_access_version_number(void)
987
0
{
988
   /* Version of *.c files used when building libpng */
989
0
   return (png_uint_32)PNG_LIBPNG_VER;
990
0
}
991
992
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
993
/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
994
 * If it doesn't 'ret' is used to set it to something appropriate, even in cases
995
 * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
996
 */
997
void /* PRIVATE */
998
png_zstream_error(png_structrp png_ptr, int ret)
999
2.61k
{
1000
   /* Translate 'ret' into an appropriate error string, priority is given to the
1001
    * one in zstream if set.  This always returns a string, even in cases like
1002
    * Z_OK or Z_STREAM_END where the error code is a success code.
1003
    */
1004
2.61k
   if (png_ptr->zstream.msg == NULL) switch (ret)
1005
1.36k
   {
1006
0
      default:
1007
47
      case Z_OK:
1008
47
         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
1009
47
         break;
1010
1011
1.08k
      case Z_STREAM_END:
1012
         /* Normal exit */
1013
1.08k
         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
1014
1.08k
         break;
1015
1016
0
      case Z_NEED_DICT:
1017
         /* This means the deflate stream did not have a dictionary; this
1018
          * indicates a bogus PNG.
1019
          */
1020
0
         png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
1021
0
         break;
1022
1023
0
      case Z_ERRNO:
1024
         /* gz APIs only: should not happen */
1025
0
         png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
1026
0
         break;
1027
1028
0
      case Z_STREAM_ERROR:
1029
         /* internal libpng error */
1030
0
         png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
1031
0
         break;
1032
1033
0
      case Z_DATA_ERROR:
1034
0
         png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
1035
0
         break;
1036
1037
0
      case Z_MEM_ERROR:
1038
0
         png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
1039
0
         break;
1040
1041
227
      case Z_BUF_ERROR:
1042
         /* End of input or output; not a problem if the caller is doing
1043
          * incremental read or write.
1044
          */
1045
227
         png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
1046
227
         break;
1047
1048
0
      case Z_VERSION_ERROR:
1049
0
         png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
1050
0
         break;
1051
1052
0
      case PNG_UNEXPECTED_ZLIB_RETURN:
1053
         /* Compile errors here mean that zlib now uses the value co-opted in
1054
          * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
1055
          * and change pngpriv.h.  Note that this message is "... return",
1056
          * whereas the default/Z_OK one is "... return code".
1057
          */
1058
0
         png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
1059
0
         break;
1060
1.36k
   }
1061
2.61k
}
1062
1063
#ifdef PNG_COLORSPACE_SUPPORTED
1064
static png_int_32
1065
png_fp_add(png_int_32 addend0, png_int_32 addend1, int *error)
1066
0
{
1067
   /* Safely add two fixed point values setting an error flag and returning 0.5
1068
    * on overflow.
1069
    * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
1070
    * relying on addition of two positive values producing a negative one is not
1071
    * safe.
1072
    */
1073
0
   if (addend0 > 0)
1074
0
   {
1075
0
      if (0x7fffffff - addend0 >= addend1)
1076
0
         return addend0+addend1;
1077
0
   }
1078
0
   else if (addend0 < 0)
1079
0
   {
1080
0
      if (-0x7fffffff - addend0 <= addend1)
1081
0
         return addend0+addend1;
1082
0
   }
1083
0
   else
1084
0
      return addend1;
1085
1086
0
   *error = 1;
1087
0
   return PNG_FP_1/2;
1088
0
}
1089
1090
static png_int_32
1091
png_fp_sub(png_int_32 addend0, png_int_32 addend1, int *error)
1092
0
{
1093
   /* As above but calculate addend0-addend1. */
1094
0
   if (addend1 > 0)
1095
0
   {
1096
0
      if (-0x7fffffff + addend1 <= addend0)
1097
0
         return addend0-addend1;
1098
0
   }
1099
0
   else if (addend1 < 0)
1100
0
   {
1101
0
      if (0x7fffffff + addend1 >= addend0)
1102
0
         return addend0-addend1;
1103
0
   }
1104
0
   else
1105
0
      return addend0;
1106
1107
0
   *error = 1;
1108
0
   return PNG_FP_1/2;
1109
0
}
1110
1111
static int
1112
png_safe_add(png_int_32 *addend0_and_result, png_int_32 addend1,
1113
      png_int_32 addend2)
1114
0
{
1115
   /* Safely add three integers.  Returns 0 on success, 1 on overflow.  Does not
1116
    * set the result on overflow.
1117
    */
1118
0
   int error = 0;
1119
0
   int result = png_fp_add(*addend0_and_result,
1120
0
                           png_fp_add(addend1, addend2, &error),
1121
0
                           &error);
1122
0
   if (!error) *addend0_and_result = result;
1123
0
   return error;
1124
0
}
1125
1126
/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
1127
 * cHRM, as opposed to using chromaticities.  These internal APIs return
1128
 * non-zero on a parameter error.  The X, Y and Z values are required to be
1129
 * positive and less than 1.0.
1130
 */
1131
int /* PRIVATE */
1132
png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
1133
0
{
1134
   /* NOTE: returns 0 on success, 1 means error. */
1135
0
   png_int_32 d, dred, dgreen, dblue, dwhite, whiteX, whiteY;
1136
1137
   /* 'd' in each of the blocks below is just X+Y+Z for each component,
1138
    * x, y and z are X,Y,Z/(X+Y+Z).
1139
    */
1140
0
   d = XYZ->red_X;
1141
0
   if (png_safe_add(&d, XYZ->red_Y, XYZ->red_Z))
1142
0
      return 1;
1143
0
   dred = d;
1144
0
   if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, dred) == 0)
1145
0
      return 1;
1146
0
   if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, dred) == 0)
1147
0
      return 1;
1148
1149
0
   d = XYZ->green_X;
1150
0
   if (png_safe_add(&d, XYZ->green_Y, XYZ->green_Z))
1151
0
      return 1;
1152
0
   dgreen = d;
1153
0
   if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, dgreen) == 0)
1154
0
      return 1;
1155
0
   if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, dgreen) == 0)
1156
0
      return 1;
1157
1158
0
   d = XYZ->blue_X;
1159
0
   if (png_safe_add(&d, XYZ->blue_Y, XYZ->blue_Z))
1160
0
      return 1;
1161
0
   dblue = d;
1162
0
   if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, dblue) == 0)
1163
0
      return 1;
1164
0
   if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, dblue) == 0)
1165
0
      return 1;
1166
1167
   /* The reference white is simply the sum of the end-point (X,Y,Z) vectors so
1168
    * the fillowing calculates (X+Y+Z) of the reference white (media white,
1169
    * encoding white) itself:
1170
    */
1171
0
   d = dblue;
1172
0
   if (png_safe_add(&d, dred, dgreen))
1173
0
      return 1;
1174
0
   dwhite = d;
1175
1176
   /* Find the white X,Y values from the sum of the red, green and blue X,Y
1177
    * values.
1178
    */
1179
0
   d = XYZ->red_X;
1180
0
   if (png_safe_add(&d, XYZ->green_X, XYZ->blue_X))
1181
0
      return 1;
1182
0
   whiteX = d;
1183
1184
0
   d = XYZ->red_Y;
1185
0
   if (png_safe_add(&d, XYZ->green_Y, XYZ->blue_Y))
1186
0
      return 1;
1187
0
   whiteY = d;
1188
1189
0
   if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
1190
0
      return 1;
1191
0
   if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
1192
0
      return 1;
1193
1194
0
   return 0;
1195
0
}
1196
1197
int /* PRIVATE */
1198
png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
1199
0
{
1200
   /* NOTE: returns 0 on success, 1 means error. */
1201
0
   png_fixed_point red_inverse, green_inverse, blue_scale;
1202
0
   png_fixed_point left, right, denominator;
1203
1204
   /* Check xy and, implicitly, z.  Note that wide gamut color spaces typically
1205
    * have end points with 0 tristimulus values (these are impossible end
1206
    * points, but they are used to cover the possible colors).  We check
1207
    * xy->whitey against 5, not 0, to avoid a possible integer overflow.
1208
    *
1209
    * The limits here will *not* accept ACES AP0, where bluey is -7700
1210
    * (-0.0770) because the PNG spec itself requires the xy values to be
1211
    * unsigned.  whitey is also required to be 5 or more to avoid overflow.
1212
    *
1213
    * Instead the upper limits have been relaxed to accomodate ACES AP1 where
1214
    * redz ends up as -600 (-0.006).  ProPhotoRGB was already "in range."
1215
    * The new limit accomodates the AP0 and AP1 ranges for z but not AP0 redy.
1216
    */
1217
0
   const png_fixed_point fpLimit = PNG_FP_1+(PNG_FP_1/10);
1218
0
   if (xy->redx   < 0 || xy->redx > fpLimit) return 1;
1219
0
   if (xy->redy   < 0 || xy->redy > fpLimit-xy->redx) return 1;
1220
0
   if (xy->greenx < 0 || xy->greenx > fpLimit) return 1;
1221
0
   if (xy->greeny < 0 || xy->greeny > fpLimit-xy->greenx) return 1;
1222
0
   if (xy->bluex  < 0 || xy->bluex > fpLimit) return 1;
1223
0
   if (xy->bluey  < 0 || xy->bluey > fpLimit-xy->bluex) return 1;
1224
0
   if (xy->whitex < 0 || xy->whitex > fpLimit) return 1;
1225
0
   if (xy->whitey < 5 || xy->whitey > fpLimit-xy->whitex) return 1;
1226
1227
   /* The reverse calculation is more difficult because the original tristimulus
1228
    * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
1229
    * derived values were recorded in the cHRM chunk;
1230
    * (red,green,blue,white)x(x,y).  This loses one degree of freedom and
1231
    * therefore an arbitrary ninth value has to be introduced to undo the
1232
    * original transformations.
1233
    *
1234
    * Think of the original end-points as points in (X,Y,Z) space.  The
1235
    * chromaticity values (c) have the property:
1236
    *
1237
    *           C
1238
    *   c = ---------
1239
    *       X + Y + Z
1240
    *
1241
    * For each c (x,y,z) from the corresponding original C (X,Y,Z).  Thus the
1242
    * three chromaticity values (x,y,z) for each end-point obey the
1243
    * relationship:
1244
    *
1245
    *   x + y + z = 1
1246
    *
1247
    * This describes the plane in (X,Y,Z) space that intersects each axis at the
1248
    * value 1.0; call this the chromaticity plane.  Thus the chromaticity
1249
    * calculation has scaled each end-point so that it is on the x+y+z=1 plane
1250
    * and chromaticity is the intersection of the vector from the origin to the
1251
    * (X,Y,Z) value with the chromaticity plane.
1252
    *
1253
    * To fully invert the chromaticity calculation we would need the three
1254
    * end-point scale factors, (red-scale, green-scale, blue-scale), but these
1255
    * were not recorded.  Instead we calculated the reference white (X,Y,Z) and
1256
    * recorded the chromaticity of this.  The reference white (X,Y,Z) would have
1257
    * given all three of the scale factors since:
1258
    *
1259
    *    color-C = color-c * color-scale
1260
    *    white-C = red-C + green-C + blue-C
1261
    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
1262
    *
1263
    * But cHRM records only white-x and white-y, so we have lost the white scale
1264
    * factor:
1265
    *
1266
    *    white-C = white-c*white-scale
1267
    *
1268
    * To handle this the inverse transformation makes an arbitrary assumption
1269
    * about white-scale:
1270
    *
1271
    *    Assume: white-Y = 1.0
1272
    *    Hence:  white-scale = 1/white-y
1273
    *    Or:     red-Y + green-Y + blue-Y = 1.0
1274
    *
1275
    * Notice the last statement of the assumption gives an equation in three of
1276
    * the nine values we want to calculate.  8 more equations come from the
1277
    * above routine as summarised at the top above (the chromaticity
1278
    * calculation):
1279
    *
1280
    *    Given: color-x = color-X / (color-X + color-Y + color-Z)
1281
    *    Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
1282
    *
1283
    * This is 9 simultaneous equations in the 9 variables "color-C" and can be
1284
    * solved by Cramer's rule.  Cramer's rule requires calculating 10 9x9 matrix
1285
    * determinants, however this is not as bad as it seems because only 28 of
1286
    * the total of 90 terms in the various matrices are non-zero.  Nevertheless
1287
    * Cramer's rule is notoriously numerically unstable because the determinant
1288
    * calculation involves the difference of large, but similar, numbers.  It is
1289
    * difficult to be sure that the calculation is stable for real world values
1290
    * and it is certain that it becomes unstable where the end points are close
1291
    * together.
1292
    *
1293
    * So this code uses the perhaps slightly less optimal but more
1294
    * understandable and totally obvious approach of calculating color-scale.
1295
    *
1296
    * This algorithm depends on the precision in white-scale and that is
1297
    * (1/white-y), so we can immediately see that as white-y approaches 0 the
1298
    * accuracy inherent in the cHRM chunk drops off substantially.
1299
    *
1300
    * libpng arithmetic: a simple inversion of the above equations
1301
    * ------------------------------------------------------------
1302
    *
1303
    *    white_scale = 1/white-y
1304
    *    white-X = white-x * white-scale
1305
    *    white-Y = 1.0
1306
    *    white-Z = (1 - white-x - white-y) * white_scale
1307
    *
1308
    *    white-C = red-C + green-C + blue-C
1309
    *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
1310
    *
1311
    * This gives us three equations in (red-scale,green-scale,blue-scale) where
1312
    * all the coefficients are now known:
1313
    *
1314
    *    red-x*red-scale + green-x*green-scale + blue-x*blue-scale
1315
    *       = white-x/white-y
1316
    *    red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
1317
    *    red-z*red-scale + green-z*green-scale + blue-z*blue-scale
1318
    *       = (1 - white-x - white-y)/white-y
1319
    *
1320
    * In the last equation color-z is (1 - color-x - color-y) so we can add all
1321
    * three equations together to get an alternative third:
1322
    *
1323
    *    red-scale + green-scale + blue-scale = 1/white-y = white-scale
1324
    *
1325
    * So now we have a Cramer's rule solution where the determinants are just
1326
    * 3x3 - far more tractible.  Unfortunately 3x3 determinants still involve
1327
    * multiplication of three coefficients so we can't guarantee to avoid
1328
    * overflow in the libpng fixed point representation.  Using Cramer's rule in
1329
    * floating point is probably a good choice here, but it's not an option for
1330
    * fixed point.  Instead proceed to simplify the first two equations by
1331
    * eliminating what is likely to be the largest value, blue-scale:
1332
    *
1333
    *    blue-scale = white-scale - red-scale - green-scale
1334
    *
1335
    * Hence:
1336
    *
1337
    *    (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
1338
    *                (white-x - blue-x)*white-scale
1339
    *
1340
    *    (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
1341
    *                1 - blue-y*white-scale
1342
    *
1343
    * And now we can trivially solve for (red-scale,green-scale):
1344
    *
1345
    *    green-scale =
1346
    *                (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
1347
    *                -----------------------------------------------------------
1348
    *                                  green-x - blue-x
1349
    *
1350
    *    red-scale =
1351
    *                1 - blue-y*white-scale - (green-y - blue-y) * green-scale
1352
    *                ---------------------------------------------------------
1353
    *                                  red-y - blue-y
1354
    *
1355
    * Hence:
1356
    *
1357
    *    red-scale =
1358
    *          ( (green-x - blue-x) * (white-y - blue-y) -
1359
    *            (green-y - blue-y) * (white-x - blue-x) ) / white-y
1360
    * -------------------------------------------------------------------------
1361
    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
1362
    *
1363
    *    green-scale =
1364
    *          ( (red-y - blue-y) * (white-x - blue-x) -
1365
    *            (red-x - blue-x) * (white-y - blue-y) ) / white-y
1366
    * -------------------------------------------------------------------------
1367
    *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
1368
    *
1369
    * Accuracy:
1370
    * The input values have 5 decimal digits of accuracy.
1371
    *
1372
    * In the previous implementation the values were all in the range 0 < value
1373
    * < 1, so simple products are in the same range but may need up to 10
1374
    * decimal digits to preserve the original precision and avoid underflow.
1375
    * Because we are using a 32-bit signed representation we cannot match this;
1376
    * the best is a little over 9 decimal digits, less than 10.
1377
    *
1378
    * This range has now been extended to allow values up to 1.1, or 110,000 in
1379
    * fixed point.
1380
    *
1381
    * The approach used here is to preserve the maximum precision within the
1382
    * signed representation.  Because the red-scale calculation above uses the
1383
    * difference between two products of values that must be in the range
1384
    * -1.1..+1.1 it is sufficient to divide the product by 8;
1385
    * ceil(121,000/32767*2).  The factor is irrelevant in the calculation
1386
    * because it is applied to both numerator and denominator.
1387
    *
1388
    * Note that the values of the differences of the products of the
1389
    * chromaticities in the above equations tend to be small, for example for
1390
    * the sRGB chromaticities they are:
1391
    *
1392
    * red numerator:    -0.04751
1393
    * green numerator:  -0.08788
1394
    * denominator:      -0.2241 (without white-y multiplication)
1395
    *
1396
    *  The resultant Y coefficients from the chromaticities of some widely used
1397
    *  color space definitions are (to 15 decimal places):
1398
    *
1399
    *  sRGB
1400
    *    0.212639005871510 0.715168678767756 0.072192315360734
1401
    *  Kodak ProPhoto
1402
    *    0.288071128229293 0.711843217810102 0.000085653960605
1403
    *  Adobe RGB
1404
    *    0.297344975250536 0.627363566255466 0.075291458493998
1405
    *  Adobe Wide Gamut RGB
1406
    *    0.258728243040113 0.724682314948566 0.016589442011321
1407
    */
1408
0
   {
1409
0
      int error = 0;
1410
1411
      /* By the argument above overflow should be impossible here, however the
1412
       * code now simply returns a failure code.  The xy subtracts in the
1413
       * arguments to png_muldiv are *not* checked for overflow because the
1414
       * checks at the start guarantee they are in the range 0..110000 and
1415
       * png_fixed_point is a 32-bit signed number.
1416
       */
1417
0
      if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 8) == 0)
1418
0
         return 1;
1419
0
      if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 8) ==
1420
0
            0)
1421
0
         return 1;
1422
0
      denominator = png_fp_sub(left, right, &error);
1423
0
      if (error) return 1;
1424
1425
      /* Now find the red numerator. */
1426
0
      if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 8) == 0)
1427
0
         return 1;
1428
0
      if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 8) ==
1429
0
            0)
1430
0
         return 1;
1431
1432
      /* Overflow is possible here and it indicates an extreme set of PNG cHRM
1433
       * chunk values.  This calculation actually returns the reciprocal of the
1434
       * scale value because this allows us to delay the multiplication of
1435
       * white-y into the denominator, which tends to produce a small number.
1436
       */
1437
0
      if (png_muldiv(&red_inverse, xy->whitey, denominator,
1438
0
                     png_fp_sub(left, right, &error)) == 0 || error ||
1439
0
          red_inverse <= xy->whitey /* r+g+b scales = white scale */)
1440
0
         return 1;
1441
1442
      /* Similarly for green_inverse: */
1443
0
      if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 8) == 0)
1444
0
         return 1;
1445
0
      if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 8) == 0)
1446
0
         return 1;
1447
0
      if (png_muldiv(&green_inverse, xy->whitey, denominator,
1448
0
                     png_fp_sub(left, right, &error)) == 0 || error ||
1449
0
          green_inverse <= xy->whitey)
1450
0
         return 1;
1451
1452
      /* And the blue scale, the checks above guarantee this can't overflow but
1453
       * it can still produce 0 for extreme cHRM values.
1454
       */
1455
0
      blue_scale = png_fp_sub(png_fp_sub(png_reciprocal(xy->whitey),
1456
0
                                         png_reciprocal(red_inverse), &error),
1457
0
                              png_reciprocal(green_inverse), &error);
1458
0
      if (error || blue_scale <= 0)
1459
0
         return 1;
1460
0
   }
1461
1462
   /* And fill in the png_XYZ.  Again the subtracts are safe because of the
1463
    * checks on the xy values at the start (the subtracts just calculate the
1464
    * corresponding z values.)
1465
    */
1466
0
   if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
1467
0
      return 1;
1468
0
   if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
1469
0
      return 1;
1470
0
   if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
1471
0
       red_inverse) == 0)
1472
0
      return 1;
1473
1474
0
   if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)
1475
0
      return 1;
1476
0
   if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)
1477
0
      return 1;
1478
0
   if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
1479
0
       green_inverse) == 0)
1480
0
      return 1;
1481
1482
0
   if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)
1483
0
      return 1;
1484
0
   if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)
1485
0
      return 1;
1486
0
   if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
1487
0
       PNG_FP_1) == 0)
1488
0
      return 1;
1489
1490
0
   return 0; /*success*/
1491
0
}
1492
#endif /* COLORSPACE */
1493
1494
#ifdef PNG_READ_iCCP_SUPPORTED
1495
/* Error message generation */
1496
static char
1497
png_icc_tag_char(png_uint_32 byte)
1498
48
{
1499
48
   byte &= 0xff;
1500
48
   if (byte >= 32 && byte <= 126)
1501
48
      return (char)byte;
1502
0
   else
1503
0
      return '?';
1504
48
}
1505
1506
static void
1507
png_icc_tag_name(char *name, png_uint_32 tag)
1508
12
{
1509
12
   name[0] = '\'';
1510
12
   name[1] = png_icc_tag_char(tag >> 24);
1511
12
   name[2] = png_icc_tag_char(tag >> 16);
1512
12
   name[3] = png_icc_tag_char(tag >>  8);
1513
12
   name[4] = png_icc_tag_char(tag      );
1514
12
   name[5] = '\'';
1515
12
}
1516
1517
static int
1518
is_ICC_signature_char(png_alloc_size_t it)
1519
90
{
1520
90
   return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
1521
90
      (it >= 97 && it <= 122);
1522
90
}
1523
1524
static int
1525
is_ICC_signature(png_alloc_size_t it)
1526
47
{
1527
47
   return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
1528
47
      is_ICC_signature_char((it >> 16) & 0xff) &&
1529
47
      is_ICC_signature_char((it >> 8) & 0xff) &&
1530
47
      is_ICC_signature_char(it & 0xff);
1531
47
}
1532
1533
static int
1534
png_icc_profile_error(png_const_structrp png_ptr, png_const_charp name,
1535
   png_alloc_size_t value, png_const_charp reason)
1536
47
{
1537
47
   size_t pos;
1538
47
   char message[196]; /* see below for calculation */
1539
1540
47
   pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
1541
47
   pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
1542
47
   pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
1543
47
   if (is_ICC_signature(value) != 0)
1544
12
   {
1545
      /* So 'value' is at most 4 bytes and the following cast is safe */
1546
12
      png_icc_tag_name(message+pos, (png_uint_32)value);
1547
12
      pos += 6; /* total +8; less than the else clause */
1548
12
      message[pos++] = ':';
1549
12
      message[pos++] = ' ';
1550
12
   }
1551
35
#  ifdef PNG_WARNINGS_SUPPORTED
1552
35
   else
1553
35
   {
1554
35
      char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */
1555
1556
35
      pos = png_safecat(message, (sizeof message), pos,
1557
35
          png_format_number(number, number+(sizeof number),
1558
35
          PNG_NUMBER_FORMAT_x, value));
1559
35
      pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */
1560
35
   }
1561
47
#  endif
1562
   /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
1563
47
   pos = png_safecat(message, (sizeof message), pos, reason);
1564
47
   PNG_UNUSED(pos)
1565
1566
47
   png_chunk_benign_error(png_ptr, message);
1567
1568
47
   return 0;
1569
47
}
1570
1571
/* Encoded value of D50 as an ICC XYZNumber.  From the ICC 2010 spec the value
1572
 * is XYZ(0.9642,1.0,0.8249), which scales to:
1573
 *
1574
 *    (63189.8112, 65536, 54060.6464)
1575
 */
1576
static const png_byte D50_nCIEXYZ[12] =
1577
   { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
1578
1579
static int /* bool */
1580
icc_check_length(png_const_structrp png_ptr, png_const_charp name,
1581
   png_uint_32 profile_length)
1582
47
{
1583
47
   if (profile_length < 132)
1584
0
      return png_icc_profile_error(png_ptr, name, profile_length, "too short");
1585
47
   return 1;
1586
47
}
1587
1588
int /* PRIVATE */
1589
png_icc_check_length(png_const_structrp png_ptr, png_const_charp name,
1590
   png_uint_32 profile_length)
1591
47
{
1592
47
   if (!icc_check_length(png_ptr, name, profile_length))
1593
0
      return 0;
1594
1595
   /* This needs to be here because the 'normal' check is in
1596
    * png_decompress_chunk, yet this happens after the attempt to
1597
    * png_malloc_base the required data.  We only need this on read; on write
1598
    * the caller supplies the profile buffer so libpng doesn't allocate it.  See
1599
    * the call to icc_check_length below (the write case).
1600
    */
1601
47
   if (profile_length > png_chunk_max(png_ptr))
1602
30
      return png_icc_profile_error(png_ptr, name, profile_length,
1603
30
            "profile too long");
1604
1605
17
   return 1;
1606
47
}
1607
1608
int /* PRIVATE */
1609
png_icc_check_header(png_const_structrp png_ptr, png_const_charp name,
1610
   png_uint_32 profile_length,
1611
   png_const_bytep profile/* first 132 bytes only */, int color_type)
1612
17
{
1613
17
   png_uint_32 temp;
1614
1615
   /* Length check; this cannot be ignored in this code because profile_length
1616
    * is used later to check the tag table, so even if the profile seems over
1617
    * long profile_length from the caller must be correct.  The caller can fix
1618
    * this up on read or write by just passing in the profile header length.
1619
    */
1620
17
   temp = png_get_uint_32(profile);
1621
17
   if (temp != profile_length)
1622
0
      return png_icc_profile_error(png_ptr, name, temp,
1623
0
          "length does not match profile");
1624
1625
17
   temp = (png_uint_32) (*(profile+8));
1626
17
   if (temp > 3 && (profile_length & 3))
1627
1
      return png_icc_profile_error(png_ptr, name, profile_length,
1628
1
          "invalid length");
1629
1630
16
   temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
1631
16
   if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
1632
16
      profile_length < 132+12*temp) /* truncated tag table */
1633
15
      return png_icc_profile_error(png_ptr, name, temp,
1634
15
          "tag count too large");
1635
1636
   /* The 'intent' must be valid or we can't store it, ICC limits the intent to
1637
    * 16 bits.
1638
    */
1639
1
   temp = png_get_uint_32(profile+64);
1640
1
   if (temp >= 0xffff) /* The ICC limit */
1641
1
      return png_icc_profile_error(png_ptr, name, temp,
1642
1
          "invalid rendering intent");
1643
1644
   /* This is just a warning because the profile may be valid in future
1645
    * versions.
1646
    */
1647
0
   if (temp >= PNG_sRGB_INTENT_LAST)
1648
0
      (void)png_icc_profile_error(png_ptr, name, temp,
1649
0
          "intent outside defined range");
1650
1651
   /* At this point the tag table can't be checked because it hasn't necessarily
1652
    * been loaded; however, various header fields can be checked.  These checks
1653
    * are for values permitted by the PNG spec in an ICC profile; the PNG spec
1654
    * restricts the profiles that can be passed in an iCCP chunk (they must be
1655
    * appropriate to processing PNG data!)
1656
    */
1657
1658
   /* Data checks (could be skipped).  These checks must be independent of the
1659
    * version number; however, the version number doesn't accommodate changes in
1660
    * the header fields (just the known tags and the interpretation of the
1661
    * data.)
1662
    */
1663
0
   temp = png_get_uint_32(profile+36); /* signature 'ascp' */
1664
0
   if (temp != 0x61637370)
1665
0
      return png_icc_profile_error(png_ptr, name, temp,
1666
0
          "invalid signature");
1667
1668
   /* Currently the PCS illuminant/adopted white point (the computational
1669
    * white point) are required to be D50,
1670
    * however the profile contains a record of the illuminant so perhaps ICC
1671
    * expects to be able to change this in the future (despite the rationale in
1672
    * the introduction for using a fixed PCS adopted white.)  Consequently the
1673
    * following is just a warning.
1674
    */
1675
0
   if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
1676
0
      (void)png_icc_profile_error(png_ptr, name, 0/*no tag value*/,
1677
0
          "PCS illuminant is not D50");
1678
1679
   /* The PNG spec requires this:
1680
    * "If the iCCP chunk is present, the image samples conform to the colour
1681
    * space represented by the embedded ICC profile as defined by the
1682
    * International Color Consortium [ICC]. The colour space of the ICC profile
1683
    * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
1684
    * 6), or a greyscale colour space for greyscale images (PNG colour types 0
1685
    * and 4)."
1686
    *
1687
    * This checking code ensures the embedded profile (on either read or write)
1688
    * conforms to the specification requirements.  Notice that an ICC 'gray'
1689
    * color-space profile contains the information to transform the monochrome
1690
    * data to XYZ or L*a*b (according to which PCS the profile uses) and this
1691
    * should be used in preference to the standard libpng K channel replication
1692
    * into R, G and B channels.
1693
    *
1694
    * Previously it was suggested that an RGB profile on grayscale data could be
1695
    * handled.  However it it is clear that using an RGB profile in this context
1696
    * must be an error - there is no specification of what it means.  Thus it is
1697
    * almost certainly more correct to ignore the profile.
1698
    */
1699
0
   temp = png_get_uint_32(profile+16); /* data colour space field */
1700
0
   switch (temp)
1701
0
   {
1702
0
      case 0x52474220: /* 'RGB ' */
1703
0
         if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
1704
0
            return png_icc_profile_error(png_ptr, name, temp,
1705
0
                "RGB color space not permitted on grayscale PNG");
1706
0
         break;
1707
1708
0
      case 0x47524159: /* 'GRAY' */
1709
0
         if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
1710
0
            return png_icc_profile_error(png_ptr, name, temp,
1711
0
                "Gray color space not permitted on RGB PNG");
1712
0
         break;
1713
1714
0
      default:
1715
0
         return png_icc_profile_error(png_ptr, name, temp,
1716
0
             "invalid ICC profile color space");
1717
0
   }
1718
1719
   /* It is up to the application to check that the profile class matches the
1720
    * application requirements; the spec provides no guidance, but it's pretty
1721
    * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
1722
    * ('prtr') or 'spac' (for generic color spaces).  Issue a warning in these
1723
    * cases.  Issue an error for device link or abstract profiles - these don't
1724
    * contain the records necessary to transform the color-space to anything
1725
    * other than the target device (and not even that for an abstract profile).
1726
    * Profiles of these classes may not be embedded in images.
1727
    */
1728
0
   temp = png_get_uint_32(profile+12); /* profile/device class */
1729
0
   switch (temp)
1730
0
   {
1731
0
      case 0x73636e72: /* 'scnr' */
1732
0
      case 0x6d6e7472: /* 'mntr' */
1733
0
      case 0x70727472: /* 'prtr' */
1734
0
      case 0x73706163: /* 'spac' */
1735
         /* All supported */
1736
0
         break;
1737
1738
0
      case 0x61627374: /* 'abst' */
1739
         /* May not be embedded in an image */
1740
0
         return png_icc_profile_error(png_ptr, name, temp,
1741
0
             "invalid embedded Abstract ICC profile");
1742
1743
0
      case 0x6c696e6b: /* 'link' */
1744
         /* DeviceLink profiles cannot be interpreted in a non-device specific
1745
          * fashion, if an app uses the AToB0Tag in the profile the results are
1746
          * undefined unless the result is sent to the intended device,
1747
          * therefore a DeviceLink profile should not be found embedded in a
1748
          * PNG.
1749
          */
1750
0
         return png_icc_profile_error(png_ptr, name, temp,
1751
0
             "unexpected DeviceLink ICC profile class");
1752
1753
0
      case 0x6e6d636c: /* 'nmcl' */
1754
         /* A NamedColor profile is also device specific, however it doesn't
1755
          * contain an AToB0 tag that is open to misinterpretation.  Almost
1756
          * certainly it will fail the tests below.
1757
          */
1758
0
         (void)png_icc_profile_error(png_ptr, name, temp,
1759
0
             "unexpected NamedColor ICC profile class");
1760
0
         break;
1761
1762
0
      default:
1763
         /* To allow for future enhancements to the profile accept unrecognized
1764
          * profile classes with a warning, these then hit the test below on the
1765
          * tag content to ensure they are backward compatible with one of the
1766
          * understood profiles.
1767
          */
1768
0
         (void)png_icc_profile_error(png_ptr, name, temp,
1769
0
             "unrecognized ICC profile class");
1770
0
         break;
1771
0
   }
1772
1773
   /* For any profile other than a device link one the PCS must be encoded
1774
    * either in XYZ or Lab.
1775
    */
1776
0
   temp = png_get_uint_32(profile+20);
1777
0
   switch (temp)
1778
0
   {
1779
0
      case 0x58595a20: /* 'XYZ ' */
1780
0
      case 0x4c616220: /* 'Lab ' */
1781
0
         break;
1782
1783
0
      default:
1784
0
         return png_icc_profile_error(png_ptr, name, temp,
1785
0
             "unexpected ICC PCS encoding");
1786
0
   }
1787
1788
0
   return 1;
1789
0
}
1790
1791
int /* PRIVATE */
1792
png_icc_check_tag_table(png_const_structrp png_ptr, png_const_charp name,
1793
   png_uint_32 profile_length,
1794
   png_const_bytep profile /* header plus whole tag table */)
1795
0
{
1796
0
   png_uint_32 tag_count = png_get_uint_32(profile+128);
1797
0
   png_uint_32 itag;
1798
0
   png_const_bytep tag = profile+132; /* The first tag */
1799
1800
   /* First scan all the tags in the table and add bits to the icc_info value
1801
    * (temporarily in 'tags').
1802
    */
1803
0
   for (itag=0; itag < tag_count; ++itag, tag += 12)
1804
0
   {
1805
0
      png_uint_32 tag_id = png_get_uint_32(tag+0);
1806
0
      png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
1807
0
      png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
1808
1809
      /* The ICC specification does not exclude zero length tags, therefore the
1810
       * start might actually be anywhere if there is no data, but this would be
1811
       * a clear abuse of the intent of the standard so the start is checked for
1812
       * being in range.  All defined tag types have an 8 byte header - a 4 byte
1813
       * type signature then 0.
1814
       */
1815
1816
      /* This is a hard error; potentially it can cause read outside the
1817
       * profile.
1818
       */
1819
0
      if (tag_start > profile_length || tag_length > profile_length - tag_start)
1820
0
         return png_icc_profile_error(png_ptr, name, tag_id,
1821
0
             "ICC profile tag outside profile");
1822
1823
0
      if ((tag_start & 3) != 0)
1824
0
      {
1825
         /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is
1826
          * only a warning here because libpng does not care about the
1827
          * alignment.
1828
          */
1829
0
         (void)png_icc_profile_error(png_ptr, name, tag_id,
1830
0
             "ICC profile tag start not a multiple of 4");
1831
0
      }
1832
0
   }
1833
1834
0
   return 1; /* success, maybe with warnings */
1835
0
}
1836
#endif /* READ_iCCP */
1837
1838
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1839
#if (defined PNG_READ_mDCV_SUPPORTED) || (defined PNG_READ_cHRM_SUPPORTED)
1840
static int
1841
have_chromaticities(png_const_structrp png_ptr)
1842
0
{
1843
   /* Handle new PNGv3 chunks and the precedence rules to determine whether
1844
    * png_struct::chromaticities must be processed.  Only required for RGB to
1845
    * gray.
1846
    *
1847
    * mDCV: this is the mastering colour space and it is independent of the
1848
    *       encoding so it needs to be used regardless of the encoded space.
1849
    *
1850
    * cICP: first in priority but not yet implemented - the chromaticities come
1851
    *       from the 'primaries'.
1852
    *
1853
    * iCCP: not supported by libpng (so ignored)
1854
    *
1855
    * sRGB: the defaults match sRGB
1856
    *
1857
    * cHRM: calculate the coefficients
1858
    */
1859
0
#  ifdef PNG_READ_mDCV_SUPPORTED
1860
0
      if (png_has_chunk(png_ptr, mDCV))
1861
0
         return 1;
1862
0
#     define check_chromaticities 1
1863
0
#  endif /*mDCV*/
1864
1865
0
#  ifdef PNG_READ_sRGB_SUPPORTED
1866
0
      if (png_has_chunk(png_ptr, sRGB))
1867
0
         return 0;
1868
0
#  endif /*sRGB*/
1869
1870
0
#  ifdef PNG_READ_cHRM_SUPPORTED
1871
0
      if (png_has_chunk(png_ptr, cHRM))
1872
0
         return 1;
1873
0
#     define check_chromaticities 1
1874
0
#  endif /*cHRM*/
1875
1876
0
   return 0; /* sRGB defaults */
1877
0
}
1878
#endif /* READ_mDCV || READ_cHRM */
1879
1880
void /* PRIVATE */
1881
png_set_rgb_coefficients(png_structrp png_ptr)
1882
0
{
1883
   /* Set the rgb_to_gray coefficients from the colorspace if available.  Note
1884
    * that '_set' means that png_rgb_to_gray was called **and** it successfully
1885
    * set up the coefficients.
1886
    */
1887
0
   if (png_ptr->rgb_to_gray_coefficients_set == 0)
1888
0
   {
1889
0
#  if check_chromaticities
1890
0
      png_XYZ xyz;
1891
1892
0
      if (have_chromaticities(png_ptr) &&
1893
0
          png_XYZ_from_xy(&xyz, &png_ptr->chromaticities) == 0)
1894
0
      {
1895
         /* png_set_rgb_to_gray has not set the coefficients, get them from the
1896
          * Y * values of the colorspace colorants.
1897
          */
1898
0
         png_fixed_point r = xyz.red_Y;
1899
0
         png_fixed_point g = xyz.green_Y;
1900
0
         png_fixed_point b = xyz.blue_Y;
1901
0
         png_fixed_point total = r+g+b;
1902
1903
0
         if (total > 0 &&
1904
0
            r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
1905
0
            g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
1906
0
            b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
1907
0
            r+g+b <= 32769)
1908
0
         {
1909
            /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
1910
             * all of the coefficients were rounded up.  Handle this by
1911
             * reducing the *largest* coefficient by 1; this matches the
1912
             * approach used for the default coefficients in pngrtran.c
1913
             */
1914
0
            int add = 0;
1915
1916
0
            if (r+g+b > 32768)
1917
0
               add = -1;
1918
0
            else if (r+g+b < 32768)
1919
0
               add = 1;
1920
1921
0
            if (add != 0)
1922
0
            {
1923
0
               if (g >= r && g >= b)
1924
0
                  g += add;
1925
0
               else if (r >= g && r >= b)
1926
0
                  r += add;
1927
0
               else
1928
0
                  b += add;
1929
0
            }
1930
1931
            /* Check for an internal error. */
1932
0
            if (r+g+b != 32768)
1933
0
               png_error(png_ptr,
1934
0
                   "internal error handling cHRM coefficients");
1935
1936
0
            else
1937
0
            {
1938
0
               png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
1939
0
               png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
1940
0
            }
1941
0
         }
1942
0
      }
1943
0
      else
1944
0
#  endif /* check_chromaticities */
1945
0
      {
1946
         /* Use the historical REC 709 (etc) values: */
1947
0
         png_ptr->rgb_to_gray_red_coeff   = 6968;
1948
0
         png_ptr->rgb_to_gray_green_coeff = 23434;
1949
         /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
1950
0
      }
1951
0
   }
1952
0
}
1953
#endif /* READ_RGB_TO_GRAY */
1954
1955
void /* PRIVATE */
1956
png_check_IHDR(png_const_structrp png_ptr,
1957
    png_uint_32 width, png_uint_32 height, int bit_depth,
1958
    int color_type, int interlace_type, int compression_type,
1959
    int filter_type)
1960
3.17k
{
1961
3.17k
   int error = 0;
1962
1963
   /* Check for width and height valid values */
1964
3.17k
   if (width == 0)
1965
2
   {
1966
2
      png_warning(png_ptr, "Image width is zero in IHDR");
1967
2
      error = 1;
1968
2
   }
1969
1970
3.17k
   if (width > PNG_UINT_31_MAX)
1971
0
   {
1972
0
      png_warning(png_ptr, "Invalid image width in IHDR");
1973
0
      error = 1;
1974
0
   }
1975
1976
   /* The bit mask on the first line below must be at least as big as a
1977
    * png_uint_32.  "~7U" is not adequate on 16-bit systems because it will
1978
    * be an unsigned 16-bit value.  Casting to (png_alloc_size_t) makes the
1979
    * type of the result at least as bit (in bits) as the RHS of the > operator
1980
    * which also avoids a common warning on 64-bit systems that the comparison
1981
    * of (png_uint_32) against the constant value on the RHS will always be
1982
    * false.
1983
    */
1984
3.17k
   if (((width + 7) & ~(png_alloc_size_t)7) >
1985
3.17k
       (((PNG_SIZE_MAX
1986
3.17k
           - 48        /* big_row_buf hack */
1987
3.17k
           - 1)        /* filter byte */
1988
3.17k
           / 8)        /* 8-byte RGBA pixels */
1989
3.17k
           - 1))       /* extra max_pixel_depth pad */
1990
0
   {
1991
      /* The size of the row must be within the limits of this architecture.
1992
       * Because the read code can perform arbitrary transformations the
1993
       * maximum size is checked here.  Because the code in png_read_start_row
1994
       * adds extra space "for safety's sake" in several places a conservative
1995
       * limit is used here.
1996
       *
1997
       * NOTE: it would be far better to check the size that is actually used,
1998
       * but the effect in the real world is minor and the changes are more
1999
       * extensive, therefore much more dangerous and much more difficult to
2000
       * write in a way that avoids compiler warnings.
2001
       */
2002
0
      png_warning(png_ptr, "Image width is too large for this architecture");
2003
0
      error = 1;
2004
0
   }
2005
2006
3.17k
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
2007
3.17k
   if (width > png_ptr->user_width_max)
2008
#else
2009
   if (width > PNG_USER_WIDTH_MAX)
2010
#endif
2011
1
   {
2012
1
      png_warning(png_ptr, "Image width exceeds user limit in IHDR");
2013
1
      error = 1;
2014
1
   }
2015
2016
3.17k
   if (height == 0)
2017
3
   {
2018
3
      png_warning(png_ptr, "Image height is zero in IHDR");
2019
3
      error = 1;
2020
3
   }
2021
2022
3.17k
   if (height > PNG_UINT_31_MAX)
2023
0
   {
2024
0
      png_warning(png_ptr, "Invalid image height in IHDR");
2025
0
      error = 1;
2026
0
   }
2027
2028
3.17k
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
2029
3.17k
   if (height > png_ptr->user_height_max)
2030
#else
2031
   if (height > PNG_USER_HEIGHT_MAX)
2032
#endif
2033
4
   {
2034
4
      png_warning(png_ptr, "Image height exceeds user limit in IHDR");
2035
4
      error = 1;
2036
4
   }
2037
2038
   /* Check other values */
2039
3.17k
   if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
2040
3.17k
       bit_depth != 8 && bit_depth != 16)
2041
10
   {
2042
10
      png_warning(png_ptr, "Invalid bit depth in IHDR");
2043
10
      error = 1;
2044
10
   }
2045
2046
3.17k
   if (color_type < 0 || color_type == 1 ||
2047
3.17k
       color_type == 5 || color_type > 6)
2048
5
   {
2049
5
      png_warning(png_ptr, "Invalid color type in IHDR");
2050
5
      error = 1;
2051
5
   }
2052
2053
3.17k
   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
2054
3.17k
       ((color_type == PNG_COLOR_TYPE_RGB ||
2055
3.17k
         color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
2056
3.17k
         color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
2057
3
   {
2058
3
      png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
2059
3
      error = 1;
2060
3
   }
2061
2062
3.17k
   if (interlace_type >= PNG_INTERLACE_LAST)
2063
8
   {
2064
8
      png_warning(png_ptr, "Unknown interlace method in IHDR");
2065
8
      error = 1;
2066
8
   }
2067
2068
3.17k
   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
2069
7
   {
2070
7
      png_warning(png_ptr, "Unknown compression method in IHDR");
2071
7
      error = 1;
2072
7
   }
2073
2074
3.17k
#ifdef PNG_MNG_FEATURES_SUPPORTED
2075
   /* Accept filter_method 64 (intrapixel differencing) only if
2076
    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
2077
    * 2. Libpng did not read a PNG signature (this filter_method is only
2078
    *    used in PNG datastreams that are embedded in MNG datastreams) and
2079
    * 3. The application called png_permit_mng_features with a mask that
2080
    *    included PNG_FLAG_MNG_FILTER_64 and
2081
    * 4. The filter_method is 64 and
2082
    * 5. The color_type is RGB or RGBA
2083
    */
2084
3.17k
   if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
2085
3.17k
       png_ptr->mng_features_permitted != 0)
2086
0
      png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
2087
2088
3.17k
   if (filter_type != PNG_FILTER_TYPE_BASE)
2089
7
   {
2090
7
      if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
2091
7
          (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
2092
7
          ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
2093
7
          (color_type == PNG_COLOR_TYPE_RGB ||
2094
0
          color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
2095
7
      {
2096
7
         png_warning(png_ptr, "Unknown filter method in IHDR");
2097
7
         error = 1;
2098
7
      }
2099
2100
7
      if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
2101
0
      {
2102
0
         png_warning(png_ptr, "Invalid filter method in IHDR");
2103
0
         error = 1;
2104
0
      }
2105
7
   }
2106
2107
#else
2108
   if (filter_type != PNG_FILTER_TYPE_BASE)
2109
   {
2110
      png_warning(png_ptr, "Unknown filter method in IHDR");
2111
      error = 1;
2112
   }
2113
#endif
2114
2115
3.17k
   if (error == 1)
2116
14
      png_error(png_ptr, "Invalid IHDR data");
2117
3.17k
}
2118
2119
#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
2120
/* ASCII to fp functions */
2121
/* Check an ASCII formatted floating point value, see the more detailed
2122
 * comments in pngpriv.h
2123
 */
2124
/* The following is used internally to preserve the sticky flags */
2125
9.38k
#define png_fp_add(state, flags) ((state) |= (flags))
2126
1.17k
#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
2127
2128
int /* PRIVATE */
2129
png_check_fp_number(png_const_charp string, size_t size, int *statep,
2130
    size_t *whereami)
2131
1.67k
{
2132
1.67k
   int state = *statep;
2133
1.67k
   size_t i = *whereami;
2134
2135
12.0k
   while (i < size)
2136
11.6k
   {
2137
11.6k
      int type;
2138
      /* First find the type of the next character */
2139
11.6k
      switch (string[i])
2140
11.6k
      {
2141
11
      case 43:  type = PNG_FP_SAW_SIGN;                   break;
2142
699
      case 45:  type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
2143
184
      case 46:  type = PNG_FP_SAW_DOT;                    break;
2144
375
      case 48:  type = PNG_FP_SAW_DIGIT;                  break;
2145
4.42k
      case 49: case 50: case 51: case 52:
2146
6.88k
      case 53: case 54: case 55: case 56:
2147
8.14k
      case 57:  type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
2148
849
      case 69:
2149
1.00k
      case 101: type = PNG_FP_SAW_E;                      break;
2150
1.23k
      default:  goto PNG_FP_End;
2151
11.6k
      }
2152
2153
      /* Now deal with this type according to the current
2154
       * state, the type is arranged to not overlap the
2155
       * bits of the PNG_FP_STATE.
2156
       */
2157
10.4k
      switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
2158
10.4k
      {
2159
20
      case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
2160
20
         if ((state & PNG_FP_SAW_ANY) != 0)
2161
5
            goto PNG_FP_End; /* not a part of the number */
2162
2163
15
         png_fp_add(state, type);
2164
15
         break;
2165
2166
179
      case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
2167
         /* Ok as trailer, ok as lead of fraction. */
2168
179
         if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
2169
1
            goto PNG_FP_End;
2170
2171
178
         else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
2172
172
            png_fp_add(state, type);
2173
2174
6
         else
2175
6
            png_fp_set(state, PNG_FP_FRACTION | type);
2176
2177
178
         break;
2178
2179
6.58k
      case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
2180
6.58k
         if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */
2181
166
            png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
2182
2183
6.58k
         png_fp_add(state, type | PNG_FP_WAS_VALID);
2184
2185
6.58k
         break;
2186
2187
846
      case PNG_FP_INTEGER + PNG_FP_SAW_E:
2188
846
         if ((state & PNG_FP_SAW_DIGIT) == 0)
2189
1
            goto PNG_FP_End;
2190
2191
845
         png_fp_set(state, PNG_FP_EXPONENT);
2192
2193
845
         break;
2194
2195
   /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
2196
         goto PNG_FP_End; ** no sign in fraction */
2197
2198
   /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
2199
         goto PNG_FP_End; ** Because SAW_DOT is always set */
2200
2201
221
      case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
2202
221
         png_fp_add(state, type | PNG_FP_WAS_VALID);
2203
221
         break;
2204
2205
154
      case PNG_FP_FRACTION + PNG_FP_SAW_E:
2206
         /* This is correct because the trailing '.' on an
2207
          * integer is handled above - so we can only get here
2208
          * with the sequence ".E" (with no preceding digits).
2209
          */
2210
154
         if ((state & PNG_FP_SAW_DIGIT) == 0)
2211
1
            goto PNG_FP_End;
2212
2213
153
         png_fp_set(state, PNG_FP_EXPONENT);
2214
2215
153
         break;
2216
2217
689
      case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
2218
689
         if ((state & PNG_FP_SAW_ANY) != 0)
2219
3
            goto PNG_FP_End; /* not a part of the number */
2220
2221
686
         png_fp_add(state, PNG_FP_SAW_SIGN);
2222
2223
686
         break;
2224
2225
   /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
2226
         goto PNG_FP_End; */
2227
2228
1.70k
      case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
2229
1.70k
         png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
2230
2231
1.70k
         break;
2232
2233
   /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
2234
         goto PNG_FP_End; */
2235
2236
15
      default: goto PNG_FP_End; /* I.e. break 2 */
2237
10.4k
      }
2238
2239
      /* The character seems ok, continue. */
2240
10.3k
      ++i;
2241
10.3k
   }
2242
2243
1.67k
PNG_FP_End:
2244
   /* Here at the end, update the state and return the correct
2245
    * return code.
2246
    */
2247
1.67k
   *statep = state;
2248
1.67k
   *whereami = i;
2249
2250
1.67k
   return (state & PNG_FP_SAW_DIGIT) != 0;
2251
1.67k
}
2252
2253
2254
/* The same but for a complete string. */
2255
int
2256
png_check_fp_string(png_const_charp string, size_t size)
2257
364
{
2258
364
   int        state=0;
2259
364
   size_t char_index=0;
2260
2261
364
   if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
2262
364
      (char_index == size || string[char_index] == 0))
2263
318
      return state /* must be non-zero - see above */;
2264
2265
46
   return 0; /* i.e. fail */
2266
364
}
2267
#endif /* pCAL || sCAL */
2268
2269
#ifdef PNG_sCAL_SUPPORTED
2270
#  ifdef PNG_FLOATING_POINT_SUPPORTED
2271
/* Utility used below - a simple accurate power of ten from an integral
2272
 * exponent.
2273
 */
2274
static double
2275
png_pow10(int power)
2276
0
{
2277
0
   int recip = 0;
2278
0
   double d = 1;
2279
2280
   /* Handle negative exponent with a reciprocal at the end because
2281
    * 10 is exact whereas .1 is inexact in base 2
2282
    */
2283
0
   if (power < 0)
2284
0
   {
2285
0
      if (power < DBL_MIN_10_EXP) return 0;
2286
0
      recip = 1; power = -power;
2287
0
   }
2288
2289
0
   if (power > 0)
2290
0
   {
2291
      /* Decompose power bitwise. */
2292
0
      double mult = 10;
2293
0
      do
2294
0
      {
2295
0
         if (power & 1) d *= mult;
2296
0
         mult *= mult;
2297
0
         power >>= 1;
2298
0
      }
2299
0
      while (power > 0);
2300
2301
0
      if (recip != 0) d = 1/d;
2302
0
   }
2303
   /* else power is 0 and d is 1 */
2304
2305
0
   return d;
2306
0
}
2307
2308
/* Function to format a floating point value in ASCII with a given
2309
 * precision.
2310
 */
2311
void /* PRIVATE */
2312
png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
2313
    double fp, unsigned int precision)
2314
0
{
2315
   /* We use standard functions from math.h, but not printf because
2316
    * that would require stdio.  The caller must supply a buffer of
2317
    * sufficient size or we will png_error.  The tests on size and
2318
    * the space in ascii[] consumed are indicated below.
2319
    */
2320
0
   if (precision < 1)
2321
0
      precision = DBL_DIG;
2322
2323
   /* Enforce the limit of the implementation precision too. */
2324
0
   if (precision > DBL_DIG+1)
2325
0
      precision = DBL_DIG+1;
2326
2327
   /* Basic sanity checks */
2328
0
   if (size >= precision+5) /* See the requirements below. */
2329
0
   {
2330
0
      if (fp < 0)
2331
0
      {
2332
0
         fp = -fp;
2333
0
         *ascii++ = 45; /* '-'  PLUS 1 TOTAL 1 */
2334
0
         --size;
2335
0
      }
2336
2337
0
      if (fp >= DBL_MIN && fp <= DBL_MAX)
2338
0
      {
2339
0
         int exp_b10;   /* A base 10 exponent */
2340
0
         double base;   /* 10^exp_b10 */
2341
2342
         /* First extract a base 10 exponent of the number,
2343
          * the calculation below rounds down when converting
2344
          * from base 2 to base 10 (multiply by log10(2) -
2345
          * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
2346
          * be increased.  Note that the arithmetic shift
2347
          * performs a floor() unlike C arithmetic - using a
2348
          * C multiply would break the following for negative
2349
          * exponents.
2350
          */
2351
0
         (void)frexp(fp, &exp_b10); /* exponent to base 2 */
2352
2353
0
         exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
2354
2355
         /* Avoid underflow here. */
2356
0
         base = png_pow10(exp_b10); /* May underflow */
2357
2358
0
         while (base < DBL_MIN || base < fp)
2359
0
         {
2360
            /* And this may overflow. */
2361
0
            double test = png_pow10(exp_b10+1);
2362
2363
0
            if (test <= DBL_MAX)
2364
0
            {
2365
0
               ++exp_b10; base = test;
2366
0
            }
2367
2368
0
            else
2369
0
               break;
2370
0
         }
2371
2372
         /* Normalize fp and correct exp_b10, after this fp is in the
2373
          * range [.1,1) and exp_b10 is both the exponent and the digit
2374
          * *before* which the decimal point should be inserted
2375
          * (starting with 0 for the first digit).  Note that this
2376
          * works even if 10^exp_b10 is out of range because of the
2377
          * test on DBL_MAX above.
2378
          */
2379
0
         fp /= base;
2380
0
         while (fp >= 1)
2381
0
         {
2382
0
            fp /= 10; ++exp_b10;
2383
0
         }
2384
2385
         /* Because of the code above fp may, at this point, be
2386
          * less than .1, this is ok because the code below can
2387
          * handle the leading zeros this generates, so no attempt
2388
          * is made to correct that here.
2389
          */
2390
2391
0
         {
2392
0
            unsigned int czero, clead, cdigits;
2393
0
            char exponent[10];
2394
2395
            /* Allow up to two leading zeros - this will not lengthen
2396
             * the number compared to using E-n.
2397
             */
2398
0
            if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
2399
0
            {
2400
0
               czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */
2401
0
               exp_b10 = 0;      /* Dot added below before first output. */
2402
0
            }
2403
0
            else
2404
0
               czero = 0;    /* No zeros to add */
2405
2406
            /* Generate the digit list, stripping trailing zeros and
2407
             * inserting a '.' before a digit if the exponent is 0.
2408
             */
2409
0
            clead = czero; /* Count of leading zeros */
2410
0
            cdigits = 0;   /* Count of digits in list. */
2411
2412
0
            do
2413
0
            {
2414
0
               double d;
2415
2416
0
               fp *= 10;
2417
               /* Use modf here, not floor and subtract, so that
2418
                * the separation is done in one step.  At the end
2419
                * of the loop don't break the number into parts so
2420
                * that the final digit is rounded.
2421
                */
2422
0
               if (cdigits+czero+1 < precision+clead)
2423
0
                  fp = modf(fp, &d);
2424
2425
0
               else
2426
0
               {
2427
0
                  d = floor(fp + .5);
2428
2429
0
                  if (d > 9)
2430
0
                  {
2431
                     /* Rounding up to 10, handle that here. */
2432
0
                     if (czero > 0)
2433
0
                     {
2434
0
                        --czero; d = 1;
2435
0
                        if (cdigits == 0) --clead;
2436
0
                     }
2437
0
                     else
2438
0
                     {
2439
0
                        while (cdigits > 0 && d > 9)
2440
0
                        {
2441
0
                           int ch = *--ascii;
2442
2443
0
                           if (exp_b10 != (-1))
2444
0
                              ++exp_b10;
2445
2446
0
                           else if (ch == 46)
2447
0
                           {
2448
0
                              ch = *--ascii; ++size;
2449
                              /* Advance exp_b10 to '1', so that the
2450
                               * decimal point happens after the
2451
                               * previous digit.
2452
                               */
2453
0
                              exp_b10 = 1;
2454
0
                           }
2455
2456
0
                           --cdigits;
2457
0
                           d = ch - 47;  /* I.e. 1+(ch-48) */
2458
0
                        }
2459
2460
                        /* Did we reach the beginning? If so adjust the
2461
                         * exponent but take into account the leading
2462
                         * decimal point.
2463
                         */
2464
0
                        if (d > 9)  /* cdigits == 0 */
2465
0
                        {
2466
0
                           if (exp_b10 == (-1))
2467
0
                           {
2468
                              /* Leading decimal point (plus zeros?), if
2469
                               * we lose the decimal point here it must
2470
                               * be reentered below.
2471
                               */
2472
0
                              int ch = *--ascii;
2473
2474
0
                              if (ch == 46)
2475
0
                              {
2476
0
                                 ++size; exp_b10 = 1;
2477
0
                              }
2478
2479
                              /* Else lost a leading zero, so 'exp_b10' is
2480
                               * still ok at (-1)
2481
                               */
2482
0
                           }
2483
0
                           else
2484
0
                              ++exp_b10;
2485
2486
                           /* In all cases we output a '1' */
2487
0
                           d = 1;
2488
0
                        }
2489
0
                     }
2490
0
                  }
2491
0
                  fp = 0; /* Guarantees termination below. */
2492
0
               }
2493
2494
0
               if (d == 0)
2495
0
               {
2496
0
                  ++czero;
2497
0
                  if (cdigits == 0) ++clead;
2498
0
               }
2499
0
               else
2500
0
               {
2501
                  /* Included embedded zeros in the digit count. */
2502
0
                  cdigits += czero - clead;
2503
0
                  clead = 0;
2504
2505
0
                  while (czero > 0)
2506
0
                  {
2507
                     /* exp_b10 == (-1) means we just output the decimal
2508
                      * place - after the DP don't adjust 'exp_b10' any
2509
                      * more!
2510
                      */
2511
0
                     if (exp_b10 != (-1))
2512
0
                     {
2513
0
                        if (exp_b10 == 0)
2514
0
                        {
2515
0
                           *ascii++ = 46; --size;
2516
0
                        }
2517
                        /* PLUS 1: TOTAL 4 */
2518
0
                        --exp_b10;
2519
0
                     }
2520
0
                     *ascii++ = 48; --czero;
2521
0
                  }
2522
2523
0
                  if (exp_b10 != (-1))
2524
0
                  {
2525
0
                     if (exp_b10 == 0)
2526
0
                     {
2527
0
                        *ascii++ = 46; --size; /* counted above */
2528
0
                     }
2529
2530
0
                     --exp_b10;
2531
0
                  }
2532
0
                  *ascii++ = (char)(48 + (int)d); ++cdigits;
2533
0
               }
2534
0
            }
2535
0
            while (cdigits+czero < precision+clead && fp > DBL_MIN);
2536
2537
            /* The total output count (max) is now 4+precision */
2538
2539
            /* Check for an exponent, if we don't need one we are
2540
             * done and just need to terminate the string.  At this
2541
             * point, exp_b10==(-1) is effectively a flag: it got
2542
             * to '-1' because of the decrement, after outputting
2543
             * the decimal point above. (The exponent required is
2544
             * *not* -1.)
2545
             */
2546
0
            if (exp_b10 >= (-1) && exp_b10 <= 2)
2547
0
            {
2548
               /* The following only happens if we didn't output the
2549
                * leading zeros above for negative exponent, so this
2550
                * doesn't add to the digit requirement.  Note that the
2551
                * two zeros here can only be output if the two leading
2552
                * zeros were *not* output, so this doesn't increase
2553
                * the output count.
2554
                */
2555
0
               while (exp_b10-- > 0) *ascii++ = 48;
2556
2557
0
               *ascii = 0;
2558
2559
               /* Total buffer requirement (including the '\0') is
2560
                * 5+precision - see check at the start.
2561
                */
2562
0
               return;
2563
0
            }
2564
2565
            /* Here if an exponent is required, adjust size for
2566
             * the digits we output but did not count.  The total
2567
             * digit output here so far is at most 1+precision - no
2568
             * decimal point and no leading or trailing zeros have
2569
             * been output.
2570
             */
2571
0
            size -= cdigits;
2572
2573
0
            *ascii++ = 69; --size;    /* 'E': PLUS 1 TOTAL 2+precision */
2574
2575
            /* The following use of an unsigned temporary avoids ambiguities in
2576
             * the signed arithmetic on exp_b10 and permits GCC at least to do
2577
             * better optimization.
2578
             */
2579
0
            {
2580
0
               unsigned int uexp_b10;
2581
2582
0
               if (exp_b10 < 0)
2583
0
               {
2584
0
                  *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */
2585
0
                  uexp_b10 = 0U-exp_b10;
2586
0
               }
2587
2588
0
               else
2589
0
                  uexp_b10 = 0U+exp_b10;
2590
2591
0
               cdigits = 0;
2592
2593
0
               while (uexp_b10 > 0)
2594
0
               {
2595
0
                  exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
2596
0
                  uexp_b10 /= 10;
2597
0
               }
2598
0
            }
2599
2600
            /* Need another size check here for the exponent digits, so
2601
             * this need not be considered above.
2602
             */
2603
0
            if (size > cdigits)
2604
0
            {
2605
0
               while (cdigits > 0) *ascii++ = exponent[--cdigits];
2606
2607
0
               *ascii = 0;
2608
2609
0
               return;
2610
0
            }
2611
0
         }
2612
0
      }
2613
0
      else if (!(fp >= DBL_MIN))
2614
0
      {
2615
0
         *ascii++ = 48; /* '0' */
2616
0
         *ascii = 0;
2617
0
         return;
2618
0
      }
2619
0
      else
2620
0
      {
2621
0
         *ascii++ = 105; /* 'i' */
2622
0
         *ascii++ = 110; /* 'n' */
2623
0
         *ascii++ = 102; /* 'f' */
2624
0
         *ascii = 0;
2625
0
         return;
2626
0
      }
2627
0
   }
2628
2629
   /* Here on buffer too small. */
2630
0
   png_error(png_ptr, "ASCII conversion buffer too small");
2631
0
}
2632
#  endif /* FLOATING_POINT */
2633
2634
#  ifdef PNG_FIXED_POINT_SUPPORTED
2635
/* Function to format a fixed point value in ASCII.
2636
 */
2637
void /* PRIVATE */
2638
png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
2639
    size_t size, png_fixed_point fp)
2640
0
{
2641
   /* Require space for 10 decimal digits, a decimal point, a minus sign and a
2642
    * trailing \0, 13 characters:
2643
    */
2644
0
   if (size > 12)
2645
0
   {
2646
0
      png_uint_32 num;
2647
2648
      /* Avoid overflow here on the minimum integer. */
2649
0
      if (fp < 0)
2650
0
      {
2651
0
         *ascii++ = 45; num = (png_uint_32)(-fp);
2652
0
      }
2653
0
      else
2654
0
         num = (png_uint_32)fp;
2655
2656
0
      if (num <= 0x80000000) /* else overflowed */
2657
0
      {
2658
0
         unsigned int ndigits = 0, first = 16 /* flag value */;
2659
0
         char digits[10] = {0};
2660
2661
0
         while (num)
2662
0
         {
2663
            /* Split the low digit off num: */
2664
0
            unsigned int tmp = num/10;
2665
0
            num -= tmp*10;
2666
0
            digits[ndigits++] = (char)(48 + num);
2667
            /* Record the first non-zero digit, note that this is a number
2668
             * starting at 1, it's not actually the array index.
2669
             */
2670
0
            if (first == 16 && num > 0)
2671
0
               first = ndigits;
2672
0
            num = tmp;
2673
0
         }
2674
2675
0
         if (ndigits > 0)
2676
0
         {
2677
0
            while (ndigits > 5) *ascii++ = digits[--ndigits];
2678
            /* The remaining digits are fractional digits, ndigits is '5' or
2679
             * smaller at this point.  It is certainly not zero.  Check for a
2680
             * non-zero fractional digit:
2681
             */
2682
0
            if (first <= 5)
2683
0
            {
2684
0
               unsigned int i;
2685
0
               *ascii++ = 46; /* decimal point */
2686
               /* ndigits may be <5 for small numbers, output leading zeros
2687
                * then ndigits digits to first:
2688
                */
2689
0
               i = 5;
2690
0
               while (ndigits < i)
2691
0
               {
2692
0
                  *ascii++ = 48; --i;
2693
0
               }
2694
0
               while (ndigits >= first) *ascii++ = digits[--ndigits];
2695
               /* Don't output the trailing zeros! */
2696
0
            }
2697
0
         }
2698
0
         else
2699
0
            *ascii++ = 48;
2700
2701
         /* And null terminate the string: */
2702
0
         *ascii = 0;
2703
0
         return;
2704
0
      }
2705
0
   }
2706
2707
   /* Here on buffer too small. */
2708
0
   png_error(png_ptr, "ASCII conversion buffer too small");
2709
0
}
2710
#   endif /* FIXED_POINT */
2711
#endif /* SCAL */
2712
2713
#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
2714
   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
2715
   (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
2716
   defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
2717
   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
2718
   (defined(PNG_sCAL_SUPPORTED) && \
2719
   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
2720
png_fixed_point
2721
png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
2722
0
{
2723
0
   double r = floor(100000 * fp + .5);
2724
2725
0
   if (r > 2147483647. || r < -2147483648.)
2726
0
      png_fixed_error(png_ptr, text);
2727
2728
#  ifndef PNG_ERROR_TEXT_SUPPORTED
2729
   PNG_UNUSED(text)
2730
#  endif
2731
2732
0
   return (png_fixed_point)r;
2733
0
}
2734
#endif
2735
2736
#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
2737
   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
2738
   (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED))
2739
png_uint_32
2740
png_fixed_ITU(png_const_structrp png_ptr, double fp, png_const_charp text)
2741
0
{
2742
0
   double r = floor(10000 * fp + .5);
2743
2744
0
   if (r > 2147483647. || r < 0)
2745
0
      png_fixed_error(png_ptr, text);
2746
2747
#  ifndef PNG_ERROR_TEXT_SUPPORTED
2748
   PNG_UNUSED(text)
2749
#  endif
2750
2751
0
   return (png_uint_32)r;
2752
0
}
2753
#endif
2754
2755
2756
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
2757
    defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
2758
/* muldiv functions */
2759
/* This API takes signed arguments and rounds the result to the nearest
2760
 * integer (or, for a fixed point number - the standard argument - to
2761
 * the nearest .00001).  Overflow and divide by zero are signalled in
2762
 * the result, a boolean - true on success, false on overflow.
2763
 */
2764
int /* PRIVATE */
2765
png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
2766
    png_int_32 divisor)
2767
419
{
2768
   /* Return a * times / divisor, rounded. */
2769
419
   if (divisor != 0)
2770
419
   {
2771
419
      if (a == 0 || times == 0)
2772
0
      {
2773
0
         *res = 0;
2774
0
         return 1;
2775
0
      }
2776
419
      else
2777
419
      {
2778
419
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
2779
419
         double r = a;
2780
419
         r *= times;
2781
419
         r /= divisor;
2782
419
         r = floor(r+.5);
2783
2784
         /* A png_fixed_point is a 32-bit integer. */
2785
419
         if (r <= 2147483647. && r >= -2147483648.)
2786
419
         {
2787
419
            *res = (png_fixed_point)r;
2788
419
            return 1;
2789
419
         }
2790
#else
2791
         int negative = 0;
2792
         png_uint_32 A, T, D;
2793
         png_uint_32 s16, s32, s00;
2794
2795
         if (a < 0)
2796
            negative = 1, A = -a;
2797
         else
2798
            A = a;
2799
2800
         if (times < 0)
2801
            negative = !negative, T = -times;
2802
         else
2803
            T = times;
2804
2805
         if (divisor < 0)
2806
            negative = !negative, D = -divisor;
2807
         else
2808
            D = divisor;
2809
2810
         /* Following can't overflow because the arguments only
2811
          * have 31 bits each, however the result may be 32 bits.
2812
          */
2813
         s16 = (A >> 16) * (T & 0xffff) +
2814
                           (A & 0xffff) * (T >> 16);
2815
         /* Can't overflow because the a*times bit is only 30
2816
          * bits at most.
2817
          */
2818
         s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
2819
         s00 = (A & 0xffff) * (T & 0xffff);
2820
2821
         s16 = (s16 & 0xffff) << 16;
2822
         s00 += s16;
2823
2824
         if (s00 < s16)
2825
            ++s32; /* carry */
2826
2827
         if (s32 < D) /* else overflow */
2828
         {
2829
            /* s32.s00 is now the 64-bit product, do a standard
2830
             * division, we know that s32 < D, so the maximum
2831
             * required shift is 31.
2832
             */
2833
            int bitshift = 32;
2834
            png_fixed_point result = 0; /* NOTE: signed */
2835
2836
            while (--bitshift >= 0)
2837
            {
2838
               png_uint_32 d32, d00;
2839
2840
               if (bitshift > 0)
2841
                  d32 = D >> (32-bitshift), d00 = D << bitshift;
2842
2843
               else
2844
                  d32 = 0, d00 = D;
2845
2846
               if (s32 > d32)
2847
               {
2848
                  if (s00 < d00) --s32; /* carry */
2849
                  s32 -= d32, s00 -= d00, result += 1<<bitshift;
2850
               }
2851
2852
               else
2853
                  if (s32 == d32 && s00 >= d00)
2854
                     s32 = 0, s00 -= d00, result += 1<<bitshift;
2855
            }
2856
2857
            /* Handle the rounding. */
2858
            if (s00 >= (D >> 1))
2859
               ++result;
2860
2861
            if (negative != 0)
2862
               result = -result;
2863
2864
            /* Check for overflow. */
2865
            if ((negative != 0 && result <= 0) ||
2866
                (negative == 0 && result >= 0))
2867
            {
2868
               *res = result;
2869
               return 1;
2870
            }
2871
         }
2872
#endif
2873
419
      }
2874
419
   }
2875
2876
0
   return 0;
2877
419
}
2878
2879
/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
2880
png_fixed_point
2881
png_reciprocal(png_fixed_point a)
2882
1.30k
{
2883
1.30k
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
2884
1.30k
   double r = floor(1E10/a+.5);
2885
2886
1.30k
   if (r <= 2147483647. && r >= -2147483648.)
2887
1.29k
      return (png_fixed_point)r;
2888
#else
2889
   png_fixed_point res;
2890
2891
   if (png_muldiv(&res, 100000, 100000, a) != 0)
2892
      return res;
2893
#endif
2894
2895
1
   return 0; /* error/overflow */
2896
1.30k
}
2897
#endif /* READ_GAMMA || COLORSPACE || INCH_CONVERSIONS || READ_pHYS */
2898
2899
#ifdef PNG_READ_GAMMA_SUPPORTED
2900
/* This is the shared test on whether a gamma value is 'significant' - whether
2901
 * it is worth doing gamma correction.
2902
 */
2903
int /* PRIVATE */
2904
png_gamma_significant(png_fixed_point gamma_val)
2905
1.94k
{
2906
   /* sRGB:       1/2.2 == 0.4545(45)
2907
    * AdobeRGB:   1/(2+51/256) ~= 0.45471 5dp
2908
    *
2909
    * So the correction from AdobeRGB to sRGB (output) is:
2910
    *
2911
    *    2.2/(2+51/256) == 1.00035524
2912
    *
2913
    * I.e. vanishly small (<4E-4) but still detectable in 16-bit linear (+/-
2914
    * 23).  Note that the Adobe choice seems to be something intended to give an
2915
    * exact number with 8 binary fractional digits - it is the closest to 2.2
2916
    * that is possible a base 2 .8p representation.
2917
    */
2918
1.94k
   return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
2919
1.94k
       gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
2920
1.94k
}
2921
2922
#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
2923
/* A local convenience routine. */
2924
static png_fixed_point
2925
png_product2(png_fixed_point a, png_fixed_point b)
2926
{
2927
   /* The required result is a * b; the following preserves accuracy. */
2928
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED /* Should now be unused */
2929
   double r = a * 1E-5;
2930
   r *= b;
2931
   r = floor(r+.5);
2932
2933
   if (r <= 2147483647. && r >= -2147483648.)
2934
      return (png_fixed_point)r;
2935
#else
2936
   png_fixed_point res;
2937
2938
   if (png_muldiv(&res, a, b, 100000) != 0)
2939
      return res;
2940
#endif
2941
2942
   return 0; /* overflow */
2943
}
2944
#endif /* FLOATING_ARITHMETIC */
2945
2946
png_fixed_point
2947
png_reciprocal2(png_fixed_point a, png_fixed_point b)
2948
177
{
2949
   /* The required result is 1/a * 1/b; the following preserves accuracy. */
2950
177
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
2951
177
   if (a != 0 && b != 0)
2952
177
   {
2953
177
      double r = 1E15/a;
2954
177
      r /= b;
2955
177
      r = floor(r+.5);
2956
2957
177
      if (r <= 2147483647. && r >= -2147483648.)
2958
177
         return (png_fixed_point)r;
2959
177
   }
2960
#else
2961
   /* This may overflow because the range of png_fixed_point isn't symmetric,
2962
    * but this API is only used for the product of file and screen gamma so it
2963
    * doesn't matter that the smallest number it can produce is 1/21474, not
2964
    * 1/100000
2965
    */
2966
   png_fixed_point res = png_product2(a, b);
2967
2968
   if (res != 0)
2969
      return png_reciprocal(res);
2970
#endif
2971
2972
0
   return 0; /* overflow */
2973
177
}
2974
#endif /* READ_GAMMA */
2975
2976
#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */
2977
#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
2978
/* Fixed point gamma.
2979
 *
2980
 * The code to calculate the tables used below can be found in the shell script
2981
 * contrib/tools/intgamma.sh
2982
 *
2983
 * To calculate gamma this code implements fast log() and exp() calls using only
2984
 * fixed point arithmetic.  This code has sufficient precision for either 8-bit
2985
 * or 16-bit sample values.
2986
 *
2987
 * The tables used here were calculated using simple 'bc' programs, but C double
2988
 * precision floating point arithmetic would work fine.
2989
 *
2990
 * 8-bit log table
2991
 *   This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
2992
 *   255, so it's the base 2 logarithm of a normalized 8-bit floating point
2993
 *   mantissa.  The numbers are 32-bit fractions.
2994
 */
2995
static const png_uint_32
2996
png_8bit_l2[128] =
2997
{
2998
   4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
2999
   3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
3000
   3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
3001
   3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
3002
   3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
3003
   2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
3004
   2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
3005
   2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
3006
   2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
3007
   2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
3008
   1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
3009
   1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
3010
   1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
3011
   1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
3012
   1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
3013
   971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
3014
   803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
3015
   639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
3016
   479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
3017
   324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
3018
   172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
3019
   24347096U, 0U
3020
3021
#if 0
3022
   /* The following are the values for 16-bit tables - these work fine for the
3023
    * 8-bit conversions but produce very slightly larger errors in the 16-bit
3024
    * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To
3025
    * use these all the shifts below must be adjusted appropriately.
3026
    */
3027
   65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
3028
   57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
3029
   50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
3030
   43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
3031
   37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
3032
   31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
3033
   25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
3034
   20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
3035
   15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
3036
   10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
3037
   6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
3038
   1119, 744, 372
3039
#endif
3040
};
3041
3042
static png_int_32
3043
png_log8bit(unsigned int x)
3044
{
3045
   unsigned int lg2 = 0;
3046
   /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
3047
    * because the log is actually negate that means adding 1.  The final
3048
    * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
3049
    * input), return -1 for the overflow (log 0) case, - so the result is
3050
    * always at most 19 bits.
3051
    */
3052
   if ((x &= 0xff) == 0)
3053
      return -1;
3054
3055
   if ((x & 0xf0) == 0)
3056
      lg2  = 4, x <<= 4;
3057
3058
   if ((x & 0xc0) == 0)
3059
      lg2 += 2, x <<= 2;
3060
3061
   if ((x & 0x80) == 0)
3062
      lg2 += 1, x <<= 1;
3063
3064
   /* result is at most 19 bits, so this cast is safe: */
3065
   return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
3066
}
3067
3068
/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
3069
 * for 16-bit images we use the most significant 8 bits of the 16-bit value to
3070
 * get an approximation then multiply the approximation by a correction factor
3071
 * determined by the remaining up to 8 bits.  This requires an additional step
3072
 * in the 16-bit case.
3073
 *
3074
 * We want log2(value/65535), we have log2(v'/255), where:
3075
 *
3076
 *    value = v' * 256 + v''
3077
 *          = v' * f
3078
 *
3079
 * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
3080
 * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
3081
 * than 258.  The final factor also needs to correct for the fact that our 8-bit
3082
 * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
3083
 *
3084
 * This gives a final formula using a calculated value 'x' which is value/v' and
3085
 * scaling by 65536 to match the above table:
3086
 *
3087
 *   log2(x/257) * 65536
3088
 *
3089
 * Since these numbers are so close to '1' we can use simple linear
3090
 * interpolation between the two end values 256/257 (result -368.61) and 258/257
3091
 * (result 367.179).  The values used below are scaled by a further 64 to give
3092
 * 16-bit precision in the interpolation:
3093
 *
3094
 * Start (256): -23591
3095
 * Zero  (257):      0
3096
 * End   (258):  23499
3097
 */
3098
#ifdef PNG_16BIT_SUPPORTED
3099
static png_int_32
3100
png_log16bit(png_uint_32 x)
3101
{
3102
   unsigned int lg2 = 0;
3103
3104
   /* As above, but now the input has 16 bits. */
3105
   if ((x &= 0xffff) == 0)
3106
      return -1;
3107
3108
   if ((x & 0xff00) == 0)
3109
      lg2  = 8, x <<= 8;
3110
3111
   if ((x & 0xf000) == 0)
3112
      lg2 += 4, x <<= 4;
3113
3114
   if ((x & 0xc000) == 0)
3115
      lg2 += 2, x <<= 2;
3116
3117
   if ((x & 0x8000) == 0)
3118
      lg2 += 1, x <<= 1;
3119
3120
   /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
3121
    * value.
3122
    */
3123
   lg2 <<= 28;
3124
   lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
3125
3126
   /* Now we need to interpolate the factor, this requires a division by the top
3127
    * 8 bits.  Do this with maximum precision.
3128
    */
3129
   x = ((x << 16) + (x >> 9)) / (x >> 8);
3130
3131
   /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
3132
    * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
3133
    * 16 bits to interpolate to get the low bits of the result.  Round the
3134
    * answer.  Note that the end point values are scaled by 64 to retain overall
3135
    * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
3136
    * the overall scaling by 6-12.  Round at every step.
3137
    */
3138
   x -= 1U << 24;
3139
3140
   if (x <= 65536U) /* <= '257' */
3141
      lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
3142
3143
   else
3144
      lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
3145
3146
   /* Safe, because the result can't have more than 20 bits: */
3147
   return (png_int_32)((lg2 + 2048) >> 12);
3148
}
3149
#endif /* 16BIT */
3150
3151
/* The 'exp()' case must invert the above, taking a 20-bit fixed point
3152
 * logarithmic value and returning a 16 or 8-bit number as appropriate.  In
3153
 * each case only the low 16 bits are relevant - the fraction - since the
3154
 * integer bits (the top 4) simply determine a shift.
3155
 *
3156
 * The worst case is the 16-bit distinction between 65535 and 65534. This
3157
 * requires perhaps spurious accuracy in the decoding of the logarithm to
3158
 * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance
3159
 * of getting this accuracy in practice.
3160
 *
3161
 * To deal with this the following exp() function works out the exponent of the
3162
 * fractional part of the logarithm by using an accurate 32-bit value from the
3163
 * top four fractional bits then multiplying in the remaining bits.
3164
 */
3165
static const png_uint_32
3166
png_32bit_exp[16] =
3167
{
3168
   /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
3169
   4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
3170
   3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
3171
   2553802834U, 2445529972U, 2341847524U, 2242560872U
3172
};
3173
3174
/* Adjustment table; provided to explain the numbers in the code below. */
3175
#if 0
3176
for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
3177
   11 44937.64284865548751208448
3178
   10 45180.98734845585101160448
3179
    9 45303.31936980687359311872
3180
    8 45364.65110595323018870784
3181
    7 45395.35850361789624614912
3182
    6 45410.72259715102037508096
3183
    5 45418.40724413220722311168
3184
    4 45422.25021786898173001728
3185
    3 45424.17186732298419044352
3186
    2 45425.13273269940811464704
3187
    1 45425.61317555035558641664
3188
    0 45425.85339951654943850496
3189
#endif
3190
3191
static png_uint_32
3192
png_exp(png_fixed_point x)
3193
{
3194
   if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
3195
   {
3196
      /* Obtain a 4-bit approximation */
3197
      png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f];
3198
3199
      /* Incorporate the low 12 bits - these decrease the returned value by
3200
       * multiplying by a number less than 1 if the bit is set.  The multiplier
3201
       * is determined by the above table and the shift. Notice that the values
3202
       * converge on 45426 and this is used to allow linear interpolation of the
3203
       * low bits.
3204
       */
3205
      if (x & 0x800)
3206
         e -= (((e >> 16) * 44938U) +  16U) >> 5;
3207
3208
      if (x & 0x400)
3209
         e -= (((e >> 16) * 45181U) +  32U) >> 6;
3210
3211
      if (x & 0x200)
3212
         e -= (((e >> 16) * 45303U) +  64U) >> 7;
3213
3214
      if (x & 0x100)
3215
         e -= (((e >> 16) * 45365U) + 128U) >> 8;
3216
3217
      if (x & 0x080)
3218
         e -= (((e >> 16) * 45395U) + 256U) >> 9;
3219
3220
      if (x & 0x040)
3221
         e -= (((e >> 16) * 45410U) + 512U) >> 10;
3222
3223
      /* And handle the low 6 bits in a single block. */
3224
      e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
3225
3226
      /* Handle the upper bits of x. */
3227
      e >>= x >> 16;
3228
      return e;
3229
   }
3230
3231
   /* Check for overflow */
3232
   if (x <= 0)
3233
      return png_32bit_exp[0];
3234
3235
   /* Else underflow */
3236
   return 0;
3237
}
3238
3239
static png_byte
3240
png_exp8bit(png_fixed_point lg2)
3241
{
3242
   /* Get a 32-bit value: */
3243
   png_uint_32 x = png_exp(lg2);
3244
3245
   /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the
3246
    * second, rounding, step can't overflow because of the first, subtraction,
3247
    * step.
3248
    */
3249
   x -= x >> 8;
3250
   return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);
3251
}
3252
3253
#ifdef PNG_16BIT_SUPPORTED
3254
static png_uint_16
3255
png_exp16bit(png_fixed_point lg2)
3256
{
3257
   /* Get a 32-bit value: */
3258
   png_uint_32 x = png_exp(lg2);
3259
3260
   /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
3261
   x -= x >> 16;
3262
   return (png_uint_16)((x + 32767U) >> 16);
3263
}
3264
#endif /* 16BIT */
3265
#endif /* FLOATING_ARITHMETIC */
3266
3267
png_byte
3268
png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
3269
35.3k
{
3270
35.3k
   if (value > 0 && value < 255)
3271
35.0k
   {
3272
35.0k
#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
3273
         /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly
3274
          * convert this to a floating point value.  This includes values that
3275
          * would overflow if 'value' were to be converted to 'int'.
3276
          *
3277
          * Apparently GCC, however, does an intermediate conversion to (int)
3278
          * on some (ARM) but not all (x86) platforms, possibly because of
3279
          * hardware FP limitations.  (E.g. if the hardware conversion always
3280
          * assumes the integer register contains a signed value.)  This results
3281
          * in ANSI-C undefined behavior for large values.
3282
          *
3283
          * Other implementations on the same machine might actually be ANSI-C90
3284
          * conformant and therefore compile spurious extra code for the large
3285
          * values.
3286
          *
3287
          * We can be reasonably sure that an unsigned to float conversion
3288
          * won't be faster than an int to float one.  Therefore this code
3289
          * assumes responsibility for the undefined behavior, which it knows
3290
          * can't happen because of the check above.
3291
          *
3292
          * Note the argument to this routine is an (unsigned int) because, on
3293
          * 16-bit platforms, it is assigned a value which might be out of
3294
          * range for an (int); that would result in undefined behavior in the
3295
          * caller if the *argument* ('value') were to be declared (int).
3296
          */
3297
35.0k
         double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5);
3298
35.0k
         return (png_byte)r;
3299
#     else
3300
         png_int_32 lg2 = png_log8bit(value);
3301
         png_fixed_point res;
3302
3303
         if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
3304
            return png_exp8bit(res);
3305
3306
         /* Overflow. */
3307
         value = 0;
3308
#     endif
3309
35.0k
   }
3310
3311
276
   return (png_byte)(value & 0xff);
3312
35.3k
}
3313
3314
#ifdef PNG_16BIT_SUPPORTED
3315
png_uint_16
3316
png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
3317
9.94k
{
3318
9.94k
   if (value > 0 && value < 65535)
3319
9.94k
   {
3320
9.94k
# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
3321
      /* The same (unsigned int)->(double) constraints apply here as above,
3322
       * however in this case the (unsigned int) to (int) conversion can
3323
       * overflow on an ANSI-C90 compliant system so the cast needs to ensure
3324
       * that this is not possible.
3325
       */
3326
9.94k
      double r = floor(65535*pow((png_int_32)value/65535.,
3327
9.94k
          gamma_val*.00001)+.5);
3328
9.94k
      return (png_uint_16)r;
3329
# else
3330
      png_int_32 lg2 = png_log16bit(value);
3331
      png_fixed_point res;
3332
3333
      if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
3334
         return png_exp16bit(res);
3335
3336
      /* Overflow. */
3337
      value = 0;
3338
# endif
3339
9.94k
   }
3340
3341
0
   return (png_uint_16)value;
3342
9.94k
}
3343
#endif /* 16BIT */
3344
3345
/* This does the right thing based on the bit_depth field of the
3346
 * png_struct, interpreting values as 8-bit or 16-bit.  While the result
3347
 * is nominally a 16-bit value if bit depth is 8 then the result is
3348
 * 8-bit (as are the arguments.)
3349
 */
3350
png_uint_16 /* PRIVATE */
3351
png_gamma_correct(png_structrp png_ptr, unsigned int value,
3352
    png_fixed_point gamma_val)
3353
0
{
3354
0
   if (png_ptr->bit_depth == 8)
3355
0
      return png_gamma_8bit_correct(value, gamma_val);
3356
3357
0
#ifdef PNG_16BIT_SUPPORTED
3358
0
   else
3359
0
      return png_gamma_16bit_correct(value, gamma_val);
3360
#else
3361
      /* should not reach this */
3362
      return 0;
3363
#endif /* 16BIT */
3364
0
}
3365
3366
#ifdef PNG_16BIT_SUPPORTED
3367
/* Internal function to build a single 16-bit table - the table consists of
3368
 * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
3369
 * to shift the input values right (or 16-number_of_signifiant_bits).
3370
 *
3371
 * The caller is responsible for ensuring that the table gets cleaned up on
3372
 * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
3373
 * should be somewhere that will be cleaned.
3374
 */
3375
static void
3376
png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
3377
    unsigned int shift, png_fixed_point gamma_val)
3378
0
{
3379
   /* Various values derived from 'shift': */
3380
0
   unsigned int num = 1U << (8U - shift);
3381
0
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
3382
   /* CSE the division and work round wacky GCC warnings (see the comments
3383
    * in png_gamma_8bit_correct for where these come from.)
3384
    */
3385
0
   double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1);
3386
0
#endif
3387
0
   unsigned int max = (1U << (16U - shift)) - 1U;
3388
0
   unsigned int max_by_2 = 1U << (15U - shift);
3389
0
   unsigned int i;
3390
3391
0
   png_uint_16pp table = *ptable =
3392
0
       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
3393
3394
0
   for (i = 0; i < num; i++)
3395
0
   {
3396
0
      png_uint_16p sub_table = table[i] =
3397
0
          (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16)));
3398
3399
      /* The 'threshold' test is repeated here because it can arise for one of
3400
       * the 16-bit tables even if the others don't hit it.
3401
       */
3402
0
      if (png_gamma_significant(gamma_val) != 0)
3403
0
      {
3404
         /* The old code would overflow at the end and this would cause the
3405
          * 'pow' function to return a result >1, resulting in an
3406
          * arithmetic error.  This code follows the spec exactly; ig is
3407
          * the recovered input sample, it always has 8-16 bits.
3408
          *
3409
          * We want input * 65535/max, rounded, the arithmetic fits in 32
3410
          * bits (unsigned) so long as max <= 32767.
3411
          */
3412
0
         unsigned int j;
3413
0
         for (j = 0; j < 256; j++)
3414
0
         {
3415
0
            png_uint_32 ig = (j << (8-shift)) + i;
3416
0
#           ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
3417
               /* Inline the 'max' scaling operation: */
3418
               /* See png_gamma_8bit_correct for why the cast to (int) is
3419
                * required here.
3420
                */
3421
0
               double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5);
3422
0
               sub_table[j] = (png_uint_16)d;
3423
#           else
3424
               if (shift != 0)
3425
                  ig = (ig * 65535U + max_by_2)/max;
3426
3427
               sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
3428
#           endif
3429
0
         }
3430
0
      }
3431
0
      else
3432
0
      {
3433
         /* We must still build a table, but do it the fast way. */
3434
0
         unsigned int j;
3435
3436
0
         for (j = 0; j < 256; j++)
3437
0
         {
3438
0
            png_uint_32 ig = (j << (8-shift)) + i;
3439
3440
0
            if (shift != 0)
3441
0
               ig = (ig * 65535U + max_by_2)/max;
3442
3443
0
            sub_table[j] = (png_uint_16)ig;
3444
0
         }
3445
0
      }
3446
0
   }
3447
0
}
3448
3449
/* NOTE: this function expects the *inverse* of the overall gamma transformation
3450
 * required.
3451
 */
3452
static void
3453
png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
3454
    unsigned int shift, png_fixed_point gamma_val)
3455
39
{
3456
39
   unsigned int num = 1U << (8U - shift);
3457
39
   unsigned int max = (1U << (16U - shift))-1U;
3458
39
   unsigned int i;
3459
39
   png_uint_32 last;
3460
3461
39
   png_uint_16pp table = *ptable =
3462
39
       (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
3463
3464
   /* 'num' is the number of tables and also the number of low bits of low
3465
    * bits of the input 16-bit value used to select a table.  Each table is
3466
    * itself indexed by the high 8 bits of the value.
3467
    */
3468
351
   for (i = 0; i < num; i++)
3469
312
      table[i] = (png_uint_16p)png_malloc(png_ptr,
3470
312
          256 * (sizeof (png_uint_16)));
3471
3472
   /* 'gamma_val' is set to the reciprocal of the value calculated above, so
3473
    * pow(out,g) is an *input* value.  'last' is the last input value set.
3474
    *
3475
    * In the loop 'i' is used to find output values.  Since the output is
3476
    * 8-bit there are only 256 possible values.  The tables are set up to
3477
    * select the closest possible output value for each input by finding
3478
    * the input value at the boundary between each pair of output values
3479
    * and filling the table up to that boundary with the lower output
3480
    * value.
3481
    *
3482
    * The boundary values are 0.5,1.5..253.5,254.5.  Since these are 9-bit
3483
    * values the code below uses a 16-bit value in i; the values start at
3484
    * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
3485
    * entries are filled with 255).  Start i at 128 and fill all 'last'
3486
    * table entries <= 'max'
3487
    */
3488
39
   last = 0;
3489
9.98k
   for (i = 0; i < 255; ++i) /* 8-bit output value */
3490
9.94k
   {
3491
      /* Find the corresponding maximum input value */
3492
9.94k
      png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
3493
3494
      /* Find the boundary value in 16 bits: */
3495
9.94k
      png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
3496
3497
      /* Adjust (round) to (16-shift) bits: */
3498
9.94k
      bound = (bound * max + 32768U)/65535U + 1U;
3499
3500
89.4k
      while (last < bound)
3501
79.5k
      {
3502
79.5k
         table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
3503
79.5k
         last++;
3504
79.5k
      }
3505
9.94k
   }
3506
3507
   /* And fill in the final entries. */
3508
369
   while (last < (num << 8))
3509
330
   {
3510
330
      table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
3511
330
      last++;
3512
330
   }
3513
39
}
3514
#endif /* 16BIT */
3515
3516
/* Build a single 8-bit table: same as the 16-bit case but much simpler (and
3517
 * typically much faster).  Note that libpng currently does no sBIT processing
3518
 * (apparently contrary to the spec) so a 256-entry table is always generated.
3519
 */
3520
static void
3521
png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
3522
    png_fixed_point gamma_val)
3523
138
{
3524
138
   unsigned int i;
3525
138
   png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
3526
3527
138
   if (png_gamma_significant(gamma_val) != 0)
3528
35.4k
      for (i=0; i<256; i++)
3529
35.3k
         table[i] = png_gamma_8bit_correct(i, gamma_val);
3530
3531
0
   else
3532
0
      for (i=0; i<256; ++i)
3533
0
         table[i] = (png_byte)(i & 0xff);
3534
138
}
3535
3536
/* Used from png_read_destroy and below to release the memory used by the gamma
3537
 * tables.
3538
 */
3539
void /* PRIVATE */
3540
png_destroy_gamma_table(png_structrp png_ptr)
3541
2.22k
{
3542
2.22k
   png_free(png_ptr, png_ptr->gamma_table);
3543
2.22k
   png_ptr->gamma_table = NULL;
3544
3545
2.22k
#ifdef PNG_16BIT_SUPPORTED
3546
2.22k
   if (png_ptr->gamma_16_table != NULL)
3547
39
   {
3548
39
      int i;
3549
39
      int istop = (1 << (8 - png_ptr->gamma_shift));
3550
351
      for (i = 0; i < istop; i++)
3551
312
      {
3552
312
         png_free(png_ptr, png_ptr->gamma_16_table[i]);
3553
312
      }
3554
39
   png_free(png_ptr, png_ptr->gamma_16_table);
3555
39
   png_ptr->gamma_16_table = NULL;
3556
39
   }
3557
2.22k
#endif /* 16BIT */
3558
3559
2.22k
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3560
2.22k
   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
3561
2.22k
   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3562
2.22k
   png_free(png_ptr, png_ptr->gamma_from_1);
3563
2.22k
   png_ptr->gamma_from_1 = NULL;
3564
2.22k
   png_free(png_ptr, png_ptr->gamma_to_1);
3565
2.22k
   png_ptr->gamma_to_1 = NULL;
3566
3567
2.22k
#ifdef PNG_16BIT_SUPPORTED
3568
2.22k
   if (png_ptr->gamma_16_from_1 != NULL)
3569
0
   {
3570
0
      int i;
3571
0
      int istop = (1 << (8 - png_ptr->gamma_shift));
3572
0
      for (i = 0; i < istop; i++)
3573
0
      {
3574
0
         png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
3575
0
      }
3576
0
   png_free(png_ptr, png_ptr->gamma_16_from_1);
3577
0
   png_ptr->gamma_16_from_1 = NULL;
3578
0
   }
3579
2.22k
   if (png_ptr->gamma_16_to_1 != NULL)
3580
0
   {
3581
0
      int i;
3582
0
      int istop = (1 << (8 - png_ptr->gamma_shift));
3583
0
      for (i = 0; i < istop; i++)
3584
0
      {
3585
0
         png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
3586
0
      }
3587
0
   png_free(png_ptr, png_ptr->gamma_16_to_1);
3588
0
   png_ptr->gamma_16_to_1 = NULL;
3589
0
   }
3590
2.22k
#endif /* 16BIT */
3591
2.22k
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
3592
2.22k
}
3593
3594
/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
3595
 * tables, we don't make a full table if we are reducing to 8-bit in
3596
 * the future.  Note also how the gamma_16 tables are segmented so that
3597
 * we don't need to allocate > 64K chunks for a full 16-bit table.
3598
 *
3599
 * TODO: move this to pngrtran.c and make it static.  Better yet create
3600
 * pngcolor.c and put all the PNG_COLORSPACE stuff in there.
3601
 */
3602
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3603
   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
3604
   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
3605
#  define GAMMA_TRANSFORMS 1 /* #ifdef CSE */
3606
#else
3607
#  define GAMMA_TRANSFORMS 0
3608
#endif
3609
3610
void /* PRIVATE */
3611
png_build_gamma_table(png_structrp png_ptr, int bit_depth)
3612
177
{
3613
177
   png_fixed_point file_gamma, screen_gamma;
3614
177
   png_fixed_point correction;
3615
177
#  if GAMMA_TRANSFORMS
3616
177
      png_fixed_point file_to_linear, linear_to_screen;
3617
177
#  endif
3618
3619
177
   png_debug(1, "in png_build_gamma_table");
3620
3621
   /* Remove any existing table; this copes with multiple calls to
3622
    * png_read_update_info. The warning is because building the gamma tables
3623
    * multiple times is a performance hit - it's harmless but the ability to
3624
    * call png_read_update_info() multiple times is new in 1.5.6 so it seems
3625
    * sensible to warn if the app introduces such a hit.
3626
    */
3627
177
   if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
3628
0
   {
3629
0
      png_warning(png_ptr, "gamma table being rebuilt");
3630
0
      png_destroy_gamma_table(png_ptr);
3631
0
   }
3632
3633
   /* The following fields are set, finally, in png_init_read_transformations.
3634
    * If file_gamma is 0 (unset) nothing can be done otherwise if screen_gamma
3635
    * is 0 (unset) there is no gamma correction but to/from linear is possible.
3636
    */
3637
177
   file_gamma = png_ptr->file_gamma;
3638
177
   screen_gamma = png_ptr->screen_gamma;
3639
177
#  if GAMMA_TRANSFORMS
3640
177
      file_to_linear = png_reciprocal(file_gamma);
3641
177
#  endif
3642
3643
177
   if (screen_gamma > 0)
3644
177
   {
3645
177
#     if GAMMA_TRANSFORMS
3646
177
         linear_to_screen = png_reciprocal(screen_gamma);
3647
177
#     endif
3648
177
      correction = png_reciprocal2(screen_gamma, file_gamma);
3649
177
   }
3650
0
   else /* screen gamma unknown */
3651
0
   {
3652
0
#     if GAMMA_TRANSFORMS
3653
0
         linear_to_screen = file_gamma;
3654
0
#     endif
3655
0
      correction = PNG_FP_1;
3656
0
   }
3657
3658
177
   if (bit_depth <= 8)
3659
138
   {
3660
138
      png_build_8bit_table(png_ptr, &png_ptr->gamma_table, correction);
3661
3662
138
#if GAMMA_TRANSFORMS
3663
138
      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
3664
0
      {
3665
0
         png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, file_to_linear);
3666
3667
0
         png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
3668
0
            linear_to_screen);
3669
0
      }
3670
138
#endif /* GAMMA_TRANSFORMS */
3671
138
   }
3672
39
#ifdef PNG_16BIT_SUPPORTED
3673
39
   else
3674
39
   {
3675
39
      png_byte shift, sig_bit;
3676
3677
39
      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
3678
20
      {
3679
20
         sig_bit = png_ptr->sig_bit.red;
3680
3681
20
         if (png_ptr->sig_bit.green > sig_bit)
3682
0
            sig_bit = png_ptr->sig_bit.green;
3683
3684
20
         if (png_ptr->sig_bit.blue > sig_bit)
3685
0
            sig_bit = png_ptr->sig_bit.blue;
3686
20
      }
3687
19
      else
3688
19
         sig_bit = png_ptr->sig_bit.gray;
3689
3690
      /* 16-bit gamma code uses this equation:
3691
       *
3692
       *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
3693
       *
3694
       * Where 'iv' is the input color value and 'ov' is the output value -
3695
       * pow(iv, gamma).
3696
       *
3697
       * Thus the gamma table consists of up to 256 256-entry tables.  The table
3698
       * is selected by the (8-gamma_shift) most significant of the low 8 bits
3699
       * of the color value then indexed by the upper 8 bits:
3700
       *
3701
       *   table[low bits][high 8 bits]
3702
       *
3703
       * So the table 'n' corresponds to all those 'iv' of:
3704
       *
3705
       *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
3706
       *
3707
       */
3708
39
      if (sig_bit > 0 && sig_bit < 16U)
3709
         /* shift == insignificant bits */
3710
0
         shift = (png_byte)((16U - sig_bit) & 0xff);
3711
3712
39
      else
3713
39
         shift = 0; /* keep all 16 bits */
3714
3715
39
      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
3716
39
      {
3717
         /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
3718
          * the significant bits in the *input* when the output will
3719
          * eventually be 8 bits.  By default it is 11.
3720
          */
3721
39
         if (shift < (16U - PNG_MAX_GAMMA_8))
3722
39
            shift = (16U - PNG_MAX_GAMMA_8);
3723
39
      }
3724
3725
39
      if (shift > 8U)
3726
0
         shift = 8U; /* Guarantees at least one table! */
3727
3728
39
      png_ptr->gamma_shift = shift;
3729
3730
      /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
3731
       * PNG_COMPOSE).  This effectively smashed the background calculation for
3732
       * 16-bit output because the 8-bit table assumes the result will be
3733
       * reduced to 8 bits.
3734
       */
3735
39
      if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
3736
39
         png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
3737
39
            png_reciprocal(correction));
3738
0
      else
3739
0
         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
3740
0
            correction);
3741
3742
39
#  if GAMMA_TRANSFORMS
3743
39
      if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
3744
0
      {
3745
0
         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
3746
0
            file_to_linear);
3747
3748
         /* Notice that the '16 from 1' table should be full precision, however
3749
          * the lookup on this table still uses gamma_shift, so it can't be.
3750
          * TODO: fix this.
3751
          */
3752
0
         png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
3753
0
            linear_to_screen);
3754
0
      }
3755
39
#endif /* GAMMA_TRANSFORMS */
3756
39
   }
3757
177
#endif /* 16BIT */
3758
177
}
3759
#endif /* READ_GAMMA */
3760
3761
/* HARDWARE OR SOFTWARE OPTION SUPPORT */
3762
#ifdef PNG_SET_OPTION_SUPPORTED
3763
int PNGAPI
3764
png_set_option(png_structrp png_ptr, int option, int onoff)
3765
0
{
3766
0
   if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
3767
0
      (option & 1) == 0)
3768
0
   {
3769
0
      png_uint_32 mask = 3U << option;
3770
0
      png_uint_32 setting = (2U + (onoff != 0)) << option;
3771
0
      png_uint_32 current = png_ptr->options;
3772
3773
0
      png_ptr->options = (png_uint_32)((current & ~mask) | setting);
3774
3775
0
      return (int)(current & mask) >> option;
3776
0
   }
3777
3778
0
   return PNG_OPTION_INVALID;
3779
0
}
3780
#endif
3781
3782
/* sRGB support */
3783
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
3784
   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
3785
/* sRGB conversion tables; these are machine generated with the code in
3786
 * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
3787
 * specification (see the article at https://en.wikipedia.org/wiki/SRGB)
3788
 * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
3789
 * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
3790
 * The inverse (linear to sRGB) table has accuracies as follows:
3791
 *
3792
 * For all possible (255*65535+1) input values:
3793
 *
3794
 *    error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
3795
 *
3796
 * For the input values corresponding to the 65536 16-bit values:
3797
 *
3798
 *    error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
3799
 *
3800
 * In all cases the inexact readings are only off by one.
3801
 */
3802
3803
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
3804
/* The convert-to-sRGB table is only currently required for read. */
3805
const png_uint_16 png_sRGB_table[256] =
3806
{
3807
   0,20,40,60,80,99,119,139,
3808
   159,179,199,219,241,264,288,313,
3809
   340,367,396,427,458,491,526,562,
3810
   599,637,677,718,761,805,851,898,
3811
   947,997,1048,1101,1156,1212,1270,1330,
3812
   1391,1453,1517,1583,1651,1720,1790,1863,
3813
   1937,2013,2090,2170,2250,2333,2418,2504,
3814
   2592,2681,2773,2866,2961,3058,3157,3258,
3815
   3360,3464,3570,3678,3788,3900,4014,4129,
3816
   4247,4366,4488,4611,4736,4864,4993,5124,
3817
   5257,5392,5530,5669,5810,5953,6099,6246,
3818
   6395,6547,6700,6856,7014,7174,7335,7500,
3819
   7666,7834,8004,8177,8352,8528,8708,8889,
3820
   9072,9258,9445,9635,9828,10022,10219,10417,
3821
   10619,10822,11028,11235,11446,11658,11873,12090,
3822
   12309,12530,12754,12980,13209,13440,13673,13909,
3823
   14146,14387,14629,14874,15122,15371,15623,15878,
3824
   16135,16394,16656,16920,17187,17456,17727,18001,
3825
   18277,18556,18837,19121,19407,19696,19987,20281,
3826
   20577,20876,21177,21481,21787,22096,22407,22721,
3827
   23038,23357,23678,24002,24329,24658,24990,25325,
3828
   25662,26001,26344,26688,27036,27386,27739,28094,
3829
   28452,28813,29176,29542,29911,30282,30656,31033,
3830
   31412,31794,32179,32567,32957,33350,33745,34143,
3831
   34544,34948,35355,35764,36176,36591,37008,37429,
3832
   37852,38278,38706,39138,39572,40009,40449,40891,
3833
   41337,41785,42236,42690,43147,43606,44069,44534,
3834
   45002,45473,45947,46423,46903,47385,47871,48359,
3835
   48850,49344,49841,50341,50844,51349,51858,52369,
3836
   52884,53401,53921,54445,54971,55500,56032,56567,
3837
   57105,57646,58190,58737,59287,59840,60396,60955,
3838
   61517,62082,62650,63221,63795,64372,64952,65535
3839
};
3840
#endif /* SIMPLIFIED_READ */
3841
3842
/* The base/delta tables are required for both read and write (but currently
3843
 * only the simplified versions.)
3844
 */
3845
const png_uint_16 png_sRGB_base[512] =
3846
{
3847
   128,1782,3383,4644,5675,6564,7357,8074,
3848
   8732,9346,9921,10463,10977,11466,11935,12384,
3849
   12816,13233,13634,14024,14402,14769,15125,15473,
3850
   15812,16142,16466,16781,17090,17393,17690,17981,
3851
   18266,18546,18822,19093,19359,19621,19879,20133,
3852
   20383,20630,20873,21113,21349,21583,21813,22041,
3853
   22265,22487,22707,22923,23138,23350,23559,23767,
3854
   23972,24175,24376,24575,24772,24967,25160,25352,
3855
   25542,25730,25916,26101,26284,26465,26645,26823,
3856
   27000,27176,27350,27523,27695,27865,28034,28201,
3857
   28368,28533,28697,28860,29021,29182,29341,29500,
3858
   29657,29813,29969,30123,30276,30429,30580,30730,
3859
   30880,31028,31176,31323,31469,31614,31758,31902,
3860
   32045,32186,32327,32468,32607,32746,32884,33021,
3861
   33158,33294,33429,33564,33697,33831,33963,34095,
3862
   34226,34357,34486,34616,34744,34873,35000,35127,
3863
   35253,35379,35504,35629,35753,35876,35999,36122,
3864
   36244,36365,36486,36606,36726,36845,36964,37083,
3865
   37201,37318,37435,37551,37668,37783,37898,38013,
3866
   38127,38241,38354,38467,38580,38692,38803,38915,
3867
   39026,39136,39246,39356,39465,39574,39682,39790,
3868
   39898,40005,40112,40219,40325,40431,40537,40642,
3869
   40747,40851,40955,41059,41163,41266,41369,41471,
3870
   41573,41675,41777,41878,41979,42079,42179,42279,
3871
   42379,42478,42577,42676,42775,42873,42971,43068,
3872
   43165,43262,43359,43456,43552,43648,43743,43839,
3873
   43934,44028,44123,44217,44311,44405,44499,44592,
3874
   44685,44778,44870,44962,45054,45146,45238,45329,
3875
   45420,45511,45601,45692,45782,45872,45961,46051,
3876
   46140,46229,46318,46406,46494,46583,46670,46758,
3877
   46846,46933,47020,47107,47193,47280,47366,47452,
3878
   47538,47623,47709,47794,47879,47964,48048,48133,
3879
   48217,48301,48385,48468,48552,48635,48718,48801,
3880
   48884,48966,49048,49131,49213,49294,49376,49458,
3881
   49539,49620,49701,49782,49862,49943,50023,50103,
3882
   50183,50263,50342,50422,50501,50580,50659,50738,
3883
   50816,50895,50973,51051,51129,51207,51285,51362,
3884
   51439,51517,51594,51671,51747,51824,51900,51977,
3885
   52053,52129,52205,52280,52356,52432,52507,52582,
3886
   52657,52732,52807,52881,52956,53030,53104,53178,
3887
   53252,53326,53400,53473,53546,53620,53693,53766,
3888
   53839,53911,53984,54056,54129,54201,54273,54345,
3889
   54417,54489,54560,54632,54703,54774,54845,54916,
3890
   54987,55058,55129,55199,55269,55340,55410,55480,
3891
   55550,55620,55689,55759,55828,55898,55967,56036,
3892
   56105,56174,56243,56311,56380,56448,56517,56585,
3893
   56653,56721,56789,56857,56924,56992,57059,57127,
3894
   57194,57261,57328,57395,57462,57529,57595,57662,
3895
   57728,57795,57861,57927,57993,58059,58125,58191,
3896
   58256,58322,58387,58453,58518,58583,58648,58713,
3897
   58778,58843,58908,58972,59037,59101,59165,59230,
3898
   59294,59358,59422,59486,59549,59613,59677,59740,
3899
   59804,59867,59930,59993,60056,60119,60182,60245,
3900
   60308,60370,60433,60495,60558,60620,60682,60744,
3901
   60806,60868,60930,60992,61054,61115,61177,61238,
3902
   61300,61361,61422,61483,61544,61605,61666,61727,
3903
   61788,61848,61909,61969,62030,62090,62150,62211,
3904
   62271,62331,62391,62450,62510,62570,62630,62689,
3905
   62749,62808,62867,62927,62986,63045,63104,63163,
3906
   63222,63281,63340,63398,63457,63515,63574,63632,
3907
   63691,63749,63807,63865,63923,63981,64039,64097,
3908
   64155,64212,64270,64328,64385,64443,64500,64557,
3909
   64614,64672,64729,64786,64843,64900,64956,65013,
3910
   65070,65126,65183,65239,65296,65352,65409,65465
3911
};
3912
3913
const png_byte png_sRGB_delta[512] =
3914
{
3915
   207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
3916
   52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
3917
   35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
3918
   28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
3919
   23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
3920
   21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
3921
   19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
3922
   17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
3923
   16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,
3924
   15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,
3925
   14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,
3926
   13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,
3927
   12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
3928
   12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,
3929
   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
3930
   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
3931
   11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
3932
   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
3933
   10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
3934
   10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
3935
   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
3936
   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
3937
   9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
3938
   9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3939
   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3940
   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3941
   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3942
   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3943
   8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,
3944
   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
3945
   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
3946
   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
3947
};
3948
#endif /* SIMPLIFIED READ/WRITE sRGB support */
3949
3950
/* SIMPLIFIED READ/WRITE SUPPORT */
3951
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
3952
   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
3953
static int
3954
png_image_free_function(png_voidp argument)
3955
425
{
3956
425
   png_imagep image = png_voidcast(png_imagep, argument);
3957
425
   png_controlp cp = image->opaque;
3958
425
   png_control c;
3959
3960
   /* Double check that we have a png_ptr - it should be impossible to get here
3961
    * without one.
3962
    */
3963
425
   if (cp->png_ptr == NULL)
3964
0
      return 0;
3965
3966
   /* First free any data held in the control structure. */
3967
#  ifdef PNG_STDIO_SUPPORTED
3968
      if (cp->owned_file != 0)
3969
      {
3970
         FILE *fp = png_voidcast(FILE *, cp->png_ptr->io_ptr);
3971
         cp->owned_file = 0;
3972
3973
         /* Ignore errors here. */
3974
         if (fp != NULL)
3975
         {
3976
            cp->png_ptr->io_ptr = NULL;
3977
            (void)fclose(fp);
3978
         }
3979
      }
3980
#  endif
3981
3982
   /* Copy the control structure so that the original, allocated, version can be
3983
    * safely freed.  Notice that a png_error here stops the remainder of the
3984
    * cleanup, but this is probably fine because that would indicate bad memory
3985
    * problems anyway.
3986
    */
3987
425
   c = *cp;
3988
425
   image->opaque = &c;
3989
425
   png_free(c.png_ptr, cp);
3990
3991
   /* Then the structures, calling the correct API. */
3992
425
   if (c.for_write != 0)
3993
0
   {
3994
#     ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
3995
         png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
3996
#     else
3997
0
         png_error(c.png_ptr, "simplified write not supported");
3998
0
#     endif
3999
0
   }
4000
425
   else
4001
425
   {
4002
425
#     ifdef PNG_SIMPLIFIED_READ_SUPPORTED
4003
425
         png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);
4004
#     else
4005
         png_error(c.png_ptr, "simplified read not supported");
4006
#     endif
4007
425
   }
4008
4009
   /* Success. */
4010
425
   return 1;
4011
425
}
4012
4013
void PNGAPI
4014
png_image_free(png_imagep image)
4015
530
{
4016
   /* Safely call the real function, but only if doing so is safe at this point
4017
    * (if not inside an error handling context).  Otherwise assume
4018
    * png_safe_execute will call this API after the return.
4019
    */
4020
530
   if (image != NULL && image->opaque != NULL &&
4021
530
      image->opaque->error_buf == NULL)
4022
425
   {
4023
425
      png_image_free_function(image);
4024
425
      image->opaque = NULL;
4025
425
   }
4026
530
}
4027
4028
int /* PRIVATE */
4029
png_image_error(png_imagep image, png_const_charp error_message)
4030
0
{
4031
   /* Utility to log an error. */
4032
0
   png_safecat(image->message, (sizeof image->message), 0, error_message);
4033
0
   image->warning_or_error |= PNG_IMAGE_ERROR;
4034
0
   png_image_free(image);
4035
0
   return 0;
4036
0
}
4037
4038
#endif /* SIMPLIFIED READ/WRITE */
4039
#endif /* READ || WRITE */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/png.h.html b/part1/report/w_corpus/src/libpng/png.h.html new file mode 100644 index 0000000..3f671bb --- /dev/null +++ b/part1/report/w_corpus/src/libpng/png.h.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/png.h
Line
Count
Source (jump to first uncovered line)
1
/* png.h - header file for PNG reference library
2
 *
3
 * libpng version 1.6.48
4
 *
5
 * Copyright (c) 2018-2025 Cosmin Truta
6
 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
7
 * Copyright (c) 1996-1997 Andreas Dilger
8
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
9
 *
10
 * This code is released under the libpng license. (See LICENSE, below.)
11
 *
12
 * Authors and maintainers:
13
 *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
14
 *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
15
 *   libpng versions 0.97, January 1998, through 1.6.35, July 2018:
16
 *     Glenn Randers-Pehrson
17
 *   libpng versions 1.6.36, December 2018, through 1.6.48, April 2025:
18
 *     Cosmin Truta
19
 *   See also "Contributing Authors", below.
20
 */
21
22
/*
23
 * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
24
 * =========================================
25
 *
26
 * PNG Reference Library License version 2
27
 * ---------------------------------------
28
 *
29
 *  * Copyright (c) 1995-2025 The PNG Reference Library Authors.
30
 *  * Copyright (c) 2018-2025 Cosmin Truta.
31
 *  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
32
 *  * Copyright (c) 1996-1997 Andreas Dilger.
33
 *  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
34
 *
35
 * The software is supplied "as is", without warranty of any kind,
36
 * express or implied, including, without limitation, the warranties
37
 * of merchantability, fitness for a particular purpose, title, and
38
 * non-infringement.  In no event shall the Copyright owners, or
39
 * anyone distributing the software, be liable for any damages or
40
 * other liability, whether in contract, tort or otherwise, arising
41
 * from, out of, or in connection with the software, or the use or
42
 * other dealings in the software, even if advised of the possibility
43
 * of such damage.
44
 *
45
 * Permission is hereby granted to use, copy, modify, and distribute
46
 * this software, or portions hereof, for any purpose, without fee,
47
 * subject to the following restrictions:
48
 *
49
 *  1. The origin of this software must not be misrepresented; you
50
 *     must not claim that you wrote the original software.  If you
51
 *     use this software in a product, an acknowledgment in the product
52
 *     documentation would be appreciated, but is not required.
53
 *
54
 *  2. Altered source versions must be plainly marked as such, and must
55
 *     not be misrepresented as being the original software.
56
 *
57
 *  3. This Copyright notice may not be removed or altered from any
58
 *     source or altered source distribution.
59
 *
60
 *
61
 * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)
62
 * -----------------------------------------------------------------------
63
 *
64
 * libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are
65
 * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
66
 * derived from libpng-1.0.6, and are distributed according to the same
67
 * disclaimer and license as libpng-1.0.6 with the following individuals
68
 * added to the list of Contributing Authors:
69
 *
70
 *     Simon-Pierre Cadieux
71
 *     Eric S. Raymond
72
 *     Mans Rullgard
73
 *     Cosmin Truta
74
 *     Gilles Vollant
75
 *     James Yu
76
 *     Mandar Sahastrabuddhe
77
 *     Google Inc.
78
 *     Vadim Barkov
79
 *
80
 * and with the following additions to the disclaimer:
81
 *
82
 *     There is no warranty against interference with your enjoyment of
83
 *     the library or against infringement.  There is no warranty that our
84
 *     efforts or the library will fulfill any of your particular purposes
85
 *     or needs.  This library is provided with all faults, and the entire
86
 *     risk of satisfactory quality, performance, accuracy, and effort is
87
 *     with the user.
88
 *
89
 * Some files in the "contrib" directory and some configure-generated
90
 * files that are distributed with libpng have other copyright owners, and
91
 * are released under other open source licenses.
92
 *
93
 * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
94
 * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
95
 * libpng-0.96, and are distributed according to the same disclaimer and
96
 * license as libpng-0.96, with the following individuals added to the
97
 * list of Contributing Authors:
98
 *
99
 *     Tom Lane
100
 *     Glenn Randers-Pehrson
101
 *     Willem van Schaik
102
 *
103
 * libpng versions 0.89, June 1996, through 0.96, May 1997, are
104
 * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
105
 * and are distributed according to the same disclaimer and license as
106
 * libpng-0.88, with the following individuals added to the list of
107
 * Contributing Authors:
108
 *
109
 *     John Bowler
110
 *     Kevin Bracey
111
 *     Sam Bushell
112
 *     Magnus Holmgren
113
 *     Greg Roelofs
114
 *     Tom Tanner
115
 *
116
 * Some files in the "scripts" directory have other copyright owners,
117
 * but are released under this license.
118
 *
119
 * libpng versions 0.5, May 1995, through 0.88, January 1996, are
120
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
121
 *
122
 * For the purposes of this copyright and license, "Contributing Authors"
123
 * is defined as the following set of individuals:
124
 *
125
 *     Andreas Dilger
126
 *     Dave Martindale
127
 *     Guy Eric Schalnat
128
 *     Paul Schmidt
129
 *     Tim Wegner
130
 *
131
 * The PNG Reference Library is supplied "AS IS".  The Contributing
132
 * Authors and Group 42, Inc. disclaim all warranties, expressed or
133
 * implied, including, without limitation, the warranties of
134
 * merchantability and of fitness for any purpose.  The Contributing
135
 * Authors and Group 42, Inc. assume no liability for direct, indirect,
136
 * incidental, special, exemplary, or consequential damages, which may
137
 * result from the use of the PNG Reference Library, even if advised of
138
 * the possibility of such damage.
139
 *
140
 * Permission is hereby granted to use, copy, modify, and distribute this
141
 * source code, or portions hereof, for any purpose, without fee, subject
142
 * to the following restrictions:
143
 *
144
 *  1. The origin of this source code must not be misrepresented.
145
 *
146
 *  2. Altered versions must be plainly marked as such and must not
147
 *     be misrepresented as being the original source.
148
 *
149
 *  3. This Copyright notice may not be removed or altered from any
150
 *     source or altered source distribution.
151
 *
152
 * The Contributing Authors and Group 42, Inc. specifically permit,
153
 * without fee, and encourage the use of this source code as a component
154
 * to supporting the PNG file format in commercial products.  If you use
155
 * this source code in a product, acknowledgment is not required but would
156
 * be appreciated.
157
 *
158
 * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
159
 *
160
 * TRADEMARK
161
 * =========
162
 *
163
 * The name "libpng" has not been registered by the Copyright owners
164
 * as a trademark in any jurisdiction.  However, because libpng has
165
 * been distributed and maintained world-wide, continually since 1995,
166
 * the Copyright owners claim "common-law trademark protection" in any
167
 * jurisdiction where common-law trademark is recognized.
168
 */
169
170
/*
171
 * A "png_get_copyright" function is available, for convenient use in "about"
172
 * boxes and the like:
173
 *
174
 *    printf("%s", png_get_copyright(NULL));
175
 *
176
 * Also, the PNG logo (in PNG format, of course) is supplied in the
177
 * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
178
 */
179
180
/*
181
 * The contributing authors would like to thank all those who helped
182
 * with testing, bug fixes, and patience.  This wouldn't have been
183
 * possible without all of you.
184
 *
185
 * Thanks to Frank J. T. Wojcik for helping with the documentation.
186
 */
187
188
/* Note about libpng version numbers:
189
 *
190
 *    Due to various miscommunications, unforeseen code incompatibilities
191
 *    and occasional factors outside the authors' control, version numbering
192
 *    on the library has not always been consistent and straightforward.
193
 *    The following table summarizes matters since version 0.89c, which was
194
 *    the first widely used release:
195
 *
196
 *    source                 png.h  png.h  shared-lib
197
 *    version                string   int  version
198
 *    -------                ------ -----  ----------
199
 *    0.89c "1.0 beta 3"     0.89      89  1.0.89
200
 *    0.90  "1.0 beta 4"     0.90      90  0.90  [should have been 2.0.90]
201
 *    0.95  "1.0 beta 5"     0.95      95  0.95  [should have been 2.0.95]
202
 *    0.96  "1.0 beta 6"     0.96      96  0.96  [should have been 2.0.96]
203
 *    0.97b "1.00.97 beta 7" 1.00.97   97  1.0.1 [should have been 2.0.97]
204
 *    0.97c                  0.97      97  2.0.97
205
 *    0.98                   0.98      98  2.0.98
206
 *    0.99                   0.99      98  2.0.99
207
 *    0.99a-m                0.99      99  2.0.99
208
 *    1.00                   1.00     100  2.1.0 [100 should be 10000]
209
 *    1.0.0      (from here on, the   100  2.1.0 [100 should be 10000]
210
 *    1.0.1       png.h string is   10001  2.1.0
211
 *    1.0.1a-e    identical to the  10002  from here on, the shared library
212
 *    1.0.2       source version)   10002  is 2.V where V is the source code
213
 *    1.0.2a-b                      10003  version, except as noted.
214
 *    1.0.3                         10003
215
 *    1.0.3a-d                      10004
216
 *    1.0.4                         10004
217
 *    1.0.4a-f                      10005
218
 *    1.0.5 (+ 2 patches)           10005
219
 *    1.0.5a-d                      10006
220
 *    1.0.5e-r                      10100 (not source compatible)
221
 *    1.0.5s-v                      10006 (not binary compatible)
222
 *    1.0.6 (+ 3 patches)           10006 (still binary incompatible)
223
 *    1.0.6d-f                      10007 (still binary incompatible)
224
 *    1.0.6g                        10007
225
 *    1.0.6h                        10007  10.6h (testing xy.z so-numbering)
226
 *    1.0.6i                        10007  10.6i
227
 *    1.0.6j                        10007  2.1.0.6j (incompatible with 1.0.0)
228
 *    1.0.7beta11-14        DLLNUM  10007  2.1.0.7beta11-14 (binary compatible)
229
 *    1.0.7beta15-18           1    10007  2.1.0.7beta15-18 (binary compatible)
230
 *    1.0.7rc1-2               1    10007  2.1.0.7rc1-2 (binary compatible)
231
 *    1.0.7                    1    10007  (still compatible)
232
 *    ...
233
 *    1.0.69                  10    10069  10.so.0.69[.0]
234
 *    ...
235
 *    1.2.59                  13    10259  12.so.0.59[.0]
236
 *    ...
237
 *    1.4.20                  14    10420  14.so.0.20[.0]
238
 *    ...
239
 *    1.5.30                  15    10530  15.so.15.30[.0]
240
 *    ...
241
 *    1.6.48                  16    10648  16.so.16.48[.0]
242
 *
243
 *    Henceforth the source version will match the shared-library major and
244
 *    minor numbers; the shared-library major version number will be used for
245
 *    changes in backward compatibility, as it is intended.
246
 *    The PNG_LIBPNG_VER macro, which is not used within libpng but is
247
 *    available for applications, is an unsigned integer of the form XYYZZ
248
 *    corresponding to the source version X.Y.Z (leading zeros in Y and Z).
249
 *    Beta versions were given the previous public release number plus a
250
 *    letter, until version 1.0.6j; from then on they were given the upcoming
251
 *    public release number plus "betaNN" or "rcNN".
252
 *
253
 *    Binary incompatibility exists only when applications make direct access
254
 *    to the info_ptr or png_ptr members through png.h, and the compiled
255
 *    application is loaded with a different version of the library.
256
 *
257
 * See libpng.txt or libpng.3 for more information.  The PNG specification
258
 * is available as a W3C Recommendation and as an ISO/IEC Standard; see
259
 * <https://www.w3.org/TR/2003/REC-PNG-20031110/>
260
 */
261
262
#ifndef PNG_H
263
#define PNG_H
264
265
/* This is not the place to learn how to use libpng. The file libpng-manual.txt
266
 * describes how to use libpng, and the file example.c summarizes it
267
 * with some code on which to build.  This file is useful for looking
268
 * at the actual function definitions and structure components.  If that
269
 * file has been stripped from your copy of libpng, you can find it at
270
 * <http://www.libpng.org/pub/png/libpng-manual.txt>
271
 *
272
 * If you just need to read a PNG file and don't want to read the documentation
273
 * skip to the end of this file and read the section entitled 'simplified API'.
274
 */
275
276
/* Version information for png.h - this should match the version in png.c */
277
17.8k
#define PNG_LIBPNG_VER_STRING "1.6.48"
278
0
#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
279
280
/* The versions of shared library builds should stay in sync, going forward */
281
#define PNG_LIBPNG_VER_SHAREDLIB 16
282
#define PNG_LIBPNG_VER_SONUM     PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */
283
#define PNG_LIBPNG_VER_DLLNUM    PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */
284
285
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
286
#define PNG_LIBPNG_VER_MAJOR   1
287
#define PNG_LIBPNG_VER_MINOR   6
288
#define PNG_LIBPNG_VER_RELEASE 48
289
290
/* This should be zero for a public release, or non-zero for a
291
 * development version.
292
 */
293
#define PNG_LIBPNG_VER_BUILD 0
294
295
/* Release Status */
296
#define PNG_LIBPNG_BUILD_ALPHA               1
297
#define PNG_LIBPNG_BUILD_BETA                2
298
#define PNG_LIBPNG_BUILD_RC                  3
299
#define PNG_LIBPNG_BUILD_STABLE              4
300
#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
301
302
/* Release-Specific Flags */
303
#define PNG_LIBPNG_BUILD_PATCH    8 /* Can be OR'ed with
304
                                       PNG_LIBPNG_BUILD_STABLE only */
305
#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
306
                                       PNG_LIBPNG_BUILD_SPECIAL */
307
#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
308
                                       PNG_LIBPNG_BUILD_PRIVATE */
309
310
#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
311
312
/* Careful here.  At one time, Guy wanted to use 082, but that
313
 * would be octal.  We must not include leading zeros.
314
 * Versions 0.7 through 1.0.0 were in the range 0 to 100 here
315
 * (only version 1.0.0 was mis-numbered 100 instead of 10000).
316
 * From version 1.0.1 it is:
317
 * XXYYZZ, where XX=major, YY=minor, ZZ=release
318
 */
319
0
#define PNG_LIBPNG_VER 10648 /* 1.6.48 */
320
321
/* Library configuration: these options cannot be changed after
322
 * the library has been built.
323
 */
324
#ifndef PNGLCONF_H
325
/* If pnglibconf.h is missing, you can
326
 * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
327
 */
328
#   include "pnglibconf.h"
329
#endif
330
331
#ifndef PNG_VERSION_INFO_ONLY
332
/* Machine specific configuration. */
333
#  include "pngconf.h"
334
#endif
335
336
/*
337
 * Added at libpng-1.2.8
338
 *
339
 * Ref MSDN: Private as priority over Special
340
 * VS_FF_PRIVATEBUILD File *was not* built using standard release
341
 * procedures. If this value is given, the StringFileInfo block must
342
 * contain a PrivateBuild string.
343
 *
344
 * VS_FF_SPECIALBUILD File *was* built by the original company using
345
 * standard release procedures but is a variation of the standard
346
 * file of the same version number. If this value is given, the
347
 * StringFileInfo block must contain a SpecialBuild string.
348
 */
349
350
#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */
351
#  define PNG_LIBPNG_BUILD_TYPE \
352
       (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
353
#else
354
#  ifdef PNG_LIBPNG_SPECIALBUILD
355
#    define PNG_LIBPNG_BUILD_TYPE \
356
         (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
357
#  else
358
#    define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
359
#  endif
360
#endif
361
362
#ifndef PNG_VERSION_INFO_ONLY
363
364
/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
365
#ifdef __cplusplus
366
extern "C" {
367
#endif /* __cplusplus */
368
369
/* Version information for C files, stored in png.c.  This had better match
370
 * the version above.
371
 */
372
#define png_libpng_ver png_get_header_ver(NULL)
373
374
/* This file is arranged in several sections:
375
 *
376
 * 1. [omitted]
377
 * 2. Any configuration options that can be specified by for the application
378
 *    code when it is built.  (Build time configuration is in pnglibconf.h)
379
 * 3. Type definitions (base types are defined in pngconf.h), structure
380
 *    definitions.
381
 * 4. Exported library functions.
382
 * 5. Simplified API.
383
 * 6. Implementation options.
384
 *
385
 * The library source code has additional files (principally pngpriv.h) that
386
 * allow configuration of the library.
387
 */
388
389
/* Section 1: [omitted] */
390
391
/* Section 2: run time configuration
392
 * See pnglibconf.h for build time configuration
393
 *
394
 * Run time configuration allows the application to choose between
395
 * implementations of certain arithmetic APIs.  The default is set
396
 * at build time and recorded in pnglibconf.h, but it is safe to
397
 * override these (and only these) settings.  Note that this won't
398
 * change what the library does, only application code, and the
399
 * settings can (and probably should) be made on a per-file basis
400
 * by setting the #defines before including png.h
401
 *
402
 * Use macros to read integers from PNG data or use the exported
403
 * functions?
404
 *   PNG_USE_READ_MACROS: use the macros (see below)  Note that
405
 *     the macros evaluate their argument multiple times.
406
 *   PNG_NO_USE_READ_MACROS: call the relevant library function.
407
 *
408
 * Use the alternative algorithm for compositing alpha samples that
409
 * does not use division?
410
 *   PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division'
411
 *      algorithm.
412
 *   PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm.
413
 *
414
 * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is
415
 * false?
416
 *   PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error
417
 *      APIs to png_warning.
418
 * Otherwise the calls are mapped to png_error.
419
 */
420
421
/* Section 3: type definitions, including structures and compile time
422
 * constants.
423
 * See pngconf.h for base types that vary by machine/system
424
 */
425
426
/* This triggers a compiler error in png.c, if png.c and png.h
427
 * do not agree upon the version number.
428
 */
429
typedef char* png_libpng_version_1_6_48;
430
431
/* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
432
 *
433
 * png_struct is the cache of information used while reading or writing a single
434
 * PNG file.  One of these is always required, although the simplified API
435
 * (below) hides the creation and destruction of it.
436
 */
437
typedef struct png_struct_def png_struct;
438
typedef const png_struct * png_const_structp;
439
typedef png_struct * png_structp;
440
typedef png_struct * * png_structpp;
441
442
/* png_info contains information read from or to be written to a PNG file.  One
443
 * or more of these must exist while reading or creating a PNG file.  The
444
 * information is not used by libpng during read but is used to control what
445
 * gets written when a PNG file is created.  "png_get_" function calls read
446
 * information during read and "png_set_" functions calls write information
447
 * when creating a PNG.
448
 * been moved into a separate header file that is not accessible to
449
 * applications.  Read libpng-manual.txt or libpng.3 for more info.
450
 */
451
typedef struct png_info_def png_info;
452
typedef png_info * png_infop;
453
typedef const png_info * png_const_infop;
454
typedef png_info * * png_infopp;
455
456
/* Types with names ending 'p' are pointer types.  The corresponding types with
457
 * names ending 'rp' are identical pointer types except that the pointer is
458
 * marked 'restrict', which means that it is the only pointer to the object
459
 * passed to the function.  Applications should not use the 'restrict' types;
460
 * it is always valid to pass 'p' to a pointer with a function argument of the
461
 * corresponding 'rp' type.  Different compilers have different rules with
462
 * regard to type matching in the presence of 'restrict'.  For backward
463
 * compatibility libpng callbacks never have 'restrict' in their parameters and,
464
 * consequentially, writing portable application code is extremely difficult if
465
 * an attempt is made to use 'restrict'.
466
 */
467
typedef png_struct * PNG_RESTRICT png_structrp;
468
typedef const png_struct * PNG_RESTRICT png_const_structrp;
469
typedef png_info * PNG_RESTRICT png_inforp;
470
typedef const png_info * PNG_RESTRICT png_const_inforp;
471
472
/* Three color definitions.  The order of the red, green, and blue, (and the
473
 * exact size) is not important, although the size of the fields need to
474
 * be png_byte or png_uint_16 (as defined below).
475
 */
476
typedef struct png_color_struct
477
{
478
   png_byte red;
479
   png_byte green;
480
   png_byte blue;
481
} png_color;
482
typedef png_color * png_colorp;
483
typedef const png_color * png_const_colorp;
484
typedef png_color * * png_colorpp;
485
486
typedef struct png_color_16_struct
487
{
488
   png_byte index;    /* used for palette files */
489
   png_uint_16 red;   /* for use in red green blue files */
490
   png_uint_16 green;
491
   png_uint_16 blue;
492
   png_uint_16 gray;  /* for use in grayscale files */
493
} png_color_16;
494
typedef png_color_16 * png_color_16p;
495
typedef const png_color_16 * png_const_color_16p;
496
typedef png_color_16 * * png_color_16pp;
497
498
typedef struct png_color_8_struct
499
{
500
   png_byte red;   /* for use in red green blue files */
501
   png_byte green;
502
   png_byte blue;
503
   png_byte gray;  /* for use in grayscale files */
504
   png_byte alpha; /* for alpha channel files */
505
} png_color_8;
506
typedef png_color_8 * png_color_8p;
507
typedef const png_color_8 * png_const_color_8p;
508
typedef png_color_8 * * png_color_8pp;
509
510
/*
511
 * The following two structures are used for the in-core representation
512
 * of sPLT chunks.
513
 */
514
typedef struct png_sPLT_entry_struct
515
{
516
   png_uint_16 red;
517
   png_uint_16 green;
518
   png_uint_16 blue;
519
   png_uint_16 alpha;
520
   png_uint_16 frequency;
521
} png_sPLT_entry;
522
typedef png_sPLT_entry * png_sPLT_entryp;
523
typedef const png_sPLT_entry * png_const_sPLT_entryp;
524
typedef png_sPLT_entry * * png_sPLT_entrypp;
525
526
/*  When the depth of the sPLT palette is 8 bits, the color and alpha samples
527
 *  occupy the LSB of their respective members, and the MSB of each member
528
 *  is zero-filled.  The frequency member always occupies the full 16 bits.
529
 */
530
531
typedef struct png_sPLT_struct
532
{
533
   png_charp name;           /* palette name */
534
   png_byte depth;           /* depth of palette samples */
535
   png_sPLT_entryp entries;  /* palette entries */
536
   png_int_32 nentries;      /* number of palette entries */
537
} png_sPLT_t;
538
typedef png_sPLT_t * png_sPLT_tp;
539
typedef const png_sPLT_t * png_const_sPLT_tp;
540
typedef png_sPLT_t * * png_sPLT_tpp;
541
542
#ifdef PNG_TEXT_SUPPORTED
543
/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
544
 * and whether that contents is compressed or not.  The "key" field
545
 * points to a regular zero-terminated C string.  The "text" fields can be a
546
 * regular C string, an empty string, or a NULL pointer.
547
 * However, the structure returned by png_get_text() will always contain
548
 * the "text" field as a regular zero-terminated C string (possibly
549
 * empty), never a NULL pointer, so it can be safely used in printf() and
550
 * other string-handling functions.  Note that the "itxt_length", "lang", and
551
 * "lang_key" members of the structure only exist when the library is built
552
 * with iTXt chunk support.  Prior to libpng-1.4.0 the library was built by
553
 * default without iTXt support. Also note that when iTXt *is* supported,
554
 * the "lang" and "lang_key" fields contain NULL pointers when the
555
 * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or
556
 * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the
557
 * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag"
558
 * which is always 0 or 1, or its "compression method" which is always 0.
559
 */
560
typedef struct png_text_struct
561
{
562
   int  compression;       /* compression value:
563
                             -1: tEXt, none
564
                              0: zTXt, deflate
565
                              1: iTXt, none
566
                              2: iTXt, deflate  */
567
   png_charp key;          /* keyword, 1-79 character description of "text" */
568
   png_charp text;         /* comment, may be an empty string (ie "")
569
                              or a NULL pointer */
570
   size_t text_length;     /* length of the text string */
571
   size_t itxt_length;     /* length of the itxt string */
572
   png_charp lang;         /* language code, 0-79 characters
573
                              or a NULL pointer */
574
   png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
575
                              chars or a NULL pointer */
576
} png_text;
577
typedef png_text * png_textp;
578
typedef const png_text * png_const_textp;
579
typedef png_text * * png_textpp;
580
#endif
581
582
/* Supported compression types for text in PNG files (tEXt, and zTXt).
583
 * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
584
#define PNG_TEXT_COMPRESSION_NONE_WR -3
585
#define PNG_TEXT_COMPRESSION_zTXt_WR -2
586
16.1k
#define PNG_TEXT_COMPRESSION_NONE    -1
587
13
#define PNG_TEXT_COMPRESSION_zTXt     0
588
161
#define PNG_ITXT_COMPRESSION_NONE     1
589
530
#define PNG_ITXT_COMPRESSION_zTXt     2
590
5.39k
#define PNG_TEXT_COMPRESSION_LAST     3  /* Not a valid value */
591
592
/* png_time is a way to hold the time in an machine independent way.
593
 * Two conversions are provided, both from time_t and struct tm.  There
594
 * is no portable way to convert to either of these structures, as far
595
 * as I know.  If you know of a portable way, send it to me.  As a side
596
 * note - PNG has always been Year 2000 compliant!
597
 */
598
typedef struct png_time_struct
599
{
600
   png_uint_16 year; /* full year, as in, 1995 */
601
   png_byte month;   /* month of year, 1 - 12 */
602
   png_byte day;     /* day of month, 1 - 31 */
603
   png_byte hour;    /* hour of day, 0 - 23 */
604
   png_byte minute;  /* minute of hour, 0 - 59 */
605
   png_byte second;  /* second of minute, 0 - 60 (for leap seconds) */
606
} png_time;
607
typedef png_time * png_timep;
608
typedef const png_time * png_const_timep;
609
typedef png_time * * png_timepp;
610
611
#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\
612
   defined(PNG_USER_CHUNKS_SUPPORTED)
613
/* png_unknown_chunk is a structure to hold queued chunks for which there is
614
 * no specific support.  The idea is that we can use this to queue
615
 * up private chunks for output even though the library doesn't actually
616
 * know about their semantics.
617
 *
618
 * The data in the structure is set by libpng on read and used on write.
619
 */
620
typedef struct png_unknown_chunk_t
621
{
622
   png_byte name[5]; /* Textual chunk name with '\0' terminator */
623
   png_byte *data;   /* Data, should not be modified on read! */
624
   size_t size;
625
626
   /* On write 'location' must be set using the flag values listed below.
627
    * Notice that on read it is set by libpng however the values stored have
628
    * more bits set than are listed below.  Always treat the value as a
629
    * bitmask.  On write set only one bit - setting multiple bits may cause the
630
    * chunk to be written in multiple places.
631
    */
632
   png_byte location; /* mode of operation at read time */
633
}
634
png_unknown_chunk;
635
636
typedef png_unknown_chunk * png_unknown_chunkp;
637
typedef const png_unknown_chunk * png_const_unknown_chunkp;
638
typedef png_unknown_chunk * * png_unknown_chunkpp;
639
#endif
640
641
/* Flag values for the unknown chunk location byte. */
642
35.2k
#define PNG_HAVE_IHDR  0x01
643
2.47k
#define PNG_HAVE_PLTE  0x02
644
5.32k
#define PNG_AFTER_IDAT 0x08
645
646
/* Maximum positive integer used in PNG is (2^31)-1 */
647
49.1k
#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
648
0
#define PNG_UINT_32_MAX ((png_uint_32)(-1))
649
36.7k
#define PNG_SIZE_MAX ((size_t)(-1))
650
651
/* These are constants for fixed point values encoded in the
652
 * PNG specification manner (x100000)
653
 */
654
4.76k
#define PNG_FP_1    100000
655
#define PNG_FP_HALF  50000
656
0
#define PNG_FP_MAX  ((png_fixed_point)0x7fffffffL)
657
0
#define PNG_FP_MIN  (-PNG_FP_MAX)
658
659
/* These describe the color_type field in png_info. */
660
/* color type masks */
661
275k
#define PNG_COLOR_MASK_PALETTE    1
662
534k
#define PNG_COLOR_MASK_COLOR      2
663
38.2k
#define PNG_COLOR_MASK_ALPHA      4
664
665
/* color types.  Note that not all combinations are legal */
666
190k
#define PNG_COLOR_TYPE_GRAY 0
667
395k
#define PNG_COLOR_TYPE_PALETTE  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
668
117k
#define PNG_COLOR_TYPE_RGB        (PNG_COLOR_MASK_COLOR)
669
16.9k
#define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
670
17.9k
#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
671
/* aliases */
672
#define PNG_COLOR_TYPE_RGBA  PNG_COLOR_TYPE_RGB_ALPHA
673
#define PNG_COLOR_TYPE_GA  PNG_COLOR_TYPE_GRAY_ALPHA
674
675
/* This is for compression type. PNG 1.0-1.2 only define the single type. */
676
5.17k
#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
677
#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
678
679
/* This is for filter type. PNG 1.0-1.2 only define the single type. */
680
3.17k
#define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
681
0
#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
682
#define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
683
684
/* These are for the interlacing type.  These values should NOT be changed. */
685
0
#define PNG_INTERLACE_NONE        0 /* Non-interlaced image */
686
0
#define PNG_INTERLACE_ADAM7       1 /* Adam7 interlacing */
687
3.17k
#define PNG_INTERLACE_LAST        2 /* Not a valid value */
688
689
/* These are for the oFFs chunk.  These values should NOT be changed. */
690
0
#define PNG_OFFSET_PIXEL          0 /* Offset in pixels */
691
0
#define PNG_OFFSET_MICROMETER     1 /* Offset in micrometers (1/10^6 meter) */
692
#define PNG_OFFSET_LAST           2 /* Not a valid value */
693
694
/* These are for the pCAL chunk.  These values should NOT be changed. */
695
2.96k
#define PNG_EQUATION_LINEAR       0 /* Linear transformation */
696
1.44k
#define PNG_EQUATION_BASE_E       1 /* Exponential base e transform */
697
1.41k
#define PNG_EQUATION_ARBITRARY    2 /* Arbitrary base exponential transform */
698
1.18k
#define PNG_EQUATION_HYPERBOLIC   3 /* Hyperbolic sine transformation */
699
587
#define PNG_EQUATION_LAST         4 /* Not a valid value */
700
701
/* These are for the sCAL chunk.  These values should NOT be changed. */
702
#define PNG_SCALE_UNKNOWN         0 /* unknown unit (image scale) */
703
#define PNG_SCALE_METER           1 /* meters per pixel */
704
#define PNG_SCALE_RADIAN          2 /* radians per pixel */
705
#define PNG_SCALE_LAST            3 /* Not a valid value */
706
707
/* These are for the pHYs chunk.  These values should NOT be changed. */
708
#define PNG_RESOLUTION_UNKNOWN    0 /* pixels/unknown unit (aspect ratio) */
709
0
#define PNG_RESOLUTION_METER      1 /* pixels/meter */
710
#define PNG_RESOLUTION_LAST       2 /* Not a valid value */
711
712
/* These are for the sRGB chunk.  These values should NOT be changed. */
713
#define PNG_sRGB_INTENT_PERCEPTUAL 0
714
#define PNG_sRGB_INTENT_RELATIVE   1
715
#define PNG_sRGB_INTENT_SATURATION 2
716
#define PNG_sRGB_INTENT_ABSOLUTE   3
717
0
#define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
718
719
/* This is for text chunks */
720
#define PNG_KEYWORD_MAX_LENGTH     79
721
722
/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
723
2.23k
#define PNG_MAX_PALETTE_LENGTH    256
724
725
/* These determine if an ancillary chunk's data has been successfully read
726
 * from the PNG header, or if the application has filled in the corresponding
727
 * data in the info_struct to be written into the output file.  The values
728
 * of the PNG_INFO_<chunk> defines should NOT be changed.
729
 */
730
775
#define PNG_INFO_gAMA 0x0001U
731
187
#define PNG_INFO_sBIT 0x0002U
732
589
#define PNG_INFO_cHRM 0x0004U
733
738
#define PNG_INFO_PLTE 0x0008U
734
1.79k
#define PNG_INFO_tRNS 0x0010U
735
261
#define PNG_INFO_bKGD 0x0020U
736
0
#define PNG_INFO_hIST 0x0040U
737
58
#define PNG_INFO_pHYs 0x0080U
738
171
#define PNG_INFO_oFFs 0x0100U
739
61
#define PNG_INFO_tIME 0x0200U
740
126
#define PNG_INFO_pCAL 0x0400U
741
226
#define PNG_INFO_sRGB 0x0800U  /* GR-P, 0.96a */
742
0
#define PNG_INFO_iCCP 0x1000U  /* ESR, 1.0.6 */
743
460
#define PNG_INFO_sPLT 0x2000U  /* ESR, 1.0.6 */
744
168
#define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
745
0
#define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
746
44
#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
747
89
#define PNG_INFO_cICP 0x20000U /* PNGv3: 1.6.45 */
748
200
#define PNG_INFO_cLLI 0x40000U /* PNGv3: 1.6.45 */
749
148
#define PNG_INFO_mDCV 0x80000U /* PNGv3: 1.6.45 */
750
/* APNG: these chunks are stored as unknown, these flags are never set
751
 * however they are provided as a convenience for implementors of APNG and
752
 * avoids any merge conflicts.
753
 *
754
 * Private chunks: these chunk names violate the chunk name recommendations
755
 * because the chunk definitions have no signature and because the private
756
 * chunks with these names have been reserved.  Private definitions should
757
 * avoid them.
758
 */
759
#define PNG_INFO_acTL 0x100000U /* PNGv3: 1.6.45: unknown */
760
#define PNG_INFO_fcTL 0x200000U /* PNGv3: 1.6.45: unknown */
761
#define PNG_INFO_fdAT 0x400000U /* PNGv3: 1.6.45: unknown */
762
763
/* This is used for the transformation routines, as some of them
764
 * change these values for the row.  It also should enable using
765
 * the routines for other purposes.
766
 */
767
typedef struct png_row_info_struct
768
{
769
   png_uint_32 width;    /* width of row */
770
   size_t rowbytes;      /* number of bytes in row */
771
   png_byte color_type;  /* color type of row */
772
   png_byte bit_depth;   /* bit depth of row */
773
   png_byte channels;    /* number of channels (1, 2, 3, or 4) */
774
   png_byte pixel_depth; /* bits per pixel (depth * channels) */
775
} png_row_info;
776
777
typedef png_row_info * png_row_infop;
778
typedef png_row_info * * png_row_infopp;
779
780
/* These are the function types for the I/O functions and for the functions
781
 * that allow the user to override the default I/O functions with his or her
782
 * own.  The png_error_ptr type should match that of user-supplied warning
783
 * and error functions, while the png_rw_ptr type should match that of the
784
 * user read/write data functions.  Note that the 'write' function must not
785
 * modify the buffer it is passed. The 'read' function, on the other hand, is
786
 * expected to return the read data in the buffer.
787
 */
788
typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
789
typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, size_t));
790
typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
791
typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
792
    int));
793
typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
794
    int));
795
796
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
797
typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
798
typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
799
800
/* The following callback receives png_uint_32 row_number, int pass for the
801
 * png_bytep data of the row.  When transforming an interlaced image the
802
 * row number is the row number within the sub-image of the interlace pass, so
803
 * the value will increase to the height of the sub-image (not the full image)
804
 * then reset to 0 for the next pass.
805
 *
806
 * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
807
 * find the output pixel (x,y) given an interlaced sub-image pixel
808
 * (row,col,pass).  (See below for these macros.)
809
 */
810
typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,
811
    png_uint_32, int));
812
#endif
813
814
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
815
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
816
typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,
817
    png_bytep));
818
#endif
819
820
#ifdef PNG_USER_CHUNKS_SUPPORTED
821
typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
822
    png_unknown_chunkp));
823
#endif
824
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
825
/* not used anywhere */
826
/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */
827
#endif
828
829
#ifdef PNG_SETJMP_SUPPORTED
830
/* This must match the function definition in <setjmp.h>, and the application
831
 * must include this before png.h to obtain the definition of jmp_buf.  The
832
 * function is required to be PNG_NORETURN, but this is not checked.  If the
833
 * function does return the application will crash via an abort() or similar
834
 * system level call.
835
 *
836
 * If you get a warning here while building the library you may need to make
837
 * changes to ensure that pnglibconf.h records the calling convention used by
838
 * your compiler.  This may be very difficult - try using a different compiler
839
 * to build the library!
840
 */
841
PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), (jmp_buf, int), typedef);
842
#endif
843
844
/* Transform masks for the high-level interface */
845
#define PNG_TRANSFORM_IDENTITY       0x0000    /* read and write */
846
0
#define PNG_TRANSFORM_STRIP_16       0x0001    /* read only */
847
0
#define PNG_TRANSFORM_STRIP_ALPHA    0x0002    /* read only */
848
0
#define PNG_TRANSFORM_PACKING        0x0004    /* read and write */
849
0
#define PNG_TRANSFORM_PACKSWAP       0x0008    /* read and write */
850
0
#define PNG_TRANSFORM_EXPAND         0x0010    /* read only */
851
0
#define PNG_TRANSFORM_INVERT_MONO    0x0020    /* read and write */
852
0
#define PNG_TRANSFORM_SHIFT          0x0040    /* read and write */
853
0
#define PNG_TRANSFORM_BGR            0x0080    /* read and write */
854
0
#define PNG_TRANSFORM_SWAP_ALPHA     0x0100    /* read and write */
855
0
#define PNG_TRANSFORM_SWAP_ENDIAN    0x0200    /* read and write */
856
0
#define PNG_TRANSFORM_INVERT_ALPHA   0x0400    /* read and write */
857
#define PNG_TRANSFORM_STRIP_FILLER   0x0800    /* write only */
858
/* Added to libpng-1.2.34 */
859
#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER
860
#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */
861
/* Added to libpng-1.4.0 */
862
0
#define PNG_TRANSFORM_GRAY_TO_RGB   0x2000      /* read only */
863
/* Added to libpng-1.5.4 */
864
0
#define PNG_TRANSFORM_EXPAND_16     0x4000      /* read only */
865
#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */
866
0
#define PNG_TRANSFORM_SCALE_16      0x8000      /* read only */
867
#endif
868
869
/* Flags for MNG supported features */
870
1
#define PNG_FLAG_MNG_EMPTY_PLTE     0x01
871
118k
#define PNG_FLAG_MNG_FILTER_64      0x04
872
0
#define PNG_ALL_MNG_FEATURES        0x05
873
874
/* NOTE: prior to 1.5 these functions had no 'API' style declaration,
875
 * this allowed the zlib default functions to be used on Windows
876
 * platforms.  In 1.5 the zlib default malloc (which just calls malloc and
877
 * ignores the first argument) should be completely compatible with the
878
 * following.
879
 */
880
typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,
881
    png_alloc_size_t));
882
typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
883
884
/* Section 4: exported functions
885
 * Here are the function definitions most commonly used.  This is not
886
 * the place to find out how to use libpng.  See libpng-manual.txt for the
887
 * full explanation, see example.c for the summary.  This just provides
888
 * a simple one line description of the use of each function.
889
 *
890
 * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in
891
 * pngconf.h and in the *.dfn files in the scripts directory.
892
 *
893
 *   PNG_EXPORT(ordinal, type, name, (args));
894
 *
895
 *       ordinal:    ordinal that is used while building
896
 *                   *.def files. The ordinal value is only
897
 *                   relevant when preprocessing png.h with
898
 *                   the *.dfn files for building symbol table
899
 *                   entries, and are removed by pngconf.h.
900
 *       type:       return type of the function
901
 *       name:       function name
902
 *       args:       function arguments, with types
903
 *
904
 * When we wish to append attributes to a function prototype we use
905
 * the PNG_EXPORTA() macro instead.
906
 *
907
 *   PNG_EXPORTA(ordinal, type, name, (args), attributes);
908
 *
909
 *       ordinal, type, name, and args: same as in PNG_EXPORT().
910
 *       attributes: function attributes
911
 */
912
913
/* Returns the version number of the library */
914
PNG_EXPORT(1, png_uint_32, png_access_version_number, (void));
915
916
/* Tell lib we have already handled the first <num_bytes> magic bytes.
917
 * Handling more than 8 bytes from the beginning of the file is an error.
918
 */
919
PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
920
921
/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
922
 * PNG file.  Returns zero if the supplied bytes match the 8-byte PNG
923
 * signature, and non-zero otherwise.  Having num_to_check == 0 or
924
 * start > 7 will always fail (i.e. return non-zero).
925
 */
926
PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start,
927
    size_t num_to_check));
928
929
/* Simple signature checking function.  This is the same as calling
930
 * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0).
931
 */
932
#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */
933
934
/* Allocate and initialize png_ptr struct for reading, and any other memory. */
935
PNG_EXPORTA(4, png_structp, png_create_read_struct,
936
    (png_const_charp user_png_ver, png_voidp error_ptr,
937
    png_error_ptr error_fn, png_error_ptr warn_fn),
938
    PNG_ALLOCATED);
939
940
/* Allocate and initialize png_ptr struct for writing, and any other memory */
941
PNG_EXPORTA(5, png_structp, png_create_write_struct,
942
    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
943
    png_error_ptr warn_fn),
944
    PNG_ALLOCATED);
945
946
PNG_EXPORT(6, size_t, png_get_compression_buffer_size,
947
    (png_const_structrp png_ptr));
948
949
PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
950
    size_t size));
951
952
/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
953
 * match up.
954
 */
955
#ifdef PNG_SETJMP_SUPPORTED
956
/* This function returns the jmp_buf built in to *png_ptr.  It must be
957
 * supplied with an appropriate 'longjmp' function to use on that jmp_buf
958
 * unless the default error function is overridden in which case NULL is
959
 * acceptable.  The size of the jmp_buf is checked against the actual size
960
 * allocated by the library - the call will return NULL on a mismatch
961
 * indicating an ABI mismatch.
962
 */
963
PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr,
964
    png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
965
#  define png_jmpbuf(png_ptr) \
966
      (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf))))
967
#else
968
#  define png_jmpbuf(png_ptr) \
969
      (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
970
#endif
971
/* This function should be used by libpng applications in place of
972
 * longjmp(png_ptr->jmpbuf, val).  If longjmp_fn() has been set, it
973
 * will use it; otherwise it will call PNG_ABORT().  This function was
974
 * added in libpng-1.5.0.
975
 */
976
PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val),
977
    PNG_NORETURN);
978
979
#ifdef PNG_READ_SUPPORTED
980
/* Reset the compression stream */
981
PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED);
982
#endif
983
984
/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
985
#ifdef PNG_USER_MEM_SUPPORTED
986
PNG_EXPORTA(11, png_structp, png_create_read_struct_2,
987
    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
988
    png_error_ptr warn_fn,
989
    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
990
    PNG_ALLOCATED);
991
PNG_EXPORTA(12, png_structp, png_create_write_struct_2,
992
    (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
993
    png_error_ptr warn_fn,
994
    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
995
    PNG_ALLOCATED);
996
#endif
997
998
/* Write the PNG file signature. */
999
PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));
1000
1001
/* Write a PNG chunk - size, type, (optional) data, CRC. */
1002
PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep
1003
    chunk_name, png_const_bytep data, size_t length));
1004
1005
/* Write the start of a PNG chunk - length and chunk name. */
1006
PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
1007
    png_const_bytep chunk_name, png_uint_32 length));
1008
1009
/* Write the data of a PNG chunk started with png_write_chunk_start(). */
1010
PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,
1011
    png_const_bytep data, size_t length));
1012
1013
/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
1014
PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr));
1015
1016
/* Allocate and initialize the info structure */
1017
PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),
1018
    PNG_ALLOCATED);
1019
1020
/* DEPRECATED: this function allowed init structures to be created using the
1021
 * default allocation method (typically malloc).  Use is deprecated in 1.6.0 and
1022
 * the API will be removed in the future.
1023
 */
1024
PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,
1025
    size_t png_info_struct_size), PNG_DEPRECATED);
1026
1027
/* Writes all the PNG information before the image. */
1028
PNG_EXPORT(20, void, png_write_info_before_PLTE,
1029
    (png_structrp png_ptr, png_const_inforp info_ptr));
1030
PNG_EXPORT(21, void, png_write_info,
1031
    (png_structrp png_ptr, png_const_inforp info_ptr));
1032
1033
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1034
/* Read the information before the actual image data. */
1035
PNG_EXPORT(22, void, png_read_info,
1036
    (png_structrp png_ptr, png_inforp info_ptr));
1037
#endif
1038
1039
#ifdef PNG_TIME_RFC1123_SUPPORTED
1040
   /* Convert to a US string format: there is no localization support in this
1041
    * routine.  The original implementation used a 29 character buffer in
1042
    * png_struct, this will be removed in future versions.
1043
    */
1044
#if PNG_LIBPNG_VER < 10700
1045
/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */
1046
PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr,
1047
    png_const_timep ptime),PNG_DEPRECATED);
1048
#endif
1049
PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29],
1050
    png_const_timep ptime));
1051
#endif
1052
1053
#ifdef PNG_CONVERT_tIME_SUPPORTED
1054
/* Convert from a struct tm to png_time */
1055
PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime,
1056
    const struct tm * ttime));
1057
1058
/* Convert from time_t to png_time.  Uses gmtime() */
1059
PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime));
1060
#endif /* CONVERT_tIME */
1061
1062
#ifdef PNG_READ_EXPAND_SUPPORTED
1063
/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
1064
PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr));
1065
PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr));
1066
PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr));
1067
PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr));
1068
#endif
1069
1070
#ifdef PNG_READ_EXPAND_16_SUPPORTED
1071
/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion
1072
 * of a tRNS chunk if present.
1073
 */
1074
PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr));
1075
#endif
1076
1077
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
1078
/* Use blue, green, red order for pixels. */
1079
PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr));
1080
#endif
1081
1082
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1083
/* Expand the grayscale to 24-bit RGB if necessary. */
1084
PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr));
1085
#endif
1086
1087
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1088
/* Reduce RGB to grayscale. */
1089
0
#define PNG_ERROR_ACTION_NONE  1
1090
0
#define PNG_ERROR_ACTION_WARN  2
1091
0
#define PNG_ERROR_ACTION_ERROR 3
1092
0
#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/
1093
1094
PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr,
1095
    int error_action, double red, double green))
1096
PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr,
1097
    int error_action, png_fixed_point red, png_fixed_point green))
1098
1099
PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp
1100
    png_ptr));
1101
#endif
1102
1103
#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
1104
PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
1105
    png_colorp palette));
1106
#endif
1107
1108
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1109
/* How the alpha channel is interpreted - this affects how the color channels
1110
 * of a PNG file are returned to the calling application when an alpha channel,
1111
 * or a tRNS chunk in a palette file, is present.
1112
 *
1113
 * This has no effect on the way pixels are written into a PNG output
1114
 * datastream. The color samples in a PNG datastream are never premultiplied
1115
 * with the alpha samples.
1116
 *
1117
 * The default is to return data according to the PNG specification: the alpha
1118
 * channel is a linear measure of the contribution of the pixel to the
1119
 * corresponding composited pixel, and the color channels are unassociated
1120
 * (not premultiplied).  The gamma encoded color channels must be scaled
1121
 * according to the contribution and to do this it is necessary to undo
1122
 * the encoding, scale the color values, perform the composition and re-encode
1123
 * the values.  This is the 'PNG' mode.
1124
 *
1125
 * The alternative is to 'associate' the alpha with the color information by
1126
 * storing color channel values that have been scaled by the alpha.
1127
 * image.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
1128
 * (the latter being the two common names for associated alpha color channels).
1129
 *
1130
 * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha
1131
 * value is equal to the maximum value.
1132
 *
1133
 * The final choice is to gamma encode the alpha channel as well.  This is
1134
 * broken because, in practice, no implementation that uses this choice
1135
 * correctly undoes the encoding before handling alpha composition.  Use this
1136
 * choice only if other serious errors in the software or hardware you use
1137
 * mandate it; the typical serious error is for dark halos to appear around
1138
 * opaque areas of the composited PNG image because of arithmetic overflow.
1139
 *
1140
 * The API function png_set_alpha_mode specifies which of these choices to use
1141
 * with an enumerated 'mode' value and the gamma of the required output:
1142
 */
1143
1.67k
#define PNG_ALPHA_PNG           0 /* according to the PNG standard */
1144
0
#define PNG_ALPHA_STANDARD      1 /* according to Porter/Duff */
1145
0
#define PNG_ALPHA_ASSOCIATED    1 /* as above; this is the normal practice */
1146
#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */
1147
0
#define PNG_ALPHA_OPTIMIZED     2 /* 'PNG' for opaque pixels, else 'STANDARD' */
1148
0
#define PNG_ALPHA_BROKEN        3 /* the alpha channel is gamma encoded */
1149
1150
PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode,
1151
    double output_gamma))
1152
PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
1153
    int mode, png_fixed_point output_gamma))
1154
#endif
1155
1156
#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)
1157
/* The output_gamma value is a screen gamma in libpng terminology: it expresses
1158
 * how to decode the output values, not how they are encoded.
1159
 */
1160
2.51k
#define PNG_DEFAULT_sRGB -1       /* sRGB gamma and color space */
1161
135
#define PNG_GAMMA_MAC_18 -2       /* Old Mac '1.8' gamma and color space */
1162
793
#define PNG_GAMMA_sRGB   220000   /* Television standards--matches sRGB gamma */
1163
45
#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */
1164
#endif
1165
1166
/* The following are examples of calls to png_set_alpha_mode to achieve the
1167
 * required overall gamma correction and, where necessary, alpha
1168
 * premultiplication.
1169
 *
1170
 * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
1171
 *    This is the default libpng handling of the alpha channel - it is not
1172
 *    pre-multiplied into the color components.  In addition the call states
1173
 *    that the output is for a sRGB system and causes all PNG files without gAMA
1174
 *    chunks to be assumed to be encoded using sRGB.
1175
 *
1176
 * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
1177
 *    In this case the output is assumed to be something like an sRGB conformant
1178
 *    display preceded by a power-law lookup table of power 1.45.  This is how
1179
 *    early Mac systems behaved.
1180
 *
1181
 * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
1182
 *    This is the classic Jim Blinn approach and will work in academic
1183
 *    environments where everything is done by the book.  It has the shortcoming
1184
 *    of assuming that input PNG data with no gamma information is linear - this
1185
 *    is unlikely to be correct unless the PNG files where generated locally.
1186
 *    Most of the time the output precision will be so low as to show
1187
 *    significant banding in dark areas of the image.
1188
 *
1189
 * png_set_expand_16(pp);
1190
 * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
1191
 *    This is a somewhat more realistic Jim Blinn inspired approach.  PNG files
1192
 *    are assumed to have the sRGB encoding if not marked with a gamma value and
1193
 *    the output is always 16 bits per component.  This permits accurate scaling
1194
 *    and processing of the data.  If you know that your input PNG files were
1195
 *    generated locally you might need to replace PNG_DEFAULT_sRGB with the
1196
 *    correct value for your system.
1197
 *
1198
 * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
1199
 *    If you just need to composite the PNG image onto an existing background
1200
 *    and if you control the code that does this you can use the optimization
1201
 *    setting.  In this case you just copy completely opaque pixels to the
1202
 *    output.  For pixels that are not completely transparent (you just skip
1203
 *    those) you do the composition math using png_composite or png_composite_16
1204
 *    below then encode the resultant 8-bit or 16-bit values to match the output
1205
 *    encoding.
1206
 *
1207
 * Other cases
1208
 *    If neither the PNG nor the standard linear encoding work for you because
1209
 *    of the software or hardware you use then you have a big problem.  The PNG
1210
 *    case will probably result in halos around the image.  The linear encoding
1211
 *    will probably result in a washed out, too bright, image (it's actually too
1212
 *    contrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably
1213
 *    substantially reduce the halos.  Alternatively try:
1214
 *
1215
 * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
1216
 *    This option will also reduce the halos, but there will be slight dark
1217
 *    halos round the opaque parts of the image where the background is light.
1218
 *    In the OPTIMIZED mode the halos will be light halos where the background
1219
 *    is dark.  Take your pick - the halos are unavoidable unless you can get
1220
 *    your hardware/software fixed!  (The OPTIMIZED approach is slightly
1221
 *    faster.)
1222
 *
1223
 * When the default gamma of PNG files doesn't match the output gamma.
1224
 *    If you have PNG files with no gamma information png_set_alpha_mode allows
1225
 *    you to provide a default gamma, but it also sets the output gamma to the
1226
 *    matching value.  If you know your PNG files have a gamma that doesn't
1227
 *    match the output you can take advantage of the fact that
1228
 *    png_set_alpha_mode always sets the output gamma but only sets the PNG
1229
 *    default if it is not already set:
1230
 *
1231
 * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
1232
 * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
1233
 *    The first call sets both the default and the output gamma values, the
1234
 *    second call overrides the output gamma without changing the default.  This
1235
 *    is easier than achieving the same effect with png_set_gamma.  You must use
1236
 *    PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
1237
 *    fire if more than one call to png_set_alpha_mode and png_set_background is
1238
 *    made in the same read operation, however multiple calls with PNG_ALPHA_PNG
1239
 *    are ignored.
1240
 */
1241
1242
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1243
PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr));
1244
#endif
1245
1246
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
1247
    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
1248
PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr));
1249
#endif
1250
1251
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
1252
    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
1253
PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr));
1254
#endif
1255
1256
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
1257
/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
1258
PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler,
1259
    int flags));
1260
/* The values of the PNG_FILLER_ defines should NOT be changed */
1261
0
#  define PNG_FILLER_BEFORE 0
1262
358
#  define PNG_FILLER_AFTER 1
1263
/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
1264
PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr,
1265
    png_uint_32 filler, int flags));
1266
#endif /* READ_FILLER || WRITE_FILLER */
1267
1268
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
1269
/* Swap bytes in 16-bit depth files. */
1270
PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr));
1271
#endif
1272
1273
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
1274
/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
1275
PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr));
1276
#endif
1277
1278
#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
1279
    defined(PNG_WRITE_PACKSWAP_SUPPORTED)
1280
/* Swap packing order of pixels in bytes. */
1281
PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr));
1282
#endif
1283
1284
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
1285
/* Converts files to legal bit depths. */
1286
PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p
1287
    true_bits));
1288
#endif
1289
1290
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
1291
    defined(PNG_WRITE_INTERLACING_SUPPORTED)
1292
/* Have the code handle the interlacing.  Returns the number of passes.
1293
 * MUST be called before png_read_update_info or png_start_read_image,
1294
 * otherwise it will not have the desired effect.  Note that it is still
1295
 * necessary to call png_read_row or png_read_rows png_get_image_height
1296
 * times for each pass.
1297
*/
1298
PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr));
1299
#endif
1300
1301
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
1302
/* Invert monochrome files */
1303
PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr));
1304
#endif
1305
1306
#ifdef PNG_READ_BACKGROUND_SUPPORTED
1307
/* Handle alpha and tRNS by replacing with a background color.  Prior to
1308
 * libpng-1.5.4 this API must not be called before the PNG file header has been
1309
 * read.  Doing so will result in unexpected behavior and possible warnings or
1310
 * errors if the PNG file contains a bKGD chunk.
1311
 */
1312
PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr,
1313
    png_const_color_16p background_color, int background_gamma_code,
1314
    int need_expand, double background_gamma))
1315
PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr,
1316
    png_const_color_16p background_color, int background_gamma_code,
1317
    int need_expand, png_fixed_point background_gamma))
1318
#endif
1319
#ifdef PNG_READ_BACKGROUND_SUPPORTED
1320
0
#  define PNG_BACKGROUND_GAMMA_UNKNOWN 0
1321
0
#  define PNG_BACKGROUND_GAMMA_SCREEN  1
1322
0
#  define PNG_BACKGROUND_GAMMA_FILE    2
1323
0
#  define PNG_BACKGROUND_GAMMA_UNIQUE  3
1324
#endif
1325
1326
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1327
/* Scale a 16-bit depth file down to 8-bit, accurately. */
1328
PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr));
1329
#endif
1330
1331
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
1332
#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */
1333
/* Strip the second byte of information from a 16-bit depth file. */
1334
PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
1335
#endif
1336
1337
#ifdef PNG_READ_QUANTIZE_SUPPORTED
1338
/* Turn on quantizing, and reduce the palette to the number of colors
1339
 * available.
1340
 */
1341
PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr,
1342
    png_colorp palette, int num_palette, int maximum_colors,
1343
    png_const_uint_16p histogram, int full_quantize));
1344
#endif
1345
1346
#ifdef PNG_READ_GAMMA_SUPPORTED
1347
/* The threshold on gamma processing is configurable but hard-wired into the
1348
 * library.  The following is the floating point variant.
1349
 */
1350
#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001)
1351
1352
/* Handle gamma correction. Screen_gamma=(display_exponent).
1353
 * NOTE: this API simply sets the screen and file gamma values. It will
1354
 * therefore override the value for gamma in a PNG file if it is called after
1355
 * the file header has been read - use with care  - call before reading the PNG
1356
 * file for best results!
1357
 *
1358
 * These routines accept the same gamma values as png_set_alpha_mode (described
1359
 * above).  The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either
1360
 * API (floating point or fixed.)  Notice, however, that the 'file_gamma' value
1361
 * is the inverse of a 'screen gamma' value.
1362
 */
1363
PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr,
1364
    double screen_gamma, double override_file_gamma))
1365
PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr,
1366
    png_fixed_point screen_gamma, png_fixed_point override_file_gamma))
1367
#endif
1368
1369
#ifdef PNG_WRITE_FLUSH_SUPPORTED
1370
/* Set how many lines between output flushes - 0 for no flushing */
1371
PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows));
1372
/* Flush the current PNG output buffer */
1373
PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr));
1374
#endif
1375
1376
/* Optional update palette with requested transformations */
1377
PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr));
1378
1379
/* Optional call to update the users info structure */
1380
PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr,
1381
    png_inforp info_ptr));
1382
1383
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1384
/* Read one or more rows of image data. */
1385
PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row,
1386
    png_bytepp display_row, png_uint_32 num_rows));
1387
#endif
1388
1389
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1390
/* Read a row of data. */
1391
PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row,
1392
    png_bytep display_row));
1393
#endif
1394
1395
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1396
/* Read the whole image into memory at once. */
1397
PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image));
1398
#endif
1399
1400
/* Write a row of image data */
1401
PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr,
1402
    png_const_bytep row));
1403
1404
/* Write a few rows of image data: (*row) is not written; however, the type
1405
 * is declared as writeable to maintain compatibility with previous versions
1406
 * of libpng and to allow the 'display_row' array from read_rows to be passed
1407
 * unchanged to write_rows.
1408
 */
1409
PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row,
1410
    png_uint_32 num_rows));
1411
1412
/* Write the image data */
1413
PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image));
1414
1415
/* Write the end of the PNG file. */
1416
PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr,
1417
    png_inforp info_ptr));
1418
1419
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1420
/* Read the end of the PNG file. */
1421
PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr));
1422
#endif
1423
1424
/* Free any memory associated with the png_info_struct */
1425
PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr,
1426
    png_infopp info_ptr_ptr));
1427
1428
/* Free any memory associated with the png_struct and the png_info_structs */
1429
PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,
1430
    png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
1431
1432
/* Free any memory associated with the png_struct and the png_info_structs */
1433
PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,
1434
    png_infopp info_ptr_ptr));
1435
1436
/* Set the libpng method of handling chunk CRC errors */
1437
PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
1438
    int ancil_action));
1439
1440
/* Values for png_set_crc_action() say how to handle CRC errors in
1441
 * ancillary and critical chunks, and whether to use the data contained
1442
 * therein.  Note that it is impossible to "discard" data in a critical
1443
 * chunk.  For versions prior to 0.90, the action was always error/quit,
1444
 * whereas in version 0.90 and later, the action for CRC errors in ancillary
1445
 * chunks is warn/discard.  These values should NOT be changed.
1446
 *
1447
 *      value                       action:critical     action:ancillary
1448
 */
1449
0
#define PNG_CRC_DEFAULT       0  /* error/quit          warn/discard data */
1450
0
#define PNG_CRC_ERROR_QUIT    1  /* error/quit          error/quit        */
1451
0
#define PNG_CRC_WARN_DISCARD  2  /* (INVALID)           warn/discard data */
1452
0
#define PNG_CRC_WARN_USE      3  /* warn/use data       warn/use data     */
1453
7.20k
#define PNG_CRC_QUIET_USE     4  /* quiet/use data      quiet/use data    */
1454
0
#define PNG_CRC_NO_CHANGE     5  /* use current value   use current value */
1455
1456
#ifdef PNG_WRITE_SUPPORTED
1457
/* These functions give the user control over the scan-line filtering in
1458
 * libpng and the compression methods used by zlib.  These functions are
1459
 * mainly useful for testing, as the defaults should work with most users.
1460
 * Those users who are tight on memory or want faster performance at the
1461
 * expense of compression can modify them.  See the compression library
1462
 * header file (zlib.h) for an explanation of the compression functions.
1463
 */
1464
1465
/* Set the filtering method(s) used by libpng.  Currently, the only valid
1466
 * value for "method" is 0.
1467
 */
1468
PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
1469
    int filters));
1470
#endif /* WRITE */
1471
1472
/* Flags for png_set_filter() to say which filters to use.  The flags
1473
 * are chosen so that they don't conflict with real filter types
1474
 * below, in case they are supplied instead of the #defined constants.
1475
 * These values should NOT be changed.
1476
 */
1477
#define PNG_NO_FILTERS     0x00
1478
#define PNG_FILTER_NONE    0x08
1479
#define PNG_FILTER_SUB     0x10
1480
#define PNG_FILTER_UP      0x20
1481
#define PNG_FILTER_AVG     0x40
1482
#define PNG_FILTER_PAETH   0x80
1483
#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP)
1484
#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH)
1485
1486
/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
1487
 * These defines should NOT be changed.
1488
 */
1489
251k
#define PNG_FILTER_VALUE_NONE  0
1490
814
#define PNG_FILTER_VALUE_SUB   1
1491
814
#define PNG_FILTER_VALUE_UP    2
1492
814
#define PNG_FILTER_VALUE_AVG   3
1493
814
#define PNG_FILTER_VALUE_PAETH 4
1494
133k
#define PNG_FILTER_VALUE_LAST  5
1495
1496
#ifdef PNG_WRITE_SUPPORTED
1497
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
1498
PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,
1499
    int heuristic_method, int num_weights, png_const_doublep filter_weights,
1500
    png_const_doublep filter_costs))
1501
PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,
1502
    (png_structrp png_ptr, int heuristic_method, int num_weights,
1503
    png_const_fixed_point_p filter_weights,
1504
    png_const_fixed_point_p filter_costs))
1505
#endif /* WRITE_WEIGHTED_FILTER */
1506
1507
/* The following are no longer used and will be removed from libpng-1.7: */
1508
#define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */
1509
#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */
1510
#define PNG_FILTER_HEURISTIC_WEIGHTED   2  /* Experimental feature */
1511
#define PNG_FILTER_HEURISTIC_LAST       3  /* Not a valid value */
1512
1513
/* Set the library compression level.  Currently, valid values range from
1514
 * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
1515
 * (0 - no compression, 9 - "maximal" compression).  Note that tests have
1516
 * shown that zlib compression levels 3-6 usually perform as well as level 9
1517
 * for PNG images, and do considerably fewer calculations.  In the future,
1518
 * these values may not correspond directly to the zlib compression levels.
1519
 */
1520
#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
1521
PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr,
1522
    int level));
1523
1524
PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr,
1525
    int mem_level));
1526
1527
PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr,
1528
    int strategy));
1529
1530
/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
1531
 * smaller value of window_bits if it can do so safely.
1532
 */
1533
PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr,
1534
    int window_bits));
1535
1536
PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
1537
    int method));
1538
#endif /* WRITE_CUSTOMIZE_COMPRESSION */
1539
1540
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
1541
/* Also set zlib parameters for compressing non-IDAT chunks */
1542
PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr,
1543
    int level));
1544
1545
PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr,
1546
    int mem_level));
1547
1548
PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr,
1549
    int strategy));
1550
1551
/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
1552
 * smaller value of window_bits if it can do so safely.
1553
 */
1554
PNG_EXPORT(225, void, png_set_text_compression_window_bits,
1555
    (png_structrp png_ptr, int window_bits));
1556
1557
PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
1558
    int method));
1559
#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
1560
#endif /* WRITE */
1561
1562
/* These next functions are called for input/output, memory, and error
1563
 * handling.  They are in the file pngrio.c, pngwio.c, and pngerror.c,
1564
 * and call standard C I/O routines such as fread(), fwrite(), and
1565
 * fprintf().  These functions can be made to use other I/O routines
1566
 * at run time for those applications that need to handle I/O in a
1567
 * different manner by calling png_set_???_fn().  See libpng-manual.txt for
1568
 * more information.
1569
 */
1570
1571
#ifdef PNG_STDIO_SUPPORTED
1572
/* Initialize the input/output for the PNG file to the default functions. */
1573
PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, FILE *fp));
1574
#endif
1575
1576
/* Replace the (error and abort), and warning functions with user
1577
 * supplied functions.  If no messages are to be printed you must still
1578
 * write and use replacement functions. The replacement error_fn should
1579
 * still do a longjmp to the last setjmp location if you are using this
1580
 * method of error handling.  If error_fn or warning_fn is NULL, the
1581
 * default function will be used.
1582
 */
1583
1584
PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr,
1585
    png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
1586
1587
/* Return the user pointer associated with the error functions */
1588
PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr));
1589
1590
/* Replace the default data output functions with a user supplied one(s).
1591
 * If buffered output is not used, then output_flush_fn can be set to NULL.
1592
 * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
1593
 * output_flush_fn will be ignored (and thus can be NULL).
1594
 * It is probably a mistake to use NULL for output_flush_fn if
1595
 * write_data_fn is not also NULL unless you have built libpng with
1596
 * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's
1597
 * default flush function, which uses the standard *FILE structure, will
1598
 * be used.
1599
 */
1600
PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr,
1601
    png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
1602
1603
/* Replace the default data input function with a user supplied one. */
1604
PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr,
1605
    png_rw_ptr read_data_fn));
1606
1607
/* Return the user pointer associated with the I/O functions */
1608
PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr));
1609
1610
PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr,
1611
    png_read_status_ptr read_row_fn));
1612
1613
PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr,
1614
    png_write_status_ptr write_row_fn));
1615
1616
#ifdef PNG_USER_MEM_SUPPORTED
1617
/* Replace the default memory allocation functions with user supplied one(s). */
1618
PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr,
1619
    png_malloc_ptr malloc_fn, png_free_ptr free_fn));
1620
/* Return the user pointer associated with the memory functions */
1621
PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr));
1622
#endif
1623
1624
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1625
PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr,
1626
    png_user_transform_ptr read_user_transform_fn));
1627
#endif
1628
1629
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
1630
PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr,
1631
    png_user_transform_ptr write_user_transform_fn));
1632
#endif
1633
1634
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
1635
PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr,
1636
    png_voidp user_transform_ptr, int user_transform_depth,
1637
    int user_transform_channels));
1638
/* Return the user pointer associated with the user transform functions */
1639
PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
1640
    (png_const_structrp png_ptr));
1641
#endif
1642
1643
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
1644
/* Return information about the row currently being processed.  Note that these
1645
 * APIs do not fail but will return unexpected results if called outside a user
1646
 * transform callback.  Also note that when transforming an interlaced image the
1647
 * row number is the row number within the sub-image of the interlace pass, so
1648
 * the value will increase to the height of the sub-image (not the full image)
1649
 * then reset to 0 for the next pass.
1650
 *
1651
 * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
1652
 * find the output pixel (x,y) given an interlaced sub-image pixel
1653
 * (row,col,pass).  (See below for these macros.)
1654
 */
1655
PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp));
1656
PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
1657
#endif
1658
1659
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1660
/* This callback is called only for *unknown* chunks.  If
1661
 * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known
1662
 * chunks to be treated as unknown, however in this case the callback must do
1663
 * any processing required by the chunk (e.g. by calling the appropriate
1664
 * png_set_ APIs.)
1665
 *
1666
 * There is no write support - on write, by default, all the chunks in the
1667
 * 'unknown' list are written in the specified position.
1668
 *
1669
 * The integer return from the callback function is interpreted thus:
1670
 *
1671
 * negative: An error occurred; png_chunk_error will be called.
1672
 *     zero: The chunk was not handled, the chunk will be saved. A critical
1673
 *           chunk will cause an error at this point unless it is to be saved.
1674
 * positive: The chunk was handled, libpng will ignore/discard it.
1675
 *
1676
 * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about
1677
 * how this behavior will change in libpng 1.7
1678
 */
1679
PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr,
1680
    png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
1681
#endif
1682
1683
#ifdef PNG_USER_CHUNKS_SUPPORTED
1684
PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr));
1685
#endif
1686
1687
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1688
/* Sets the function callbacks for the push reader, and a pointer to a
1689
 * user-defined structure available to the callback functions.
1690
 */
1691
PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr,
1692
    png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
1693
    png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn));
1694
1695
/* Returns the user pointer associated with the push read functions */
1696
PNG_EXPORT(91, png_voidp, png_get_progressive_ptr,
1697
    (png_const_structrp png_ptr));
1698
1699
/* Function to be called when data becomes available */
1700
PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
1701
    png_inforp info_ptr, png_bytep buffer, size_t buffer_size));
1702
1703
/* A function which may be called *only* within png_process_data to stop the
1704
 * processing of any more data.  The function returns the number of bytes
1705
 * remaining, excluding any that libpng has cached internally.  A subsequent
1706
 * call to png_process_data must supply these bytes again.  If the argument
1707
 * 'save' is set to true the routine will first save all the pending data and
1708
 * will always return 0.
1709
 */
1710
PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save));
1711
1712
/* A function which may be called *only* outside (after) a call to
1713
 * png_process_data.  It returns the number of bytes of data to skip in the
1714
 * input.  Normally it will return 0, but if it returns a non-zero value the
1715
 * application must skip than number of bytes of input data and pass the
1716
 * following data to the next call to png_process_data.
1717
 */
1718
PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp));
1719
1720
/* Function that combines rows.  'new_row' is a flag that should come from
1721
 * the callback and be non-NULL if anything needs to be done; the library
1722
 * stores its own version of the new data internally and ignores the passed
1723
 * in value.
1724
 */
1725
PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr,
1726
    png_bytep old_row, png_const_bytep new_row));
1727
#endif /* PROGRESSIVE_READ */
1728
1729
PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr,
1730
    png_alloc_size_t size), PNG_ALLOCATED);
1731
/* Added at libpng version 1.4.0 */
1732
PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr,
1733
    png_alloc_size_t size), PNG_ALLOCATED);
1734
1735
/* Added at libpng version 1.2.4 */
1736
PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr,
1737
    png_alloc_size_t size), PNG_ALLOCATED);
1738
1739
/* Frees a pointer allocated by png_malloc() */
1740
PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));
1741
1742
/* Free data that was allocated internally */
1743
PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
1744
    png_inforp info_ptr, png_uint_32 free_me, int num));
1745
1746
/* Reassign the responsibility for freeing existing data, whether allocated
1747
 * by libpng or by the application; this works on the png_info structure passed
1748
 * in, without changing the state for other png_info structures.
1749
 */
1750
PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
1751
    png_inforp info_ptr, int freer, png_uint_32 mask));
1752
1753
/* Assignments for png_data_freer */
1754
0
#define PNG_DESTROY_WILL_FREE_DATA 1
1755
#define PNG_SET_WILL_FREE_DATA 1
1756
0
#define PNG_USER_WILL_FREE_DATA 2
1757
/* Flags for png_ptr->free_me and info_ptr->free_me */
1758
5.01k
#define PNG_FREE_HIST 0x0008U
1759
5.01k
#define PNG_FREE_ICCP 0x0010U
1760
464
#define PNG_FREE_SPLT 0x0020U
1761
5.01k
#define PNG_FREE_ROWS 0x0040U
1762
5.07k
#define PNG_FREE_PCAL 0x0080U
1763
5.09k
#define PNG_FREE_SCAL 0x0100U
1764
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1765
0
#  define PNG_FREE_UNKN 0x0200U
1766
#endif
1767
/*      PNG_FREE_LIST 0x0400U   removed in 1.6.0 because it is ignored */
1768
10.2k
#define PNG_FREE_PLTE 0x1000U
1769
11.2k
#define PNG_FREE_TRNS 0x2000U
1770
2.11k
#define PNG_FREE_TEXT 0x4000U
1771
5.05k
#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */
1772
4.02k
#define PNG_FREE_ALL  0xffffU
1773
988
#define PNG_FREE_MUL  0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
1774
1775
#ifdef PNG_USER_MEM_SUPPORTED
1776
PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
1777
    png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED);
1778
PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr,
1779
    png_voidp ptr), PNG_DEPRECATED);
1780
#endif
1781
1782
#ifdef PNG_ERROR_TEXT_SUPPORTED
1783
/* Fatal error in PNG image of libpng - can't continue */
1784
PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr,
1785
    png_const_charp error_message), PNG_NORETURN);
1786
1787
/* The same, but the chunk name is prepended to the error string. */
1788
PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr,
1789
    png_const_charp error_message), PNG_NORETURN);
1790
1791
#else
1792
/* Fatal error in PNG image of libpng - can't continue */
1793
PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN);
1794
#  define png_error(s1,s2) png_err(s1)
1795
#  define png_chunk_error(s1,s2) png_err(s1)
1796
#endif
1797
1798
#ifdef PNG_WARNINGS_SUPPORTED
1799
/* Non-fatal error in libpng.  Can continue, but may have a problem. */
1800
PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr,
1801
    png_const_charp warning_message));
1802
1803
/* Non-fatal error in libpng, chunk name is prepended to message. */
1804
PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,
1805
    png_const_charp warning_message));
1806
#else
1807
#  define png_warning(s1,s2) ((void)(s1))
1808
#  define png_chunk_warning(s1,s2) ((void)(s1))
1809
#endif
1810
1811
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1812
/* Benign error in libpng.  Can continue, but may have a problem.
1813
 * User can choose whether to handle as a fatal error or as a warning. */
1814
PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr,
1815
    png_const_charp warning_message));
1816
1817
#ifdef PNG_READ_SUPPORTED
1818
/* Same, chunk name is prepended to message (only during read) */
1819
PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr,
1820
    png_const_charp warning_message));
1821
#endif
1822
1823
PNG_EXPORT(109, void, png_set_benign_errors,
1824
    (png_structrp png_ptr, int allowed));
1825
#else
1826
#  ifdef PNG_ALLOW_BENIGN_ERRORS
1827
#    define png_benign_error png_warning
1828
#    define png_chunk_benign_error png_chunk_warning
1829
#  else
1830
#    define png_benign_error png_error
1831
#    define png_chunk_benign_error png_chunk_error
1832
#  endif
1833
#endif
1834
1835
/* The png_set_<chunk> functions are for storing values in the png_info_struct.
1836
 * Similarly, the png_get_<chunk> calls are used to read values from the
1837
 * png_info_struct, either storing the parameters in the passed variables, or
1838
 * setting pointers into the png_info_struct where the data is stored.  The
1839
 * png_get_<chunk> functions return a non-zero value if the data was available
1840
 * in info_ptr, or return zero and do not change any of the parameters if the
1841
 * data was not available.
1842
 *
1843
 * These functions should be used instead of directly accessing png_info
1844
 * to avoid problems with future changes in the size and internal layout of
1845
 * png_info_struct.
1846
 */
1847
/* Returns "flag" if chunk data is valid in info_ptr. */
1848
PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,
1849
    png_const_inforp info_ptr, png_uint_32 flag));
1850
1851
/* Returns number of bytes needed to hold a transformed row. */
1852
PNG_EXPORT(111, size_t, png_get_rowbytes, (png_const_structrp png_ptr,
1853
    png_const_inforp info_ptr));
1854
1855
#ifdef PNG_INFO_IMAGE_SUPPORTED
1856
/* Returns row_pointers, which is an array of pointers to scanlines that was
1857
 * returned from png_read_png().
1858
 */
1859
PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr,
1860
    png_const_inforp info_ptr));
1861
1862
/* Set row_pointers, which is an array of pointers to scanlines for use
1863
 * by png_write_png().
1864
 */
1865
PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr,
1866
    png_inforp info_ptr, png_bytepp row_pointers));
1867
#endif
1868
1869
/* Returns number of color channels in image. */
1870
PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr,
1871
    png_const_inforp info_ptr));
1872
1873
#ifdef PNG_EASY_ACCESS_SUPPORTED
1874
/* Returns image width in pixels. */
1875
PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr,
1876
    png_const_inforp info_ptr));
1877
1878
/* Returns image height in pixels. */
1879
PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr,
1880
    png_const_inforp info_ptr));
1881
1882
/* Returns image bit_depth. */
1883
PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr,
1884
    png_const_inforp info_ptr));
1885
1886
/* Returns image color_type. */
1887
PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr,
1888
    png_const_inforp info_ptr));
1889
1890
/* Returns image filter_type. */
1891
PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr,
1892
    png_const_inforp info_ptr));
1893
1894
/* Returns image interlace_type. */
1895
PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr,
1896
    png_const_inforp info_ptr));
1897
1898
/* Returns image compression_type. */
1899
PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr,
1900
    png_const_inforp info_ptr));
1901
1902
/* Returns image resolution in pixels per meter, from pHYs chunk data. */
1903
PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter,
1904
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
1905
PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,
1906
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
1907
PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,
1908
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
1909
1910
/* Returns pixel aspect ratio, computed from pHYs chunk data.  */
1911
PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio,
1912
    (png_const_structrp png_ptr, png_const_inforp info_ptr))
1913
PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,
1914
    (png_const_structrp png_ptr, png_const_inforp info_ptr))
1915
1916
/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
1917
PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels,
1918
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
1919
PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,
1920
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
1921
PNG_EXPORT(128, png_int_32, png_get_x_offset_microns,
1922
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
1923
PNG_EXPORT(129, png_int_32, png_get_y_offset_microns,
1924
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
1925
1926
#endif /* EASY_ACCESS */
1927
1928
#ifdef PNG_READ_SUPPORTED
1929
/* Returns pointer to signature string read from PNG header */
1930
PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr,
1931
    png_const_inforp info_ptr));
1932
#endif
1933
1934
#ifdef PNG_bKGD_SUPPORTED
1935
PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr,
1936
    png_inforp info_ptr, png_color_16p *background));
1937
#endif
1938
1939
#ifdef PNG_bKGD_SUPPORTED
1940
PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr,
1941
    png_inforp info_ptr, png_const_color_16p background));
1942
#endif
1943
1944
#ifdef PNG_cHRM_SUPPORTED
1945
PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr,
1946
    png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x,
1947
    double *red_y, double *green_x, double *green_y, double *blue_x,
1948
    double *blue_y))
1949
PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr,
1950
    png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z,
1951
    double *green_X, double *green_Y, double *green_Z, double *blue_X,
1952
    double *blue_Y, double *blue_Z))
1953
PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
1954
    (png_const_structrp png_ptr, png_const_inforp info_ptr,
1955
    png_fixed_point *int_white_x, png_fixed_point *int_white_y,
1956
    png_fixed_point *int_red_x, png_fixed_point *int_red_y,
1957
    png_fixed_point *int_green_x, png_fixed_point *int_green_y,
1958
    png_fixed_point *int_blue_x, png_fixed_point *int_blue_y))
1959
PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,
1960
    (png_const_structrp png_ptr, png_const_inforp info_ptr,
1961
    png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
1962
    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
1963
    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
1964
    png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
1965
    png_fixed_point *int_blue_Z))
1966
#endif
1967
1968
#ifdef PNG_cHRM_SUPPORTED
1969
PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr,
1970
    png_inforp info_ptr,
1971
    double white_x, double white_y, double red_x, double red_y, double green_x,
1972
    double green_y, double blue_x, double blue_y))
1973
PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr,
1974
    png_inforp info_ptr, double red_X, double red_Y, double red_Z,
1975
    double green_X, double green_Y, double green_Z, double blue_X,
1976
    double blue_Y, double blue_Z))
1977
PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr,
1978
    png_inforp info_ptr, png_fixed_point int_white_x,
1979
    png_fixed_point int_white_y, png_fixed_point int_red_x,
1980
    png_fixed_point int_red_y, png_fixed_point int_green_x,
1981
    png_fixed_point int_green_y, png_fixed_point int_blue_x,
1982
    png_fixed_point int_blue_y))
1983
PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
1984
    png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,
1985
    png_fixed_point int_red_Z, png_fixed_point int_green_X,
1986
    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
1987
    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
1988
    png_fixed_point int_blue_Z))
1989
#endif
1990
1991
#ifdef PNG_cICP_SUPPORTED
1992
PNG_EXPORT(250, png_uint_32, png_get_cICP, (png_const_structrp png_ptr,
1993
    png_const_inforp info_ptr, png_bytep colour_primaries,
1994
    png_bytep transfer_function, png_bytep matrix_coefficients,
1995
    png_bytep video_full_range_flag));
1996
#endif
1997
1998
#ifdef PNG_cICP_SUPPORTED
1999
PNG_EXPORT(251, void, png_set_cICP, (png_const_structrp png_ptr,
2000
    png_inforp info_ptr, png_byte colour_primaries,
2001
    png_byte transfer_function, png_byte matrix_coefficients,
2002
    png_byte video_full_range_flag));
2003
#endif
2004
2005
#ifdef PNG_cLLI_SUPPORTED
2006
PNG_FP_EXPORT(252, png_uint_32, png_get_cLLI, (png_const_structrp png_ptr,
2007
         png_const_inforp info_ptr, double *maximum_content_light_level,
2008
         double *maximum_frame_average_light_level))
2009
PNG_FIXED_EXPORT(253, png_uint_32, png_get_cLLI_fixed,
2010
    (png_const_structrp png_ptr, png_const_inforp info_ptr,
2011
    /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
2012
     * 100,000 as in the case of png_fixed_point.
2013
     */
2014
    png_uint_32p maximum_content_light_level_scaled_by_10000,
2015
    png_uint_32p maximum_frame_average_light_level_scaled_by_10000))
2016
#endif
2017
2018
#ifdef PNG_cLLI_SUPPORTED
2019
PNG_FP_EXPORT(254, void, png_set_cLLI, (png_const_structrp png_ptr,
2020
         png_inforp info_ptr, double maximum_content_light_level,
2021
         double maximum_frame_average_light_level))
2022
PNG_FIXED_EXPORT(255, void, png_set_cLLI_fixed, (png_const_structrp png_ptr,
2023
    png_inforp info_ptr,
2024
    /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
2025
     * 100,000 as in the case of png_fixed_point.
2026
     */
2027
    png_uint_32 maximum_content_light_level_scaled_by_10000,
2028
    png_uint_32 maximum_frame_average_light_level_scaled_by_10000))
2029
#endif
2030
2031
#ifdef PNG_eXIf_SUPPORTED
2032
PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr,
2033
    png_inforp info_ptr, png_bytep *exif));
2034
PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr,
2035
    png_inforp info_ptr, png_bytep exif));
2036
2037
PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr,
2038
    png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif));
2039
PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr,
2040
    png_inforp info_ptr, png_uint_32 num_exif, png_bytep exif));
2041
#endif
2042
2043
#ifdef PNG_gAMA_SUPPORTED
2044
PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
2045
    png_const_inforp info_ptr, double *file_gamma))
2046
PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,
2047
    (png_const_structrp png_ptr, png_const_inforp info_ptr,
2048
    png_fixed_point *int_file_gamma))
2049
#endif
2050
2051
#ifdef PNG_gAMA_SUPPORTED
2052
PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr,
2053
    png_inforp info_ptr, double file_gamma))
2054
PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
2055
    png_inforp info_ptr, png_fixed_point int_file_gamma))
2056
#endif
2057
2058
#ifdef PNG_hIST_SUPPORTED
2059
PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
2060
    png_inforp info_ptr, png_uint_16p *hist));
2061
PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
2062
    png_inforp info_ptr, png_const_uint_16p hist));
2063
#endif
2064
2065
PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr,
2066
    png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,
2067
    int *bit_depth, int *color_type, int *interlace_method,
2068
    int *compression_method, int *filter_method));
2069
2070
PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr,
2071
    png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
2072
    int color_type, int interlace_method, int compression_method,
2073
    int filter_method));
2074
2075
#ifdef PNG_mDCV_SUPPORTED
2076
PNG_FP_EXPORT(256, png_uint_32, png_get_mDCV, (png_const_structrp png_ptr,
2077
    png_const_inforp info_ptr,
2078
    /* The chromaticities of the mastering display.  As cHRM, but independent of
2079
     * the encoding endpoints in cHRM, or cICP, or iCCP.  These values will
2080
     * always be in the range 0 to 1.3107.
2081
     */
2082
    double *white_x, double *white_y, double *red_x, double *red_y,
2083
    double *green_x, double *green_y, double *blue_x, double *blue_y,
2084
    /* Mastering display luminance in cd/m2 (nits). */
2085
    double *mastering_display_maximum_luminance,
2086
    double *mastering_display_minimum_luminance))
2087
2088
PNG_FIXED_EXPORT(257, png_uint_32, png_get_mDCV_fixed,
2089
    (png_const_structrp png_ptr, png_const_inforp info_ptr,
2090
    png_fixed_point *int_white_x, png_fixed_point *int_white_y,
2091
    png_fixed_point *int_red_x, png_fixed_point *int_red_y,
2092
    png_fixed_point *int_green_x, png_fixed_point *int_green_y,
2093
    png_fixed_point *int_blue_x, png_fixed_point *int_blue_y,
2094
    /* Mastering display luminance in cd/m2 (nits) multiplied (scaled) by
2095
     * 10,000.
2096
     */
2097
    png_uint_32p mastering_display_maximum_luminance_scaled_by_10000,
2098
    png_uint_32p mastering_display_minimum_luminance_scaled_by_10000))
2099
#endif
2100
2101
#ifdef PNG_mDCV_SUPPORTED
2102
PNG_FP_EXPORT(258, void, png_set_mDCV, (png_const_structrp png_ptr,
2103
    png_inforp info_ptr,
2104
    /* The chromaticities of the mastering display.  As cHRM, but independent of
2105
     * the encoding endpoints in cHRM, or cICP, or iCCP.
2106
     */
2107
    double white_x, double white_y, double red_x, double red_y, double green_x,
2108
    double green_y, double blue_x, double blue_y,
2109
    /* Mastering display luminance in cd/m2 (nits). */
2110
    double mastering_display_maximum_luminance,
2111
    double mastering_display_minimum_luminance))
2112
2113
PNG_FIXED_EXPORT(259, void, png_set_mDCV_fixed, (png_const_structrp png_ptr,
2114
    png_inforp info_ptr,
2115
    /* The admissible range of these values is not the full range of a PNG
2116
     * fixed point value.  Negative values cannot be encoded and the maximum
2117
     * value is about 1.3 */
2118
    png_fixed_point int_white_x, png_fixed_point int_white_y,
2119
    png_fixed_point int_red_x, png_fixed_point int_red_y,
2120
    png_fixed_point int_green_x, png_fixed_point int_green_y,
2121
    png_fixed_point int_blue_x, png_fixed_point int_blue_y,
2122
    /* These are PNG unsigned 4 byte values: 31-bit unsigned values.  The MSB
2123
     * must be zero.
2124
     */
2125
    png_uint_32 mastering_display_maximum_luminance_scaled_by_10000,
2126
    png_uint_32 mastering_display_minimum_luminance_scaled_by_10000))
2127
#endif
2128
2129
#ifdef PNG_oFFs_SUPPORTED
2130
PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr,
2131
   png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
2132
   int *unit_type));
2133
#endif
2134
2135
#ifdef PNG_oFFs_SUPPORTED
2136
PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr,
2137
    png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y,
2138
    int unit_type));
2139
#endif
2140
2141
#ifdef PNG_pCAL_SUPPORTED
2142
PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr,
2143
    png_inforp info_ptr, png_charp *purpose, png_int_32 *X0,
2144
    png_int_32 *X1, int *type, int *nparams, png_charp *units,
2145
    png_charpp *params));
2146
#endif
2147
2148
#ifdef PNG_pCAL_SUPPORTED
2149
PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr,
2150
    png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1,
2151
    int type, int nparams, png_const_charp units, png_charpp params));
2152
#endif
2153
2154
#ifdef PNG_pHYs_SUPPORTED
2155
PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr,
2156
    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
2157
    int *unit_type));
2158
#endif
2159
2160
#ifdef PNG_pHYs_SUPPORTED
2161
PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr,
2162
    png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
2163
#endif
2164
2165
PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr,
2166
   png_inforp info_ptr, png_colorp *palette, int *num_palette));
2167
2168
PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr,
2169
    png_inforp info_ptr, png_const_colorp palette, int num_palette));
2170
2171
#ifdef PNG_sBIT_SUPPORTED
2172
PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr,
2173
    png_inforp info_ptr, png_color_8p *sig_bit));
2174
#endif
2175
2176
#ifdef PNG_sBIT_SUPPORTED
2177
PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr,
2178
    png_inforp info_ptr, png_const_color_8p sig_bit));
2179
#endif
2180
2181
#ifdef PNG_sRGB_SUPPORTED
2182
PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr,
2183
    png_const_inforp info_ptr, int *file_srgb_intent));
2184
#endif
2185
2186
#ifdef PNG_sRGB_SUPPORTED
2187
PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr,
2188
    png_inforp info_ptr, int srgb_intent));
2189
PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr,
2190
    png_inforp info_ptr, int srgb_intent));
2191
#endif
2192
2193
#ifdef PNG_iCCP_SUPPORTED
2194
PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr,
2195
    png_inforp info_ptr, png_charpp name, int *compression_type,
2196
    png_bytepp profile, png_uint_32 *proflen));
2197
#endif
2198
2199
#ifdef PNG_iCCP_SUPPORTED
2200
PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr,
2201
    png_inforp info_ptr, png_const_charp name, int compression_type,
2202
    png_const_bytep profile, png_uint_32 proflen));
2203
#endif
2204
2205
#ifdef PNG_sPLT_SUPPORTED
2206
PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr,
2207
    png_inforp info_ptr, png_sPLT_tpp entries));
2208
#endif
2209
2210
#ifdef PNG_sPLT_SUPPORTED
2211
PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr,
2212
    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries));
2213
#endif
2214
2215
#ifdef PNG_TEXT_SUPPORTED
2216
/* png_get_text also returns the number of text chunks in *num_text */
2217
PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr,
2218
    png_inforp info_ptr, png_textp *text_ptr, int *num_text));
2219
#endif
2220
2221
/* Note while png_set_text() will accept a structure whose text,
2222
 * language, and  translated keywords are NULL pointers, the structure
2223
 * returned by png_get_text will always contain regular
2224
 * zero-terminated C strings.  They might be empty strings but
2225
 * they will never be NULL pointers.
2226
 */
2227
2228
#ifdef PNG_TEXT_SUPPORTED
2229
PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr,
2230
    png_inforp info_ptr, png_const_textp text_ptr, int num_text));
2231
#endif
2232
2233
#ifdef PNG_tIME_SUPPORTED
2234
PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr,
2235
    png_inforp info_ptr, png_timep *mod_time));
2236
#endif
2237
2238
#ifdef PNG_tIME_SUPPORTED
2239
PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr,
2240
    png_inforp info_ptr, png_const_timep mod_time));
2241
#endif
2242
2243
#ifdef PNG_tRNS_SUPPORTED
2244
PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr,
2245
    png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans,
2246
    png_color_16p *trans_color));
2247
#endif
2248
2249
#ifdef PNG_tRNS_SUPPORTED
2250
PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr,
2251
    png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans,
2252
    png_const_color_16p trans_color));
2253
#endif
2254
2255
#ifdef PNG_sCAL_SUPPORTED
2256
PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr,
2257
    png_const_inforp info_ptr, int *unit, double *width, double *height))
2258
#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
2259
   defined(PNG_FLOATING_POINT_SUPPORTED)
2260
/* NOTE: this API is currently implemented using floating point arithmetic,
2261
 * consequently it can only be used on systems with floating point support.
2262
 * In any case the range of values supported by png_fixed_point is small and it
2263
 * is highly recommended that png_get_sCAL_s be used instead.
2264
 */
2265
PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed,
2266
    (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
2267
    png_fixed_point *width, png_fixed_point *height))
2268
#endif
2269
PNG_EXPORT(169, png_uint_32, png_get_sCAL_s,
2270
    (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
2271
    png_charpp swidth, png_charpp sheight));
2272
2273
PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr,
2274
    png_inforp info_ptr, int unit, double width, double height))
2275
PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr,
2276
   png_inforp info_ptr, int unit, png_fixed_point width,
2277
   png_fixed_point height))
2278
PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
2279
    png_inforp info_ptr, int unit,
2280
    png_const_charp swidth, png_const_charp sheight));
2281
#endif /* sCAL */
2282
2283
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
2284
/* Provide the default handling for all unknown chunks or, optionally, for
2285
 * specific unknown chunks.
2286
 *
2287
 * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was
2288
 * ignored and the default was used, the per-chunk setting only had an effect on
2289
 * write.  If you wish to have chunk-specific handling on read in code that must
2290
 * work on earlier versions you must use a user chunk callback to specify the
2291
 * desired handling (keep or discard.)
2292
 *
2293
 * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below.  The
2294
 * parameter is interpreted as follows:
2295
 *
2296
 * READ:
2297
 *    PNG_HANDLE_CHUNK_AS_DEFAULT:
2298
 *       Known chunks: do normal libpng processing, do not keep the chunk (but
2299
 *          see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
2300
 *       Unknown chunks: for a specific chunk use the global default, when used
2301
 *          as the default discard the chunk data.
2302
 *    PNG_HANDLE_CHUNK_NEVER:
2303
 *       Discard the chunk data.
2304
 *    PNG_HANDLE_CHUNK_IF_SAFE:
2305
 *       Keep the chunk data if the chunk is not critical else raise a chunk
2306
 *       error.
2307
 *    PNG_HANDLE_CHUNK_ALWAYS:
2308
 *       Keep the chunk data.
2309
 *
2310
 * If the chunk data is saved it can be retrieved using png_get_unknown_chunks,
2311
 * below.  Notice that specifying "AS_DEFAULT" as a global default is equivalent
2312
 * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks
2313
 * it simply resets the behavior to the libpng default.
2314
 *
2315
 * INTERACTION WITH USER CHUNK CALLBACKS:
2316
 * The per-chunk handling is always used when there is a png_user_chunk_ptr
2317
 * callback and the callback returns 0; the chunk is then always stored *unless*
2318
 * it is critical and the per-chunk setting is other than ALWAYS.  Notice that
2319
 * the global default is *not* used in this case.  (In effect the per-chunk
2320
 * value is incremented to at least IF_SAFE.)
2321
 *
2322
 * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and
2323
 * per-chunk defaults will be honored.  If you want to preserve the current
2324
 * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE
2325
 * as the default - if you don't do this libpng 1.6 will issue a warning.
2326
 *
2327
 * If you want unhandled unknown chunks to be discarded in libpng 1.6 and
2328
 * earlier simply return '1' (handled).
2329
 *
2330
 * PNG_HANDLE_AS_UNKNOWN_SUPPORTED:
2331
 *    If this is *not* set known chunks will always be handled by libpng and
2332
 *    will never be stored in the unknown chunk list.  Known chunks listed to
2333
 *    png_set_keep_unknown_chunks will have no effect.  If it is set then known
2334
 *    chunks listed with a keep other than AS_DEFAULT will *never* be processed
2335
 *    by libpng, in addition critical chunks must either be processed by the
2336
 *    callback or saved.
2337
 *
2338
 *    The IHDR and IEND chunks must not be listed.  Because this turns off the
2339
 *    default handling for chunks that would otherwise be recognized the
2340
 *    behavior of libpng transformations may well become incorrect!
2341
 *
2342
 * WRITE:
2343
 *    When writing chunks the options only apply to the chunks specified by
2344
 *    png_set_unknown_chunks (below), libpng will *always* write known chunks
2345
 *    required by png_set_ calls and will always write the core critical chunks
2346
 *    (as required for PLTE).
2347
 *
2348
 *    Each chunk in the png_set_unknown_chunks list is looked up in the
2349
 *    png_set_keep_unknown_chunks list to find the keep setting, this is then
2350
 *    interpreted as follows:
2351
 *
2352
 *    PNG_HANDLE_CHUNK_AS_DEFAULT:
2353
 *       Write safe-to-copy chunks and write other chunks if the global
2354
 *       default is set to _ALWAYS, otherwise don't write this chunk.
2355
 *    PNG_HANDLE_CHUNK_NEVER:
2356
 *       Do not write the chunk.
2357
 *    PNG_HANDLE_CHUNK_IF_SAFE:
2358
 *       Write the chunk if it is safe-to-copy, otherwise do not write it.
2359
 *    PNG_HANDLE_CHUNK_ALWAYS:
2360
 *       Write the chunk.
2361
 *
2362
 * Note that the default behavior is effectively the opposite of the read case -
2363
 * in read unknown chunks are not stored by default, in write they are written
2364
 * by default.  Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different
2365
 * - on write the safe-to-copy bit is checked, on read the critical bit is
2366
 * checked and on read if the chunk is critical an error will be raised.
2367
 *
2368
 * num_chunks:
2369
 * ===========
2370
 *    If num_chunks is positive, then the "keep" parameter specifies the manner
2371
 *    for handling only those chunks appearing in the chunk_list array,
2372
 *    otherwise the chunk list array is ignored.
2373
 *
2374
 *    If num_chunks is 0 the "keep" parameter specifies the default behavior for
2375
 *    unknown chunks, as described above.
2376
 *
2377
 *    If num_chunks is negative, then the "keep" parameter specifies the manner
2378
 *    for handling all unknown chunks plus all chunks recognized by libpng
2379
 *    except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
2380
 *    be processed by libpng.
2381
 */
2382
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2383
PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
2384
    int keep, png_const_bytep chunk_list, int num_chunks));
2385
#endif /* HANDLE_AS_UNKNOWN */
2386
2387
/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
2388
 * the result is therefore true (non-zero) if special handling is required,
2389
 * false for the default handling.
2390
 */
2391
PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
2392
    png_const_bytep chunk_name));
2393
#endif /* SET_UNKNOWN_CHUNKS */
2394
2395
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
2396
PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
2397
    png_inforp info_ptr, png_const_unknown_chunkp unknowns,
2398
    int num_unknowns));
2399
   /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added
2400
    * unknowns to the location currently stored in the png_struct.  This is
2401
    * invariably the wrong value on write.  To fix this call the following API
2402
    * for each chunk in the list with the correct location.  If you know your
2403
    * code won't be compiled on earlier versions you can rely on
2404
    * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing
2405
    * the correct thing.
2406
    */
2407
2408
PNG_EXPORT(175, void, png_set_unknown_chunk_location,
2409
    (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location));
2410
2411
PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr,
2412
    png_inforp info_ptr, png_unknown_chunkpp entries));
2413
#endif
2414
2415
/* Png_free_data() will turn off the "valid" flag for anything it frees.
2416
 * If you need to turn it off for a chunk that your application has freed,
2417
 * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
2418
 */
2419
PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr,
2420
    png_inforp info_ptr, int mask));
2421
2422
#ifdef PNG_INFO_IMAGE_SUPPORTED
2423
/* The "params" pointer is currently not used and is for future expansion. */
2424
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
2425
PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr,
2426
    int transforms, png_voidp params));
2427
#endif
2428
#ifdef PNG_WRITE_SUPPORTED
2429
PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr,
2430
    int transforms, png_voidp params));
2431
#endif
2432
#endif
2433
2434
PNG_EXPORT(180, png_const_charp, png_get_copyright,
2435
    (png_const_structrp png_ptr));
2436
PNG_EXPORT(181, png_const_charp, png_get_header_ver,
2437
    (png_const_structrp png_ptr));
2438
PNG_EXPORT(182, png_const_charp, png_get_header_version,
2439
    (png_const_structrp png_ptr));
2440
PNG_EXPORT(183, png_const_charp, png_get_libpng_ver,
2441
    (png_const_structrp png_ptr));
2442
2443
#ifdef PNG_MNG_FEATURES_SUPPORTED
2444
PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,
2445
    png_uint_32 mng_features_permitted));
2446
#endif
2447
2448
/* For use in png_set_keep_unknown, added to version 1.2.6 */
2449
48.1k
#define PNG_HANDLE_CHUNK_AS_DEFAULT   0
2450
419
#define PNG_HANDLE_CHUNK_NEVER        1
2451
7.33k
#define PNG_HANDLE_CHUNK_IF_SAFE      2
2452
7.36k
#define PNG_HANDLE_CHUNK_ALWAYS       3
2453
838
#define PNG_HANDLE_CHUNK_LAST         4
2454
2455
/* Strip the prepended error numbers ("#nnn ") from error and warning
2456
 * messages before passing them to the error or warning handler.
2457
 */
2458
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
2459
PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr,
2460
    png_uint_32 strip_mode));
2461
#endif
2462
2463
/* Added in libpng-1.2.6 */
2464
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
2465
PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr,
2466
    png_uint_32 user_width_max, png_uint_32 user_height_max));
2467
PNG_EXPORT(187, png_uint_32, png_get_user_width_max,
2468
    (png_const_structrp png_ptr));
2469
PNG_EXPORT(188, png_uint_32, png_get_user_height_max,
2470
    (png_const_structrp png_ptr));
2471
/* Added in libpng-1.4.0 */
2472
PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr,
2473
    png_uint_32 user_chunk_cache_max));
2474
PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max,
2475
    (png_const_structrp png_ptr));
2476
/* Added in libpng-1.4.1 */
2477
PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr,
2478
    png_alloc_size_t user_chunk_cache_max));
2479
PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max,
2480
    (png_const_structrp png_ptr));
2481
#endif
2482
2483
#if defined(PNG_INCH_CONVERSIONS_SUPPORTED)
2484
PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,
2485
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
2486
2487
PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,
2488
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
2489
2490
PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,
2491
    (png_const_structrp png_ptr, png_const_inforp info_ptr));
2492
2493
PNG_FP_EXPORT(196, float, png_get_x_offset_inches,
2494
    (png_const_structrp png_ptr, png_const_inforp info_ptr))
2495
#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
2496
PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed,
2497
    (png_const_structrp png_ptr, png_const_inforp info_ptr))
2498
#endif
2499
2500
PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr,
2501
    png_const_inforp info_ptr))
2502
#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
2503
PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed,
2504
    (png_const_structrp png_ptr, png_const_inforp info_ptr))
2505
#endif
2506
2507
#  ifdef PNG_pHYs_SUPPORTED
2508
PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr,
2509
    png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
2510
    int *unit_type));
2511
#  endif /* pHYs */
2512
#endif  /* INCH_CONVERSIONS */
2513
2514
/* Added in libpng-1.4.0 */
2515
#ifdef PNG_IO_STATE_SUPPORTED
2516
PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr));
2517
2518
/* Removed from libpng 1.6; use png_get_io_chunk_type. */
2519
PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr),
2520
    PNG_DEPRECATED)
2521
2522
PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
2523
    (png_const_structrp png_ptr));
2524
2525
/* The flags returned by png_get_io_state() are the following: */
2526
#  define PNG_IO_NONE        0x0000   /* no I/O at this moment */
2527
113k
#  define PNG_IO_READING     0x0001   /* currently reading */
2528
#  define PNG_IO_WRITING     0x0002   /* currently writing */
2529
425
#  define PNG_IO_SIGNATURE   0x0010   /* currently at the file signature */
2530
38.1k
#  define PNG_IO_CHUNK_HDR   0x0020   /* currently at the chunk header */
2531
37.9k
#  define PNG_IO_CHUNK_DATA  0x0040   /* currently at the chunk data */
2532
36.8k
#  define PNG_IO_CHUNK_CRC   0x0080   /* currently at the chunk crc */
2533
#  define PNG_IO_MASK_OP     0x000f   /* current operation: reading/writing */
2534
#  define PNG_IO_MASK_LOC    0x00f0   /* current location: sig/hdr/data/crc */
2535
#endif /* IO_STATE */
2536
2537
/* Interlace support.  The following macros are always defined so that if
2538
 * libpng interlace handling is turned off the macros may be used to handle
2539
 * interlaced images within the application.
2540
 */
2541
0
#define PNG_INTERLACE_ADAM7_PASSES 7
2542
2543
/* Two macros to return the first row and first column of the original,
2544
 * full, image which appears in a given pass.  'pass' is in the range 0
2545
 * to 6 and the result is in the range 0 to 7.
2546
 */
2547
0
#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7)
2548
92.8k
#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7)
2549
2550
/* A macro to return the offset between pixels in the output row for a pair of
2551
 * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that
2552
 * follows.  Note that ROW_OFFSET is the offset from one row to the next whereas
2553
 * COL_OFFSET is from one column to the next, within a row.
2554
 */
2555
0
#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8)
2556
46.4k
#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1))
2557
2558
/* Two macros to help evaluate the number of rows or columns in each
2559
 * pass.  This is expressed as a shift - effectively log2 of the number or
2560
 * rows or columns in each 8x8 tile of the original image.
2561
 */
2562
#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
2563
0
#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
2564
2565
/* Hence two macros to determine the number of rows or columns in a given
2566
 * pass of an image given its height or width.  In fact these macros may
2567
 * return non-zero even though the sub-image is empty, because the other
2568
 * dimension may be empty for a small image.
2569
 */
2570
#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
2571
   -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
2572
0
#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
2573
0
   -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
2574
2575
/* For the reader row callbacks (both progressive and sequential) it is
2576
 * necessary to find the row in the output image given a row in an interlaced
2577
 * image, so two more macros:
2578
 */
2579
#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \
2580
   (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
2581
#define PNG_COL_FROM_PASS_COL(x_in, pass) \
2582
   (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
2583
2584
/* Two macros which return a boolean (0 or 1) saying whether the given row
2585
 * or column is in a particular pass.  These use a common utility macro that
2586
 * returns a mask for a given pass - the offset 'off' selects the row or
2587
 * column version.  The mask has the appropriate bit set for each column in
2588
 * the tile.
2589
 */
2590
#define PNG_PASS_MASK(pass,off) ( \
2591
   ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \
2592
   ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0))
2593
2594
#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
2595
   ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
2596
#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
2597
   ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
2598
2599
#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
2600
/* With these routines we avoid an integer divide, which will be slower on
2601
 * most machines.  However, it does take more operations than the corresponding
2602
 * divide method, so it may be slower on a few RISC systems.  There are two
2603
 * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
2604
 *
2605
 * Note that the rounding factors are NOT supposed to be the same!  128 and
2606
 * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
2607
 * standard method.
2608
 *
2609
 * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
2610
 */
2611
2612
 /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
2613
2614
#  define png_composite(composite, fg, alpha, bg)        \
2615
0
   {                                                     \
2616
0
      png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
2617
0
          * (png_uint_16)(alpha)                         \
2618
0
          + (png_uint_16)(bg)*(png_uint_16)(255          \
2619
0
          - (png_uint_16)(alpha)) + 128);                \
2620
0
      (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
2621
0
   }
2622
2623
#  define png_composite_16(composite, fg, alpha, bg)     \
2624
0
   {                                                     \
2625
0
      png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
2626
0
          * (png_uint_32)(alpha)                         \
2627
0
          + (png_uint_32)(bg)*(65535                     \
2628
0
          - (png_uint_32)(alpha)) + 32768);              \
2629
0
      (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
2630
0
   }
2631
2632
#else  /* Standard method using integer division */
2633
2634
#  define png_composite(composite, fg, alpha, bg)                      \
2635
   (composite) =                                                       \
2636
       (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) +  \
2637
       (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
2638
       127) / 255))
2639
2640
#  define png_composite_16(composite, fg, alpha, bg)                       \
2641
   (composite) =                                                           \
2642
       (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
2643
       (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) +     \
2644
       32767) / 65535))
2645
#endif /* READ_COMPOSITE_NODIV */
2646
2647
#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
2648
PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));
2649
PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));
2650
PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf));
2651
#endif
2652
2653
PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr,
2654
    png_const_bytep buf));
2655
/* No png_get_int_16 -- may be added if there's a real need for it. */
2656
2657
/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
2658
#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
2659
PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));
2660
#endif
2661
#ifdef PNG_SAVE_INT_32_SUPPORTED
2662
PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
2663
#endif
2664
2665
/* Place a 16-bit number into a buffer in PNG byte order.
2666
 * The parameter is declared unsigned int, not png_uint_16,
2667
 * just to avoid potential problems on pre-ANSI C compilers.
2668
 */
2669
#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
2670
PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
2671
/* No png_save_int_16 -- may be added if there's a real need for it. */
2672
#endif
2673
2674
#ifdef PNG_USE_READ_MACROS
2675
/* Inline macros to do direct reads of bytes from the input buffer.
2676
 * The png_get_int_32() routine assumes we are using two's complement
2677
 * format for negative values, which is almost certainly true.
2678
 */
2679
#  define PNG_get_uint_32(buf) \
2680
68.5k
   (((png_uint_32)(*(buf)) << 24) + \
2681
68.5k
    ((png_uint_32)(*((buf) + 1)) << 16) + \
2682
68.5k
    ((png_uint_32)(*((buf) + 2)) << 8) + \
2683
68.5k
    ((png_uint_32)(*((buf) + 3))))
2684
2685
   /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
2686
    * function) incorrectly returned a value of type png_uint_32.
2687
    */
2688
#  define PNG_get_uint_16(buf) \
2689
18.7k
   ((png_uint_16) \
2690
18.7k
    (((unsigned int)(*(buf)) << 8) + \
2691
18.7k
    ((unsigned int)(*((buf) + 1)))))
2692
2693
#  define PNG_get_int_32(buf) \
2694
3.30k
   ((png_int_32)((*(buf) & 0x80) \
2695
3.30k
    ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
2696
3.30k
    : (png_int_32)png_get_uint_32(buf)))
2697
2698
/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
2699
 * but defining a macro name prefixed with PNG_PREFIX.
2700
 */
2701
#  ifndef PNG_PREFIX
2702
#    define png_get_uint_32(buf) PNG_get_uint_32(buf)
2703
#    define png_get_uint_16(buf) PNG_get_uint_16(buf)
2704
#    define png_get_int_32(buf)  PNG_get_int_32(buf)
2705
#  endif
2706
#else
2707
#  ifdef PNG_PREFIX
2708
   /* No macros; revert to the (redefined) function */
2709
#    define PNG_get_uint_32 (png_get_uint_32)
2710
#    define PNG_get_uint_16 (png_get_uint_16)
2711
#    define PNG_get_int_32  (png_get_int_32)
2712
#  endif
2713
#endif
2714
2715
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
2716
PNG_EXPORT(242, void, png_set_check_for_invalid_index,
2717
    (png_structrp png_ptr, int allowed));
2718
#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
2719
PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,
2720
    png_const_infop info_ptr));
2721
#  endif
2722
#endif /* CHECK_FOR_INVALID_INDEX */
2723
2724
/*******************************************************************************
2725
 * Section 5: SIMPLIFIED API
2726
 *******************************************************************************
2727
 *
2728
 * Please read the documentation in libpng-manual.txt (TODO: write said
2729
 * documentation) if you don't understand what follows.
2730
 *
2731
 * The simplified API hides the details of both libpng and the PNG file format
2732
 * itself.  It allows PNG files to be read into a very limited number of
2733
 * in-memory bitmap formats or to be written from the same formats.  If these
2734
 * formats do not accommodate your needs then you can, and should, use the more
2735
 * sophisticated APIs above - these support a wide variety of in-memory formats
2736
 * and a wide variety of sophisticated transformations to those formats as well
2737
 * as a wide variety of APIs to manipulate ancillary information.
2738
 *
2739
 * To read a PNG file using the simplified API:
2740
 *
2741
 * 1) Declare a 'png_image' structure (see below) on the stack, set the
2742
 *    version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL
2743
 *    (this is REQUIRED, your program may crash if you don't do it.)
2744
 * 2) Call the appropriate png_image_begin_read... function.
2745
 * 3) Set the png_image 'format' member to the required sample format.
2746
 * 4) Allocate a buffer for the image and, if required, the color-map.
2747
 * 5) Call png_image_finish_read to read the image and, if required, the
2748
 *    color-map into your buffers.
2749
 *
2750
 * There are no restrictions on the format of the PNG input itself; all valid
2751
 * color types, bit depths, and interlace methods are acceptable, and the
2752
 * input image is transformed as necessary to the requested in-memory format
2753
 * during the png_image_finish_read() step.  The only caveat is that if you
2754
 * request a color-mapped image from a PNG that is full-color or makes
2755
 * complex use of an alpha channel the transformation is extremely lossy and the
2756
 * result may look terrible.
2757
 *
2758
 * To write a PNG file using the simplified API:
2759
 *
2760
 * 1) Declare a 'png_image' structure on the stack and memset() it to all zero.
2761
 * 2) Initialize the members of the structure that describe the image, setting
2762
 *    the 'format' member to the format of the image samples.
2763
 * 3) Call the appropriate png_image_write... function with a pointer to the
2764
 *    image and, if necessary, the color-map to write the PNG data.
2765
 *
2766
 * png_image is a structure that describes the in-memory format of an image
2767
 * when it is being read or defines the in-memory format of an image that you
2768
 * need to write:
2769
 */
2770
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \
2771
    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
2772
2773
1.69k
#define PNG_IMAGE_VERSION 1
2774
2775
typedef struct png_control *png_controlp;
2776
typedef struct
2777
{
2778
   png_controlp opaque;    /* Initialize to NULL, free with png_image_free */
2779
   png_uint_32  version;   /* Set to PNG_IMAGE_VERSION */
2780
   png_uint_32  width;     /* Image width in pixels (columns) */
2781
   png_uint_32  height;    /* Image height in pixels (rows) */
2782
   png_uint_32  format;    /* Image format as defined below */
2783
   png_uint_32  flags;     /* A bit mask containing informational flags */
2784
   png_uint_32  colormap_entries;
2785
                           /* Number of entries in the color-map */
2786
2787
   /* In the event of an error or warning the following field will be set to a
2788
    * non-zero value and the 'message' field will contain a '\0' terminated
2789
    * string with the libpng error or warning message.  If both warnings and
2790
    * an error were encountered, only the error is recorded.  If there
2791
    * are multiple warnings, only the first one is recorded.
2792
    *
2793
    * The upper 30 bits of this value are reserved, the low two bits contain
2794
    * a value as follows:
2795
    */
2796
228
#  define PNG_IMAGE_WARNING 1
2797
111
#  define PNG_IMAGE_ERROR 2
2798
   /*
2799
    * The result is a two-bit code such that a value more than 1 indicates
2800
    * a failure in the API just called:
2801
    *
2802
    *    0 - no warning or error
2803
    *    1 - warning
2804
    *    2 - error
2805
    *    3 - error preceded by warning
2806
    */
2807
#  define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1)
2808
2809
   png_uint_32  warning_or_error;
2810
2811
   char         message[64];
2812
} png_image, *png_imagep;
2813
2814
/* The samples of the image have one to four channels whose components have
2815
 * original values in the range 0 to 1.0:
2816
 *
2817
 * 1: A single gray or luminance channel (G).
2818
 * 2: A gray/luminance channel and an alpha channel (GA).
2819
 * 3: Three red, green, blue color channels (RGB).
2820
 * 4: Three color channels and an alpha channel (RGBA).
2821
 *
2822
 * The components are encoded in one of two ways:
2823
 *
2824
 * a) As a small integer, value 0..255, contained in a single byte.  For the
2825
 * alpha channel the original value is simply value/255.  For the color or
2826
 * luminance channels the value is encoded according to the sRGB specification
2827
 * and matches the 8-bit format expected by typical display devices.
2828
 *
2829
 * The color/gray channels are not scaled (pre-multiplied) by the alpha
2830
 * channel and are suitable for passing to color management software.
2831
 *
2832
 * b) As a value in the range 0..65535, contained in a 2-byte integer.  All
2833
 * channels can be converted to the original value by dividing by 65535; all
2834
 * channels are linear.  Color channels use the RGB encoding (RGB end-points) of
2835
 * the sRGB specification.  This encoding is identified by the
2836
 * PNG_FORMAT_FLAG_LINEAR flag below.
2837
 *
2838
 * When the simplified API needs to convert between sRGB and linear colorspaces,
2839
 * the actual sRGB transfer curve defined in the sRGB specification (see the
2840
 * article at <https://en.wikipedia.org/wiki/SRGB>) is used, not the gamma=1/2.2
2841
 * approximation used elsewhere in libpng.
2842
 *
2843
 * When an alpha channel is present it is expected to denote pixel coverage
2844
 * of the color or luminance channels and is returned as an associated alpha
2845
 * channel: the color/gray channels are scaled (pre-multiplied) by the alpha
2846
 * value.
2847
 *
2848
 * The samples are either contained directly in the image data, between 1 and 8
2849
 * bytes per pixel according to the encoding, or are held in a color-map indexed
2850
 * by bytes in the image data.  In the case of a color-map the color-map entries
2851
 * are individual samples, encoded as above, and the image data has one byte per
2852
 * pixel to select the relevant sample from the color-map.
2853
 */
2854
2855
/* PNG_FORMAT_*
2856
 *
2857
 * #defines to be used in png_image::format.  Each #define identifies a
2858
 * particular layout of sample data and, if present, alpha values.  There are
2859
 * separate defines for each of the two component encodings.
2860
 *
2861
 * A format is built up using single bit flag values.  All combinations are
2862
 * valid.  Formats can be built up from the flag values or you can use one of
2863
 * the predefined values below.  When testing formats always use the FORMAT_FLAG
2864
 * macros to test for individual features - future versions of the library may
2865
 * add new flags.
2866
 *
2867
 * When reading or writing color-mapped images the format should be set to the
2868
 * format of the entries in the color-map then png_image_{read,write}_colormap
2869
 * called to read or write the color-map and set the format correctly for the
2870
 * image data.  Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!
2871
 *
2872
 * NOTE: libpng can be built with particular features disabled. If you see
2873
 * compiler errors because the definition of one of the following flags has been
2874
 * compiled out it is because libpng does not have the required support.  It is
2875
 * possible, however, for the libpng configuration to enable the format on just
2876
 * read or just write; in that case you may see an error at run time.  You can
2877
 * guard against this by checking for the definition of the appropriate
2878
 * "_SUPPORTED" macro, one of:
2879
 *
2880
 *    PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED
2881
 */
2882
2.51k
#define PNG_FORMAT_FLAG_ALPHA    0x01U /* format with an alpha channel */
2883
2.93k
#define PNG_FORMAT_FLAG_COLOR    0x02U /* color format: otherwise grayscale */
2884
2.23k
#define PNG_FORMAT_FLAG_LINEAR   0x04U /* 2-byte channels else 1-byte */
2885
2.71k
#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */
2886
2887
#ifdef PNG_FORMAT_BGR_SUPPORTED
2888
419
#  define PNG_FORMAT_FLAG_BGR    0x10U /* BGR colors, else order is RGB */
2889
#endif
2890
2891
#ifdef PNG_FORMAT_AFIRST_SUPPORTED
2892
598
#  define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
2893
#endif
2894
2895
838
#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
2896
2897
/* Commonly used formats have predefined macros.
2898
 *
2899
 * First the single byte (sRGB) formats:
2900
 */
2901
#define PNG_FORMAT_GRAY 0
2902
#define PNG_FORMAT_GA   PNG_FORMAT_FLAG_ALPHA
2903
#define PNG_FORMAT_AG   (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST)
2904
419
#define PNG_FORMAT_RGB  PNG_FORMAT_FLAG_COLOR
2905
#define PNG_FORMAT_BGR  (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR)
2906
419
#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA)
2907
#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST)
2908
#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA)
2909
#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)
2910
2911
/* Then the linear 2-byte formats.  When naming these "Y" is used to
2912
 * indicate a luminance (gray) channel.
2913
 */
2914
#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
2915
#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)
2916
#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR)
2917
#define PNG_FORMAT_LINEAR_RGB_ALPHA \
2918
   (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA)
2919
2920
/* With color-mapped formats the image data is one byte for each pixel, the byte
2921
 * is an index into the color-map which is formatted as above.  To obtain a
2922
 * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP
2923
 * to one of the above definitions, or you can use one of the definitions below.
2924
 */
2925
#define PNG_FORMAT_RGB_COLORMAP  (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP)
2926
#define PNG_FORMAT_BGR_COLORMAP  (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP)
2927
#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP)
2928
#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP)
2929
#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP)
2930
#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP)
2931
2932
/* PNG_IMAGE macros
2933
 *
2934
 * These are convenience macros to derive information from a png_image
2935
 * structure.  The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
2936
 * actual image sample values - either the entries in the color-map or the
2937
 * pixels in the image.  The PNG_IMAGE_PIXEL_ macros return corresponding values
2938
 * for the pixels and will always return 1 for color-mapped formats.  The
2939
 * remaining macros return information about the rows in the image and the
2940
 * complete image.
2941
 *
2942
 * NOTE: All the macros that take a png_image::format parameter are compile time
2943
 * constants if the format parameter is, itself, a constant.  Therefore these
2944
 * macros can be used in array declarations and case labels where required.
2945
 * Similarly the macros are also pre-processor constants (sizeof is not used) so
2946
 * they can be used in #if tests.
2947
 *
2948
 * First the information about the samples.
2949
 */
2950
#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\
2951
419
   (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1)
2952
   /* Return the total number of channels in a given format: 1..4 */
2953
2954
#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\
2955
838
   ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1)
2956
   /* Return the size in bytes of a single component of a pixel or color-map
2957
    * entry (as appropriate) in the image: 1 or 2.
2958
    */
2959
2960
#define PNG_IMAGE_SAMPLE_SIZE(fmt)\
2961
0
   (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt))
2962
   /* This is the size of the sample data for one sample.  If the image is
2963
    * color-mapped it is the size of one color-map entry (and image pixels are
2964
    * one byte in size), otherwise it is the size of one image pixel.
2965
    */
2966
2967
#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\
2968
   (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)
2969
   /* The maximum size of the color-map required by the format expressed in a
2970
    * count of components.  This can be used to compile-time allocate a
2971
    * color-map:
2972
    *
2973
    * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];
2974
    *
2975
    * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];
2976
    *
2977
    * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the
2978
    * information from one of the png_image_begin_read_ APIs and dynamically
2979
    * allocate the required memory.
2980
    */
2981
2982
/* Corresponding information about the pixels */
2983
#define PNG_IMAGE_PIXEL_(test,fmt)\
2984
1.25k
   (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt))
2985
2986
#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\
2987
419
   PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt)
2988
   /* The number of separate channels (components) in a pixel; 1 for a
2989
    * color-mapped image.
2990
    */
2991
2992
#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\
2993
838
   PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt)
2994
   /* The size, in bytes, of each component in a pixel; 1 for a color-mapped
2995
    * image.
2996
    */
2997
2998
#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt)
2999
   /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */
3000
3001
/* Information about the whole row, or whole image */
3002
#define PNG_IMAGE_ROW_STRIDE(image)\
3003
   (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width)
3004
   /* Return the total number of components in a single row of the image; this
3005
    * is the minimum 'row stride', the minimum count of components between each
3006
    * row.  For a color-mapped image this is the minimum number of bytes in a
3007
    * row.
3008
    *
3009
    * WARNING: this macro overflows for some images with more than one component
3010
    * and very large image widths.  libpng will refuse to process an image where
3011
    * this macro would overflow.
3012
    */
3013
3014
#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
3015
838
   (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
3016
   /* Return the size, in bytes, of an image buffer given a png_image and a row
3017
    * stride - the number of components to leave space for in each row.
3018
    *
3019
    * WARNING: this macro overflows a 32-bit integer for some large PNG images,
3020
    * libpng will refuse to process an image where such an overflow would occur.
3021
    */
3022
3023
#define PNG_IMAGE_SIZE(image)\
3024
419
   PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image))
3025
   /* Return the size, in bytes, of the image in memory given just a png_image;
3026
    * the row stride is the minimum stride required for the image.
3027
    */
3028
3029
#define PNG_IMAGE_COLORMAP_SIZE(image)\
3030
   (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries)
3031
   /* Return the size, in bytes, of the color-map of this image.  If the image
3032
    * format is not a color-map format this will return a size sufficient for
3033
    * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if
3034
    * you don't want to allocate a color-map in this case.
3035
    */
3036
3037
/* PNG_IMAGE_FLAG_*
3038
 *
3039
 * Flags containing additional information about the image are held in the
3040
 * 'flags' field of png_image.
3041
 */
3042
40
#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01
3043
   /* This indicates that the RGB values of the in-memory bitmap do not
3044
    * correspond to the red, green and blue end-points defined by sRGB.
3045
    */
3046
3047
#define PNG_IMAGE_FLAG_FAST 0x02
3048
   /* On write emphasise speed over compression; the resultant PNG file will be
3049
    * larger but will be produced significantly faster, particular for large
3050
    * images.  Do not use this option for images which will be distributed, only
3051
    * used it when producing intermediate files that will be read back in
3052
    * repeatedly.  For a typical 24-bit image the option will double the read
3053
    * speed at the cost of increasing the image size by 25%, however for many
3054
    * more compressible images the PNG file can be 10 times larger with only a
3055
    * slight speed gain.
3056
    */
3057
3058
45
#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04
3059
   /* On read if the image is a 16-bit per component image and there is no gAMA
3060
    * or sRGB chunk assume that the components are sRGB encoded.  Notice that
3061
    * images output by the simplified API always have gamma information; setting
3062
    * this flag only affects the interpretation of 16-bit images from an
3063
    * external source.  It is recommended that the application expose this flag
3064
    * to the user; the user can normally easily recognize the difference between
3065
    * linear and sRGB encoding.  This flag has no effect on write - the data
3066
    * passed to the write APIs must have the correct encoding (as defined
3067
    * above.)
3068
    *
3069
    * If the flag is not set (the default) input 16-bit per component data is
3070
    * assumed to be linear.
3071
    *
3072
    * NOTE: the flag can only be set after the png_image_begin_read_ call,
3073
    * because that call initializes the 'flags' field.
3074
    */
3075
3076
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
3077
/* READ APIs
3078
 * ---------
3079
 *
3080
 * The png_image passed to the read APIs must have been initialized by setting
3081
 * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.)
3082
 */
3083
#ifdef PNG_STDIO_SUPPORTED
3084
PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image,
3085
   const char *file_name));
3086
   /* The named file is opened for read and the image header is filled in
3087
    * from the PNG header in the file.
3088
    */
3089
3090
PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,
3091
   FILE *file));
3092
   /* The PNG header is read from the stdio FILE object. */
3093
#endif /* STDIO */
3094
3095
PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
3096
   png_const_voidp memory, size_t size));
3097
   /* The PNG header is read from the given memory buffer. */
3098
3099
PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
3100
   png_const_colorp background, void *buffer, png_int_32 row_stride,
3101
   void *colormap));
3102
   /* Finish reading the image into the supplied buffer and clean up the
3103
    * png_image structure.
3104
    *
3105
    * row_stride is the step, in byte or 2-byte units as appropriate,
3106
    * between adjacent rows.  A positive stride indicates that the top-most row
3107
    * is first in the buffer - the normal top-down arrangement.  A negative
3108
    * stride indicates that the bottom-most row is first in the buffer.
3109
    *
3110
    * background need only be supplied if an alpha channel must be removed from
3111
    * a png_byte format and the removal is to be done by compositing on a solid
3112
    * color; otherwise it may be NULL and any composition will be done directly
3113
    * onto the buffer.  The value is an sRGB color to use for the background,
3114
    * for grayscale output the green channel is used.
3115
    *
3116
    * background must be supplied when an alpha channel must be removed from a
3117
    * single byte color-mapped output format, in other words if:
3118
    *
3119
    * 1) The original format from png_image_begin_read_from_* had
3120
    *    PNG_FORMAT_FLAG_ALPHA set.
3121
    * 2) The format set by the application does not.
3122
    * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and
3123
    *    PNG_FORMAT_FLAG_LINEAR *not* set.
3124
    *
3125
    * For linear output removing the alpha channel is always done by compositing
3126
    * on black and background is ignored.
3127
    *
3128
    * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set.  It must
3129
    * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE.
3130
    * image->colormap_entries will be updated to the actual number of entries
3131
    * written to the colormap; this may be less than the original value.
3132
    */
3133
3134
PNG_EXPORT(238, void, png_image_free, (png_imagep image));
3135
   /* Free any data allocated by libpng in image->opaque, setting the pointer to
3136
    * NULL.  May be called at any time after the structure is initialized.
3137
    */
3138
#endif /* SIMPLIFIED_READ */
3139
3140
#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
3141
/* WRITE APIS
3142
 * ----------
3143
 * For write you must initialize a png_image structure to describe the image to
3144
 * be written.  To do this use memset to set the whole structure to 0 then
3145
 * initialize fields describing your image.
3146
 *
3147
 * version: must be set to PNG_IMAGE_VERSION
3148
 * opaque: must be initialized to NULL
3149
 * width: image width in pixels
3150
 * height: image height in rows
3151
 * format: the format of the data (image and color-map) you wish to write
3152
 * flags: set to 0 unless one of the defined flags applies; set
3153
 *    PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB
3154
 *    values do not correspond to the colors in sRGB.
3155
 * colormap_entries: set to the number of entries in the color-map (0 to 256)
3156
 */
3157
#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
3158
PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
3159
   const char *file, int convert_to_8bit, const void *buffer,
3160
   png_int_32 row_stride, const void *colormap));
3161
   /* Write the image to the named file. */
3162
3163
PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
3164
   int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
3165
   const void *colormap));
3166
   /* Write the image to the given FILE object. */
3167
#endif /* SIMPLIFIED_WRITE_STDIO */
3168
3169
/* With all write APIs if image is in one of the linear formats with 16-bit
3170
 * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
3171
 * gamma encoded according to the sRGB specification, otherwise a 16-bit linear
3172
 * encoded PNG file is written.
3173
 *
3174
 * With color-mapped data formats the colormap parameter point to a color-map
3175
 * with at least image->colormap_entries encoded in the specified format.  If
3176
 * the format is linear the written PNG color-map will be converted to sRGB
3177
 * regardless of the convert_to_8_bit flag.
3178
 *
3179
 * With all APIs row_stride is handled as in the read APIs - it is the spacing
3180
 * from one row to the next in component sized units (1 or 2 bytes) and if
3181
 * negative indicates a bottom-up row layout in the buffer.  If row_stride is
3182
 * zero, libpng will calculate it for you from the image width and number of
3183
 * channels.
3184
 *
3185
 * Note that the write API does not support interlacing, sub-8-bit pixels or
3186
 * most ancillary chunks.  If you need to write text chunks (e.g. for copyright
3187
 * notices) you need to use one of the other APIs.
3188
 */
3189
3190
PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
3191
   png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit,
3192
   const void *buffer, png_int_32 row_stride, const void *colormap));
3193
   /* Write the image to the given memory buffer.  The function both writes the
3194
    * whole PNG data stream to *memory and updates *memory_bytes with the count
3195
    * of bytes written.
3196
    *
3197
    * 'memory' may be NULL.  In this case *memory_bytes is not read however on
3198
    * success the number of bytes which would have been written will still be
3199
    * stored in *memory_bytes.  On failure *memory_bytes will contain 0.
3200
    *
3201
    * If 'memory' is not NULL it must point to memory[*memory_bytes] of
3202
    * writeable memory.
3203
    *
3204
    * If the function returns success memory[*memory_bytes] (if 'memory' is not
3205
    * NULL) contains the written PNG data.  *memory_bytes will always be less
3206
    * than or equal to the original value.
3207
    *
3208
    * If the function returns false and *memory_bytes was not changed an error
3209
    * occurred during write.  If *memory_bytes was changed, or is not 0 if
3210
    * 'memory' was NULL, the write would have succeeded but for the memory
3211
    * buffer being too small.  *memory_bytes contains the required number of
3212
    * bytes and will be bigger that the original value.
3213
    */
3214
3215
#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\
3216
   row_stride, colormap)\
3217
   png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\
3218
         row_stride, colormap)
3219
   /* Return the amount of memory in 'size' required to compress this image.
3220
    * The png_image structure 'image' must be filled in as in the above
3221
    * function and must not be changed before the actual write call, the buffer
3222
    * and all other parameters must also be identical to that in the final
3223
    * write call.  The 'size' variable need not be initialized.
3224
    *
3225
    * NOTE: the macro returns true/false, if false is returned 'size' will be
3226
    * set to zero and the write failed and probably will fail if tried again.
3227
    */
3228
3229
/* You can pre-allocate the buffer by making sure it is of sufficient size
3230
 * regardless of the amount of compression achieved.  The buffer size will
3231
 * always be bigger than the original image and it will never be filled.  The
3232
 * following macros are provided to assist in allocating the buffer.
3233
 */
3234
#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height)
3235
   /* The number of uncompressed bytes in the PNG byte encoding of the image;
3236
    * uncompressing the PNG IDAT data will give this number of bytes.
3237
    *
3238
    * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this
3239
    * macro can because of the extra bytes used in the PNG byte encoding.  You
3240
    * need to avoid this macro if your image size approaches 2^30 in width or
3241
    * height.  The same goes for the remainder of these macros; they all produce
3242
    * bigger numbers than the actual in-memory image size.
3243
    */
3244
#ifndef PNG_ZLIB_MAX_SIZE
3245
#  define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U)
3246
   /* An upper bound on the number of compressed bytes given 'b' uncompressed
3247
    * bytes.  This is based on deflateBounds() in zlib; different
3248
    * implementations of zlib compression may conceivably produce more data so
3249
    * if your zlib implementation is not zlib itself redefine this macro
3250
    * appropriately.
3251
    */
3252
#endif
3253
3254
#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\
3255
   PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image))
3256
   /* An upper bound on the size of the data in the PNG IDAT chunks. */
3257
3258
#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
3259
   ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
3260
    (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
3261
    12U+3U*(image).colormap_entries/*PLTE data*/+\
3262
    (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
3263
    12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
3264
    12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
3265
   /* A helper for the following macro; if your compiler cannot handle the
3266
    * following macro use this one with the result of
3267
    * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most
3268
    * compilers should handle this just fine.)
3269
    */
3270
3271
#define PNG_IMAGE_PNG_SIZE_MAX(image)\
3272
   PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image))
3273
   /* An upper bound on the total length of the PNG data stream for 'image'.
3274
    * The result is of type png_alloc_size_t, on 32-bit systems this may
3275
    * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will
3276
    * run out of buffer space but return a corrected size which should work.
3277
    */
3278
#endif /* SIMPLIFIED_WRITE */
3279
/*******************************************************************************
3280
 *  END OF SIMPLIFIED API
3281
 ******************************************************************************/
3282
#endif /* SIMPLIFIED_{READ|WRITE} */
3283
3284
/*******************************************************************************
3285
 * Section 6: IMPLEMENTATION OPTIONS
3286
 *******************************************************************************
3287
 *
3288
 * Support for arbitrary implementation-specific optimizations.  The API allows
3289
 * particular options to be turned on or off.  'Option' is the number of the
3290
 * option and 'onoff' is 0 (off) or non-0 (on).  The value returned is given
3291
 * by the PNG_OPTION_ defines below.
3292
 *
3293
 * HARDWARE: normally hardware capabilities, such as the Intel SSE instructions,
3294
 *           are detected at run time, however sometimes it may be impossible
3295
 *           to do this in user mode, in which case it is necessary to discover
3296
 *           the capabilities in an OS specific way.  Such capabilities are
3297
 *           listed here when libpng has support for them and must be turned
3298
 *           ON by the application if present.
3299
 *
3300
 * SOFTWARE: sometimes software optimizations actually result in performance
3301
 *           decrease on some architectures or systems, or with some sets of
3302
 *           PNG images.  'Software' options allow such optimizations to be
3303
 *           selected at run time.
3304
 */
3305
#ifdef PNG_SET_OPTION_SUPPORTED
3306
#ifdef PNG_ARM_NEON_API_SUPPORTED
3307
#  define PNG_ARM_NEON   0 /* HARDWARE: ARM Neon SIMD instructions supported */
3308
#endif
3309
3.11k
#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
3310
#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
3311
#ifdef PNG_MIPS_MSA_API_SUPPORTED
3312
#  define PNG_MIPS_MSA   6 /* HARDWARE: MIPS Msa SIMD instructions supported */
3313
#endif
3314
#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
3315
#  define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */
3316
#endif
3317
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
3318
#  define PNG_POWERPC_VSX   10 /* HARDWARE: PowerPC VSX SIMD instructions
3319
                                * supported */
3320
#endif
3321
#ifdef PNG_MIPS_MMI_API_SUPPORTED
3322
#  define PNG_MIPS_MMI   12 /* HARDWARE: MIPS MMI SIMD instructions supported */
3323
#endif
3324
3325
0
#define PNG_OPTION_NEXT  14 /* Next option - numbers must be even */
3326
3327
/* Return values: NOTE: there are four values and 'off' is *not* zero */
3328
#define PNG_OPTION_UNSET   0 /* Unset - defaults to off */
3329
0
#define PNG_OPTION_INVALID 1 /* Option number out of range */
3330
#define PNG_OPTION_OFF     2
3331
3.11k
#define PNG_OPTION_ON      3
3332
3333
PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
3334
   int onoff));
3335
#endif /* SET_OPTION */
3336
3337
/*******************************************************************************
3338
 *  END OF HARDWARE AND SOFTWARE OPTIONS
3339
 ******************************************************************************/
3340
3341
/* Maintainer: Put new public prototypes here ^, in libpng.3, in project
3342
 * defs, and in scripts/symbols.def.
3343
 */
3344
3345
/* The last ordinal number (this is the *last* one already used; the next
3346
 * one to use is one more than this.)
3347
 */
3348
#ifdef PNG_EXPORT_LAST_ORDINAL
3349
  PNG_EXPORT_LAST_ORDINAL(259);
3350
#endif
3351
3352
#ifdef __cplusplus
3353
}
3354
#endif
3355
3356
#endif /* PNG_VERSION_INFO_ONLY */
3357
/* Do not put anything past this line */
3358
#endif /* PNG_H */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngdebug.h.html b/part1/report/w_corpus/src/libpng/pngdebug.h.html new file mode 100644 index 0000000..7e4247c --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngdebug.h.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngdebug.h
Line
Count
Source (jump to first uncovered line)
1
/* pngdebug.h - internal debugging macros for libpng
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 */
12
13
#ifndef PNGPRIV_H
14
#  error This file must not be included by applications; please include <png.h>
15
#endif
16
17
/* Define PNG_DEBUG at compile time for debugging information.  Higher
18
 * numbers for PNG_DEBUG mean more debugging information.  This has
19
 * only been added since version 0.95 so it is not implemented throughout
20
 * libpng yet, but more support will be added as needed.
21
 *
22
 * png_debug[1-2]?(level, message ,arg{0-2})
23
 *   Expands to a statement (either a simple expression or a compound
24
 *   do..while(0) statement) that outputs a message with parameter
25
 *   substitution if PNG_DEBUG is defined to 2 or more.  If PNG_DEBUG
26
 *   is undefined, 0 or 1 every png_debug expands to a simple expression
27
 *   (actually ((void)0)).
28
 *
29
 *   level: level of detail of message, starting at 0.  A level 'n'
30
 *          message is preceded by 'n' 3-space indentations (not implemented
31
 *          on Microsoft compilers unless PNG_DEBUG_FILE is also
32
 *          defined, to allow debug DLL compilation with no standard IO).
33
 *   message: a printf(3) style text string.  A trailing '\n' is added
34
 *            to the message.
35
 *   arg: 0 to 2 arguments for printf(3) style substitution in message.
36
 */
37
#ifndef PNGDEBUG_H
38
#define PNGDEBUG_H
39
/* These settings control the formatting of messages in png.c and pngerror.c */
40
/* Moved to pngdebug.h at 1.5.0 */
41
#  ifndef PNG_LITERAL_SHARP
42
23.5k
#    define PNG_LITERAL_SHARP 0x23
43
#  endif
44
#  ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
45
428
#    define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
46
#  endif
47
#  ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
48
428
#    define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
49
#  endif
50
#  ifndef PNG_STRING_NEWLINE
51
0
#    define PNG_STRING_NEWLINE "\n"
52
#  endif
53
54
#ifdef PNG_DEBUG
55
#  if (PNG_DEBUG > 0)
56
#    if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
57
#      include <crtdbg.h>
58
#      if (PNG_DEBUG > 1)
59
#        ifndef _DEBUG
60
#          define _DEBUG
61
#        endif
62
#        ifndef png_debug
63
#          define png_debug(l,m)  _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
64
#        endif
65
#        ifndef png_debug1
66
#          define png_debug1(l,m,p1)  _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
67
#        endif
68
#        ifndef png_debug2
69
#          define png_debug2(l,m,p1,p2) \
70
             _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
71
#        endif
72
#      endif
73
#    else /* PNG_DEBUG_FILE || !_MSC_VER */
74
#      ifndef PNG_STDIO_SUPPORTED
75
#        include <stdio.h> /* not included yet */
76
#      endif
77
#      ifndef PNG_DEBUG_FILE
78
#        define PNG_DEBUG_FILE stderr
79
#      endif /* PNG_DEBUG_FILE */
80
81
#      if (PNG_DEBUG > 1)
82
#        ifdef __STDC__
83
#          ifndef png_debug
84
#            define png_debug(l,m) \
85
       do { \
86
       int num_tabs=l; \
87
       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
88
         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : "")))); \
89
       } while (0)
90
#          endif
91
#          ifndef png_debug1
92
#            define png_debug1(l,m,p1) \
93
       do { \
94
       int num_tabs=l; \
95
       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
96
         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : ""))),p1); \
97
       } while (0)
98
#          endif
99
#          ifndef png_debug2
100
#            define png_debug2(l,m,p1,p2) \
101
       do { \
102
       int num_tabs=l; \
103
       fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? "   " : \
104
         (num_tabs==2 ? "      " : (num_tabs>2 ? "         " : ""))),p1,p2);\
105
       } while (0)
106
#          endif
107
#        else /* __STDC __ */
108
#          ifndef png_debug
109
#            define png_debug(l,m) \
110
       do { \
111
       int num_tabs=l; \
112
       char format[256]; \
113
       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
114
         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
115
         m,PNG_STRING_NEWLINE); \
116
       fprintf(PNG_DEBUG_FILE,format); \
117
       } while (0)
118
#          endif
119
#          ifndef png_debug1
120
#            define png_debug1(l,m,p1) \
121
       do { \
122
       int num_tabs=l; \
123
       char format[256]; \
124
       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
125
         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
126
         m,PNG_STRING_NEWLINE); \
127
       fprintf(PNG_DEBUG_FILE,format,p1); \
128
       } while (0)
129
#          endif
130
#          ifndef png_debug2
131
#            define png_debug2(l,m,p1,p2) \
132
       do { \
133
       int num_tabs=l; \
134
       char format[256]; \
135
       snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
136
         (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
137
         m,PNG_STRING_NEWLINE); \
138
       fprintf(PNG_DEBUG_FILE,format,p1,p2); \
139
       } while (0)
140
#          endif
141
#        endif /* __STDC __ */
142
#      endif /* (PNG_DEBUG > 1) */
143
144
#    endif /* _MSC_VER */
145
#  endif /* (PNG_DEBUG > 0) */
146
#endif /* PNG_DEBUG */
147
#ifndef png_debug
148
1.19M
#  define png_debug(l, m) ((void)0)
149
#endif
150
#ifndef png_debug1
151
152k
#  define png_debug1(l, m, p1) ((void)0)
152
#endif
153
#ifndef png_debug2
154
538k
#  define png_debug2(l, m, p1, p2) ((void)0)
155
#endif
156
#endif /* PNGDEBUG_H */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngerror.c.html b/part1/report/w_corpus/src/libpng/pngerror.c.html new file mode 100644 index 0000000..797ab5e --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngerror.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngerror.c
Line
Count
Source (jump to first uncovered line)
1
/* pngerror.c - stub functions for i/o and memory allocation
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 * This file provides a location for all error handling.  Users who
13
 * need special error handling are expected to write replacement functions
14
 * and use png_set_error_fn() to use those functions.  See the instructions
15
 * at each function.
16
 */
17
18
#include "pngpriv.h"
19
20
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
21
22
static PNG_FUNCTION(void /* PRIVATE */,
23
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
24
    PNG_NORETURN);
25
26
#ifdef PNG_WARNINGS_SUPPORTED
27
static void /* PRIVATE */
28
png_default_warning(png_const_structrp png_ptr,
29
    png_const_charp warning_message);
30
#endif /* WARNINGS */
31
32
/* This function is called whenever there is a fatal error.  This function
33
 * should not be changed.  If there is a need to handle errors differently,
34
 * you should supply a replacement error function and use png_set_error_fn()
35
 * to replace the error function at run-time.
36
 */
37
#ifdef PNG_ERROR_TEXT_SUPPORTED
38
PNG_FUNCTION(void,PNGAPI
39
png_error,(png_const_structrp png_ptr, png_const_charp error_message),
40
    PNG_NORETURN)
41
1.48k
{
42
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
43
   char msg[16];
44
   if (png_ptr != NULL)
45
   {
46
      if ((png_ptr->flags &
47
         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
48
      {
49
         if (*error_message == PNG_LITERAL_SHARP)
50
         {
51
            /* Strip "#nnnn " from beginning of error message. */
52
            int offset;
53
            for (offset = 1; offset<15; offset++)
54
               if (error_message[offset] == ' ')
55
                  break;
56
57
            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
58
            {
59
               int i;
60
               for (i = 0; i < offset - 1; i++)
61
                  msg[i] = error_message[i + 1];
62
               msg[i - 1] = '\0';
63
               error_message = msg;
64
            }
65
66
            else
67
               error_message += offset;
68
         }
69
70
         else
71
         {
72
            if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
73
            {
74
               msg[0] = '0';
75
               msg[1] = '\0';
76
               error_message = msg;
77
            }
78
         }
79
      }
80
   }
81
#endif
82
1.48k
   if (png_ptr != NULL && png_ptr->error_fn != NULL)
83
111
      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
84
111
          error_message);
85
86
   /* If the custom handler doesn't exist, or if it returns,
87
      use the default handler, which will not return. */
88
1.48k
   png_default_error(png_ptr, error_message);
89
1.48k
}
90
#else
91
PNG_FUNCTION(void,PNGAPI
92
png_err,(png_const_structrp png_ptr),PNG_NORETURN)
93
{
94
   /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
95
    * erroneously as '\0', instead of the empty string "".  This was
96
    * apparently an error, introduced in libpng-1.2.20, and png_default_error
97
    * will crash in this case.
98
    */
99
   if (png_ptr != NULL && png_ptr->error_fn != NULL)
100
      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
101
102
   /* If the custom handler doesn't exist, or if it returns,
103
      use the default handler, which will not return. */
104
   png_default_error(png_ptr, "");
105
}
106
#endif /* ERROR_TEXT */
107
108
/* Utility to safely appends strings to a buffer.  This never errors out so
109
 * error checking is not required in the caller.
110
 */
111
size_t
112
png_safecat(png_charp buffer, size_t bufsize, size_t pos,
113
    png_const_charp string)
114
597
{
115
597
   if (buffer != NULL && pos < bufsize)
116
597
   {
117
597
      if (string != NULL)
118
7.94k
         while (*string != '\0' && pos < bufsize-1)
119
7.34k
           buffer[pos++] = *string++;
120
121
597
      buffer[pos] = '\0';
122
597
   }
123
124
597
   return pos;
125
597
}
126
127
#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
128
/* Utility to dump an unsigned value into a buffer, given a start pointer and
129
 * and end pointer (which should point just *beyond* the end of the buffer!)
130
 * Returns the pointer to the start of the formatted string.
131
 */
132
png_charp
133
png_format_number(png_const_charp start, png_charp end, int format,
134
    png_alloc_size_t number)
135
35
{
136
35
   int count = 0;    /* number of digits output */
137
35
   int mincount = 1; /* minimum number required */
138
35
   int output = 0;   /* digit output (for the fixed point format) */
139
140
35
   *--end = '\0';
141
142
   /* This is written so that the loop always runs at least once, even with
143
    * number zero.
144
    */
145
305
   while (end > start && (number != 0 || count < mincount))
146
270
   {
147
148
270
      static const char digits[] = "0123456789ABCDEF";
149
150
270
      switch (format)
151
270
      {
152
0
         case PNG_NUMBER_FORMAT_fixed:
153
            /* Needs five digits (the fraction) */
154
0
            mincount = 5;
155
0
            if (output != 0 || number % 10 != 0)
156
0
            {
157
0
               *--end = digits[number % 10];
158
0
               output = 1;
159
0
            }
160
0
            number /= 10;
161
0
            break;
162
163
0
         case PNG_NUMBER_FORMAT_02u:
164
            /* Expects at least 2 digits. */
165
0
            mincount = 2;
166
            /* FALLTHROUGH */
167
168
0
         case PNG_NUMBER_FORMAT_u:
169
0
            *--end = digits[number % 10];
170
0
            number /= 10;
171
0
            break;
172
173
0
         case PNG_NUMBER_FORMAT_02x:
174
            /* This format expects at least two digits */
175
0
            mincount = 2;
176
            /* FALLTHROUGH */
177
178
270
         case PNG_NUMBER_FORMAT_x:
179
270
            *--end = digits[number & 0xf];
180
270
            number >>= 4;
181
270
            break;
182
183
0
         default: /* an error */
184
0
            number = 0;
185
0
            break;
186
270
      }
187
188
      /* Keep track of the number of digits added */
189
270
      ++count;
190
191
      /* Float a fixed number here: */
192
270
      if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))
193
0
      {
194
         /* End of the fraction, but maybe nothing was output?  In that case
195
          * drop the decimal point.  If the number is a true zero handle that
196
          * here.
197
          */
198
0
         if (output != 0)
199
0
            *--end = '.';
200
0
         else if (number == 0) /* and !output */
201
0
            *--end = '0';
202
0
      }
203
270
   }
204
205
35
   return end;
206
35
}
207
#endif
208
209
#ifdef PNG_WARNINGS_SUPPORTED
210
/* This function is called whenever there is a non-fatal error.  This function
211
 * should not be changed.  If there is a need to handle warnings differently,
212
 * you should supply a replacement warning function and use
213
 * png_set_error_fn() to replace the warning function at run-time.
214
 */
215
void PNGAPI
216
png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
217
23.5k
{
218
23.5k
   int offset = 0;
219
23.5k
   if (png_ptr != NULL)
220
23.5k
   {
221
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
222
   if ((png_ptr->flags &
223
       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
224
#endif
225
23.5k
      {
226
23.5k
         if (*warning_message == PNG_LITERAL_SHARP)
227
0
         {
228
0
            for (offset = 1; offset < 15; offset++)
229
0
               if (warning_message[offset] == ' ')
230
0
                  break;
231
0
         }
232
23.5k
      }
233
23.5k
   }
234
23.5k
   if (png_ptr != NULL && png_ptr->warning_fn != NULL)
235
5.67k
      (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
236
5.67k
          warning_message + offset);
237
17.8k
   else
238
17.8k
      png_default_warning(png_ptr, warning_message + offset);
239
23.5k
}
240
241
/* These functions support 'formatted' warning messages with up to
242
 * PNG_WARNING_PARAMETER_COUNT parameters.  In the format string the parameter
243
 * is introduced by @<number>, where 'number' starts at 1.  This follows the
244
 * standard established by X/Open for internationalizable error messages.
245
 */
246
void
247
png_warning_parameter(png_warning_parameters p, int number,
248
    png_const_charp string)
249
0
{
250
0
   if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
251
0
      (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
252
0
}
253
254
void
255
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
256
    png_alloc_size_t value)
257
0
{
258
0
   char buffer[PNG_NUMBER_BUFFER_SIZE] = {0};
259
0
   png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
260
0
}
261
262
void
263
png_warning_parameter_signed(png_warning_parameters p, int number, int format,
264
    png_int_32 value)
265
0
{
266
0
   png_alloc_size_t u;
267
0
   png_charp str;
268
0
   char buffer[PNG_NUMBER_BUFFER_SIZE] = {0};
269
270
   /* Avoid overflow by doing the negate in a png_alloc_size_t: */
271
0
   u = (png_alloc_size_t)value;
272
0
   if (value < 0)
273
0
      u = ~u + 1;
274
275
0
   str = PNG_FORMAT_NUMBER(buffer, format, u);
276
277
0
   if (value < 0 && str > buffer)
278
0
      *--str = '-';
279
280
0
   png_warning_parameter(p, number, str);
281
0
}
282
283
void
284
png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
285
    png_const_charp message)
286
0
{
287
   /* The internal buffer is just 192 bytes - enough for all our messages,
288
    * overflow doesn't happen because this code checks!  If someone figures
289
    * out how to send us a message longer than 192 bytes, all that will
290
    * happen is that the message will be truncated appropriately.
291
    */
292
0
   size_t i = 0; /* Index in the msg[] buffer: */
293
0
   char msg[192];
294
295
   /* Each iteration through the following loop writes at most one character
296
    * to msg[i++] then returns here to validate that there is still space for
297
    * the trailing '\0'.  It may (in the case of a parameter) read more than
298
    * one character from message[]; it must check for '\0' and continue to the
299
    * test if it finds the end of string.
300
    */
301
0
   while (i<(sizeof msg)-1 && *message != '\0')
302
0
   {
303
      /* '@' at end of string is now just printed (previously it was skipped);
304
       * it is an error in the calling code to terminate the string with @.
305
       */
306
0
      if (p != NULL && *message == '@' && message[1] != '\0')
307
0
      {
308
0
         int parameter_char = *++message; /* Consume the '@' */
309
0
         static const char valid_parameters[] = "123456789";
310
0
         int parameter = 0;
311
312
         /* Search for the parameter digit, the index in the string is the
313
          * parameter to use.
314
          */
315
0
         while (valid_parameters[parameter] != parameter_char &&
316
0
            valid_parameters[parameter] != '\0')
317
0
            ++parameter;
318
319
         /* If the parameter digit is out of range it will just get printed. */
320
0
         if (parameter < PNG_WARNING_PARAMETER_COUNT)
321
0
         {
322
            /* Append this parameter */
323
0
            png_const_charp parm = p[parameter];
324
0
            png_const_charp pend = p[parameter] + (sizeof p[parameter]);
325
326
            /* No need to copy the trailing '\0' here, but there is no guarantee
327
             * that parm[] has been initialized, so there is no guarantee of a
328
             * trailing '\0':
329
             */
330
0
            while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
331
0
               msg[i++] = *parm++;
332
333
            /* Consume the parameter digit too: */
334
0
            ++message;
335
0
            continue;
336
0
         }
337
338
         /* else not a parameter and there is a character after the @ sign; just
339
          * copy that.  This is known not to be '\0' because of the test above.
340
          */
341
0
      }
342
343
      /* At this point *message can't be '\0', even in the bad parameter case
344
       * above where there is a lone '@' at the end of the message string.
345
       */
346
0
      msg[i++] = *message++;
347
0
   }
348
349
   /* i is always less than (sizeof msg), so: */
350
0
   msg[i] = '\0';
351
352
   /* And this is the formatted message. It may be larger than
353
    * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
354
    * are not (currently) formatted.
355
    */
356
0
   png_warning(png_ptr, msg);
357
0
}
358
#endif /* WARNINGS */
359
360
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
361
void PNGAPI
362
png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
363
303
{
364
303
   if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
365
303
   {
366
303
#     ifdef PNG_READ_SUPPORTED
367
303
         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
368
303
            png_ptr->chunk_name != 0)
369
303
            png_chunk_warning(png_ptr, error_message);
370
0
         else
371
0
#     endif
372
0
      png_warning(png_ptr, error_message);
373
303
   }
374
375
0
   else
376
0
   {
377
0
#     ifdef PNG_READ_SUPPORTED
378
0
         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
379
0
            png_ptr->chunk_name != 0)
380
0
            png_chunk_error(png_ptr, error_message);
381
0
         else
382
0
#     endif
383
0
      png_error(png_ptr, error_message);
384
0
   }
385
386
#  ifndef PNG_ERROR_TEXT_SUPPORTED
387
      PNG_UNUSED(error_message)
388
#  endif
389
303
}
390
391
void /* PRIVATE */
392
png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
393
0
{
394
0
   if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
395
0
      png_warning(png_ptr, error_message);
396
0
   else
397
0
      png_error(png_ptr, error_message);
398
399
#  ifndef PNG_ERROR_TEXT_SUPPORTED
400
      PNG_UNUSED(error_message)
401
#  endif
402
0
}
403
404
void /* PRIVATE */
405
png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
406
0
{
407
0
   if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
408
0
      png_warning(png_ptr, error_message);
409
0
   else
410
0
      png_error(png_ptr, error_message);
411
412
#  ifndef PNG_ERROR_TEXT_SUPPORTED
413
      PNG_UNUSED(error_message)
414
#  endif
415
0
}
416
#endif /* BENIGN_ERRORS */
417
418
311k
#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */
419
#if defined(PNG_WARNINGS_SUPPORTED) || \
420
   (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))
421
/* These utilities are used internally to build an error message that relates
422
 * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
423
 * which is used to prefix the message.  The message is limited in length
424
 * to 63 bytes. The name characters are output as hex digits wrapped in []
425
 * if the character is invalid.
426
 */
427
94.2k
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
428
static const char png_digit[16] = {
429
   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
430
   'A', 'B', 'C', 'D', 'E', 'F'
431
};
432
433
static void /* PRIVATE */
434
png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
435
    error_message)
436
23.5k
{
437
23.5k
   png_uint_32 chunk_name = png_ptr->chunk_name;
438
23.5k
   int iout = 0, ishift = 24;
439
440
117k
   while (ishift >= 0)
441
94.2k
   {
442
94.2k
      int c = (int)(chunk_name >> ishift) & 0xff;
443
444
94.2k
      ishift -= 8;
445
94.2k
      if (isnonalpha(c) != 0)
446
428
      {
447
428
         buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
448
428
         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
449
428
         buffer[iout++] = png_digit[c & 0x0f];
450
428
         buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
451
428
      }
452
453
93.7k
      else
454
93.7k
      {
455
93.7k
         buffer[iout++] = (char)c;
456
93.7k
      }
457
94.2k
   }
458
459
23.5k
   if (error_message == NULL)
460
0
      buffer[iout] = '\0';
461
462
23.5k
   else
463
23.5k
   {
464
23.5k
      int iin = 0;
465
466
23.5k
      buffer[iout++] = ':';
467
23.5k
      buffer[iout++] = ' ';
468
469
311k
      while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
470
288k
         buffer[iout++] = error_message[iin++];
471
472
      /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
473
23.5k
      buffer[iout] = '\0';
474
23.5k
   }
475
23.5k
}
476
#endif /* WARNINGS || ERROR_TEXT */
477
478
#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
479
PNG_FUNCTION(void,PNGAPI
480
png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
481
    PNG_NORETURN)
482
412
{
483
412
   char msg[18+PNG_MAX_ERROR_TEXT];
484
412
   if (png_ptr == NULL)
485
0
      png_error(png_ptr, error_message);
486
487
412
   else
488
412
   {
489
412
      png_format_buffer(png_ptr, msg, error_message);
490
412
      png_error(png_ptr, msg);
491
412
   }
492
412
}
493
#endif /* READ && ERROR_TEXT */
494
495
#ifdef PNG_WARNINGS_SUPPORTED
496
void PNGAPI
497
png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
498
23.1k
{
499
23.1k
   char msg[18+PNG_MAX_ERROR_TEXT];
500
23.1k
   if (png_ptr == NULL)
501
0
      png_warning(png_ptr, warning_message);
502
503
23.1k
   else
504
23.1k
   {
505
23.1k
      png_format_buffer(png_ptr, msg, warning_message);
506
23.1k
      png_warning(png_ptr, msg);
507
23.1k
   }
508
23.1k
}
509
#endif /* WARNINGS */
510
511
#ifdef PNG_READ_SUPPORTED
512
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
513
void PNGAPI
514
png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
515
    error_message)
516
19.1k
{
517
19.1k
   if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
518
19.1k
      png_chunk_warning(png_ptr, error_message);
519
520
0
   else
521
0
      png_chunk_error(png_ptr, error_message);
522
523
#  ifndef PNG_ERROR_TEXT_SUPPORTED
524
      PNG_UNUSED(error_message)
525
#  endif
526
19.1k
}
527
#endif
528
#endif /* READ */
529
530
void /* PRIVATE */
531
png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
532
80
{
533
#  ifndef PNG_WARNINGS_SUPPORTED
534
      PNG_UNUSED(message)
535
#  endif
536
537
   /* This is always supported, but for just read or just write it
538
    * unconditionally does the right thing.
539
    */
540
#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
541
      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
542
#  endif
543
544
80
#  ifdef PNG_READ_SUPPORTED
545
80
      {
546
80
         if (error < PNG_CHUNK_ERROR)
547
80
            png_chunk_warning(png_ptr, message);
548
549
0
         else
550
0
            png_chunk_benign_error(png_ptr, message);
551
80
      }
552
80
#  endif
553
554
#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
555
      else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
556
#  endif
557
558
#  ifdef PNG_WRITE_SUPPORTED
559
      {
560
         if (error < PNG_CHUNK_WRITE_ERROR)
561
            png_app_warning(png_ptr, message);
562
563
         else
564
            png_app_error(png_ptr, message);
565
      }
566
#  endif
567
80
}
568
569
#ifdef PNG_ERROR_TEXT_SUPPORTED
570
#ifdef PNG_FLOATING_POINT_SUPPORTED
571
PNG_FUNCTION(void,
572
png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
573
0
{
574
0
#  define fixed_message "fixed point overflow in "
575
0
#  define fixed_message_ln ((sizeof fixed_message)-1)
576
0
   unsigned int  iin;
577
0
   char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
578
0
   memcpy(msg, fixed_message, fixed_message_ln);
579
0
   iin = 0;
580
0
   if (name != NULL)
581
0
      while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
582
0
      {
583
0
         msg[fixed_message_ln + iin] = name[iin];
584
0
         ++iin;
585
0
      }
586
0
   msg[fixed_message_ln + iin] = 0;
587
0
   png_error(png_ptr, msg);
588
0
}
589
#endif
590
#endif
591
592
#ifdef PNG_SETJMP_SUPPORTED
593
/* This API only exists if ANSI-C style error handling is used,
594
 * otherwise it is necessary for png_default_error to be overridden.
595
 */
596
jmp_buf* PNGAPI
597
png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
598
    size_t jmp_buf_size)
599
2.77k
{
600
   /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
601
    * and it must not change after that.  Libpng doesn't care how big the
602
    * buffer is, just that it doesn't change.
603
    *
604
    * If the buffer size is no *larger* than the size of jmp_buf when libpng is
605
    * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
606
    * semantics that this call will not fail.  If the size is larger, however,
607
    * the buffer is allocated and this may fail, causing the function to return
608
    * NULL.
609
    */
610
2.77k
   if (png_ptr == NULL)
611
0
      return NULL;
612
613
2.77k
   if (png_ptr->jmp_buf_ptr == NULL)
614
1.80k
   {
615
1.80k
      png_ptr->jmp_buf_size = 0; /* not allocated */
616
617
1.80k
      if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
618
1.80k
         png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
619
620
0
      else
621
0
      {
622
0
         png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
623
0
             png_malloc_warn(png_ptr, jmp_buf_size));
624
625
0
         if (png_ptr->jmp_buf_ptr == NULL)
626
0
            return NULL; /* new NULL return on OOM */
627
628
0
         png_ptr->jmp_buf_size = jmp_buf_size;
629
0
      }
630
1.80k
   }
631
632
970
   else /* Already allocated: check the size */
633
970
   {
634
970
      size_t size = png_ptr->jmp_buf_size;
635
636
970
      if (size == 0)
637
970
      {
638
970
         size = (sizeof png_ptr->jmp_buf_local);
639
970
         if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
640
0
         {
641
            /* This is an internal error in libpng: somehow we have been left
642
             * with a stack allocated jmp_buf when the application regained
643
             * control.  It's always possible to fix this up, but for the moment
644
             * this is a png_error because that makes it easy to detect.
645
             */
646
0
            png_error(png_ptr, "Libpng jmp_buf still allocated");
647
            /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
648
0
         }
649
970
      }
650
651
970
      if (size != jmp_buf_size)
652
0
      {
653
0
         png_warning(png_ptr, "Application jmp_buf size changed");
654
0
         return NULL; /* caller will probably crash: no choice here */
655
0
      }
656
970
   }
657
658
   /* Finally fill in the function, now we have a satisfactory buffer. It is
659
    * valid to change the function on every call.
660
    */
661
2.77k
   png_ptr->longjmp_fn = longjmp_fn;
662
2.77k
   return png_ptr->jmp_buf_ptr;
663
2.77k
}
664
665
void /* PRIVATE */
666
png_free_jmpbuf(png_structrp png_ptr)
667
2.22k
{
668
2.22k
   if (png_ptr != NULL)
669
2.22k
   {
670
2.22k
      jmp_buf *jb = png_ptr->jmp_buf_ptr;
671
672
      /* A size of 0 is used to indicate a local, stack, allocation of the
673
       * pointer; used here and in png.c
674
       */
675
2.22k
      if (jb != NULL && png_ptr->jmp_buf_size > 0)
676
0
      {
677
678
         /* This stuff is so that a failure to free the error control structure
679
          * does not leave libpng in a state with no valid error handling: the
680
          * free always succeeds, if there is an error it gets ignored.
681
          */
682
0
         if (jb != &png_ptr->jmp_buf_local)
683
0
         {
684
            /* Make an internal, libpng, jmp_buf to return here */
685
0
            jmp_buf free_jmp_buf;
686
687
0
            if (!setjmp(free_jmp_buf))
688
0
            {
689
0
               png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
690
0
               png_ptr->jmp_buf_size = 0; /* stack allocation */
691
0
               png_ptr->longjmp_fn = longjmp;
692
0
               png_free(png_ptr, jb); /* Return to setjmp on error */
693
0
            }
694
0
         }
695
0
      }
696
697
      /* *Always* cancel everything out: */
698
2.22k
      png_ptr->jmp_buf_size = 0;
699
2.22k
      png_ptr->jmp_buf_ptr = NULL;
700
2.22k
      png_ptr->longjmp_fn = 0;
701
2.22k
   }
702
2.22k
}
703
#endif
704
705
/* This is the default error handling function.  Note that replacements for
706
 * this function MUST NOT RETURN, or the program will likely crash.  This
707
 * function is used by default, or if the program supplies NULL for the
708
 * error function pointer in png_set_error_fn().
709
 */
710
static PNG_FUNCTION(void /* PRIVATE */,
711
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
712
    PNG_NORETURN)
713
1.37k
{
714
#ifdef PNG_CONSOLE_IO_SUPPORTED
715
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
716
   /* Check on NULL only added in 1.5.4 */
717
   if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
718
   {
719
      /* Strip "#nnnn " from beginning of error message. */
720
      int offset;
721
      char error_number[16];
722
      for (offset = 0; offset<15; offset++)
723
      {
724
         error_number[offset] = error_message[offset + 1];
725
         if (error_message[offset] == ' ')
726
            break;
727
      }
728
729
      if ((offset > 1) && (offset < 15))
730
      {
731
         error_number[offset - 1] = '\0';
732
         fprintf(stderr, "libpng error no. %s: %s",
733
             error_number, error_message + offset + 1);
734
         fprintf(stderr, PNG_STRING_NEWLINE);
735
      }
736
737
      else
738
      {
739
         fprintf(stderr, "libpng error: %s, offset=%d",
740
             error_message, offset);
741
         fprintf(stderr, PNG_STRING_NEWLINE);
742
      }
743
   }
744
   else
745
#endif
746
   {
747
      fprintf(stderr, "libpng error: %s", error_message ? error_message :
748
         "undefined");
749
      fprintf(stderr, PNG_STRING_NEWLINE);
750
   }
751
#else
752
1.37k
   PNG_UNUSED(error_message) /* Make compiler happy */
753
1.37k
#endif
754
1.37k
   png_longjmp(png_ptr, 1);
755
1.37k
}
756
757
PNG_FUNCTION(void,PNGAPI
758
png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
759
1.37k
{
760
1.37k
#ifdef PNG_SETJMP_SUPPORTED
761
1.37k
   if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
762
1.37k
       png_ptr->jmp_buf_ptr != NULL)
763
1.37k
      png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
764
#else
765
   PNG_UNUSED(png_ptr)
766
   PNG_UNUSED(val)
767
#endif
768
769
   /* If control reaches this point, png_longjmp() must not return. The only
770
    * choice is to terminate the whole process (or maybe the thread); to do
771
    * this the ANSI-C abort() function is used unless a different method is
772
    * implemented by overriding the default configuration setting for
773
    * PNG_ABORT().
774
    */
775
1.37k
   PNG_ABORT();
776
1.37k
}
777
778
#ifdef PNG_WARNINGS_SUPPORTED
779
/* This function is called when there is a warning, but the library thinks
780
 * it can continue anyway.  Replacement functions don't have to do anything
781
 * here if you don't want them to.  In the default configuration, png_ptr is
782
 * not used, but it is passed in case it may be useful.
783
 */
784
static void /* PRIVATE */
785
png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
786
17.8k
{
787
#ifdef PNG_CONSOLE_IO_SUPPORTED
788
#  ifdef PNG_ERROR_NUMBERS_SUPPORTED
789
   if (*warning_message == PNG_LITERAL_SHARP)
790
   {
791
      int offset;
792
      char warning_number[16];
793
      for (offset = 0; offset < 15; offset++)
794
      {
795
         warning_number[offset] = warning_message[offset + 1];
796
         if (warning_message[offset] == ' ')
797
            break;
798
      }
799
800
      if ((offset > 1) && (offset < 15))
801
      {
802
         warning_number[offset + 1] = '\0';
803
         fprintf(stderr, "libpng warning no. %s: %s",
804
             warning_number, warning_message + offset);
805
         fprintf(stderr, PNG_STRING_NEWLINE);
806
      }
807
808
      else
809
      {
810
         fprintf(stderr, "libpng warning: %s",
811
             warning_message);
812
         fprintf(stderr, PNG_STRING_NEWLINE);
813
      }
814
   }
815
   else
816
#  endif
817
818
   {
819
      fprintf(stderr, "libpng warning: %s", warning_message);
820
      fprintf(stderr, PNG_STRING_NEWLINE);
821
   }
822
#else
823
17.8k
   PNG_UNUSED(warning_message) /* Make compiler happy */
824
17.8k
#endif
825
17.8k
   PNG_UNUSED(png_ptr) /* Make compiler happy */
826
17.8k
}
827
#endif /* WARNINGS */
828
829
/* This function is called when the application wants to use another method
830
 * of handling errors and warnings.  Note that the error function MUST NOT
831
 * return to the calling routine or serious problems will occur.  The return
832
 * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
833
 */
834
void PNGAPI
835
png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
836
    png_error_ptr error_fn, png_error_ptr warning_fn)
837
2.22k
{
838
2.22k
   if (png_ptr == NULL)
839
0
      return;
840
841
2.22k
   png_ptr->error_ptr = error_ptr;
842
2.22k
   png_ptr->error_fn = error_fn;
843
2.22k
#ifdef PNG_WARNINGS_SUPPORTED
844
2.22k
   png_ptr->warning_fn = warning_fn;
845
#else
846
   PNG_UNUSED(warning_fn)
847
#endif
848
2.22k
}
849
850
851
/* This function returns a pointer to the error_ptr associated with the user
852
 * functions.  The application should free any memory associated with this
853
 * pointer before png_write_destroy and png_read_destroy are called.
854
 */
855
png_voidp PNGAPI
856
png_get_error_ptr(png_const_structrp png_ptr)
857
0
{
858
0
   if (png_ptr == NULL)
859
0
      return NULL;
860
861
0
   return (png_voidp)png_ptr->error_ptr;
862
0
}
863
864
865
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
866
void PNGAPI
867
png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
868
{
869
   if (png_ptr != NULL)
870
   {
871
      png_ptr->flags &=
872
         ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
873
         PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
874
   }
875
}
876
#endif
877
878
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
879
   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
880
   /* Currently the above both depend on SETJMP_SUPPORTED, however it would be
881
    * possible to implement without setjmp support just so long as there is some
882
    * way to handle the error return here:
883
    */
884
PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
885
png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
886
    PNG_NORETURN)
887
111
{
888
111
   png_const_structrp png_ptr = png_nonconst_ptr;
889
111
   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
890
891
   /* An error is always logged here, overwriting anything (typically a warning)
892
    * that is already there:
893
    */
894
111
   if (image != NULL)
895
111
   {
896
111
      png_safecat(image->message, (sizeof image->message), 0, error_message);
897
111
      image->warning_or_error |= PNG_IMAGE_ERROR;
898
899
      /* Retrieve the jmp_buf from within the png_control, making this work for
900
       * C++ compilation too is pretty tricky: C++ wants a pointer to the first
901
       * element of a jmp_buf, but C doesn't tell us the type of that.
902
       */
903
111
      if (image->opaque != NULL && image->opaque->error_buf != NULL)
904
111
         longjmp(png_control_jmp_buf(image->opaque), 1);
905
906
      /* Missing longjmp buffer, the following is to help debugging: */
907
0
      {
908
0
         size_t pos = png_safecat(image->message, (sizeof image->message), 0,
909
0
             "bad longjmp: ");
910
0
         png_safecat(image->message, (sizeof image->message), pos,
911
0
             error_message);
912
0
      }
913
0
   }
914
915
   /* Here on an internal programming error. */
916
0
   abort();
917
111
}
918
919
#ifdef PNG_WARNINGS_SUPPORTED
920
void /* PRIVATE */ PNGCBAPI
921
png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
922
5.67k
{
923
5.67k
   png_const_structrp png_ptr = png_nonconst_ptr;
924
5.67k
   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
925
926
   /* A warning is only logged if there is no prior warning or error. */
927
5.67k
   if (image->warning_or_error == 0)
928
228
   {
929
228
      png_safecat(image->message, (sizeof image->message), 0, warning_message);
930
228
      image->warning_or_error |= PNG_IMAGE_WARNING;
931
228
   }
932
5.67k
}
933
#endif
934
935
int /* PRIVATE */
936
png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg)
937
844
{
938
844
   const png_voidp saved_error_buf = image->opaque->error_buf;
939
844
   jmp_buf safe_jmpbuf;
940
941
   /* Safely execute function(arg), with png_error returning back here. */
942
844
   if (setjmp(safe_jmpbuf) == 0)
943
844
   {
944
844
      int result;
945
946
844
      image->opaque->error_buf = safe_jmpbuf;
947
844
      result = function(arg);
948
844
      image->opaque->error_buf = saved_error_buf;
949
950
844
      if (result)
951
733
         return 1; /* success */
952
844
   }
953
954
   /* The function failed either because of a caught png_error and a regular
955
    * return of false above or because of an uncaught png_error from the
956
    * function itself.  Ensure that the error_buf is always set back to the
957
    * value saved above:
958
    */
959
111
   image->opaque->error_buf = saved_error_buf;
960
961
   /* On the final false return, when about to return control to the caller, the
962
    * image is freed (png_image_free does this check but it is duplicated here
963
    * for clarity:
964
    */
965
111
   if (saved_error_buf == NULL)
966
111
      png_image_free(image);
967
968
111
   return 0; /* failure */
969
844
}
970
#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
971
#endif /* READ || WRITE */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngget.c.html b/part1/report/w_corpus/src/libpng/pngget.c.html new file mode 100644 index 0000000..e8d1d01 --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngget.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngget.c
Line
Count
Source (jump to first uncovered line)
1
/* pngget.c - retrieval of values from info struct
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 */
13
14
#include "pngpriv.h"
15
16
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
17
18
png_uint_32 PNGAPI
19
png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
20
    png_uint_32 flag)
21
0
{
22
0
   if (png_ptr != NULL && info_ptr != NULL)
23
0
   {
24
0
#ifdef PNG_READ_tRNS_SUPPORTED
25
      /* png_handle_PLTE() may have canceled a valid tRNS chunk but left the
26
       * 'valid' flag for the detection of duplicate chunks. Do not report a
27
       * valid tRNS chunk in this case.
28
       */
29
0
      if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0)
30
0
         return 0;
31
0
#endif
32
33
0
      return info_ptr->valid & flag;
34
0
   }
35
36
0
   return 0;
37
0
}
38
39
size_t PNGAPI
40
png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
41
967
{
42
967
   if (png_ptr != NULL && info_ptr != NULL)
43
967
      return info_ptr->rowbytes;
44
45
0
   return 0;
46
967
}
47
48
#ifdef PNG_INFO_IMAGE_SUPPORTED
49
png_bytepp PNGAPI
50
png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
51
0
{
52
0
   if (png_ptr != NULL && info_ptr != NULL)
53
0
      return info_ptr->row_pointers;
54
55
0
   return 0;
56
0
}
57
#endif
58
59
#ifdef PNG_EASY_ACCESS_SUPPORTED
60
/* Easy access to info, added in libpng-0.99 */
61
png_uint_32 PNGAPI
62
png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
63
0
{
64
0
   if (png_ptr != NULL && info_ptr != NULL)
65
0
      return info_ptr->width;
66
67
0
   return 0;
68
0
}
69
70
png_uint_32 PNGAPI
71
png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
72
0
{
73
0
   if (png_ptr != NULL && info_ptr != NULL)
74
0
      return info_ptr->height;
75
76
0
   return 0;
77
0
}
78
79
png_byte PNGAPI
80
png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
81
0
{
82
0
   if (png_ptr != NULL && info_ptr != NULL)
83
0
      return info_ptr->bit_depth;
84
85
0
   return 0;
86
0
}
87
88
png_byte PNGAPI
89
png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
90
0
{
91
0
   if (png_ptr != NULL && info_ptr != NULL)
92
0
      return info_ptr->color_type;
93
94
0
   return 0;
95
0
}
96
97
png_byte PNGAPI
98
png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
99
0
{
100
0
   if (png_ptr != NULL && info_ptr != NULL)
101
0
      return info_ptr->filter_type;
102
103
0
   return 0;
104
0
}
105
106
png_byte PNGAPI
107
png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
108
0
{
109
0
   if (png_ptr != NULL && info_ptr != NULL)
110
0
      return info_ptr->interlace_type;
111
112
0
   return 0;
113
0
}
114
115
png_byte PNGAPI
116
png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
117
0
{
118
0
   if (png_ptr != NULL && info_ptr != NULL)
119
0
      return info_ptr->compression_type;
120
121
0
   return 0;
122
0
}
123
124
png_uint_32 PNGAPI
125
png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
126
   info_ptr)
127
0
{
128
0
#ifdef PNG_pHYs_SUPPORTED
129
0
   png_debug(1, "in png_get_x_pixels_per_meter");
130
131
0
   if (png_ptr != NULL && info_ptr != NULL &&
132
0
       (info_ptr->valid & PNG_INFO_pHYs) != 0)
133
0
   {
134
0
      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
135
0
         return info_ptr->x_pixels_per_unit;
136
0
   }
137
#else
138
   PNG_UNUSED(png_ptr)
139
   PNG_UNUSED(info_ptr)
140
#endif
141
142
0
   return 0;
143
0
}
144
145
png_uint_32 PNGAPI
146
png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
147
    info_ptr)
148
0
{
149
0
#ifdef PNG_pHYs_SUPPORTED
150
0
   png_debug(1, "in png_get_y_pixels_per_meter");
151
152
0
   if (png_ptr != NULL && info_ptr != NULL &&
153
0
       (info_ptr->valid & PNG_INFO_pHYs) != 0)
154
0
   {
155
0
      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
156
0
         return info_ptr->y_pixels_per_unit;
157
0
   }
158
#else
159
   PNG_UNUSED(png_ptr)
160
   PNG_UNUSED(info_ptr)
161
#endif
162
163
0
   return 0;
164
0
}
165
166
png_uint_32 PNGAPI
167
png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
168
0
{
169
0
#ifdef PNG_pHYs_SUPPORTED
170
0
   png_debug(1, "in png_get_pixels_per_meter");
171
172
0
   if (png_ptr != NULL && info_ptr != NULL &&
173
0
       (info_ptr->valid & PNG_INFO_pHYs) != 0)
174
0
   {
175
0
      if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
176
0
          info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
177
0
         return info_ptr->x_pixels_per_unit;
178
0
   }
179
#else
180
   PNG_UNUSED(png_ptr)
181
   PNG_UNUSED(info_ptr)
182
#endif
183
184
0
   return 0;
185
0
}
186
187
#ifdef PNG_FLOATING_POINT_SUPPORTED
188
float PNGAPI
189
png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
190
   info_ptr)
191
0
{
192
0
#ifdef PNG_READ_pHYs_SUPPORTED
193
0
   png_debug(1, "in png_get_pixel_aspect_ratio");
194
195
0
   if (png_ptr != NULL && info_ptr != NULL &&
196
0
       (info_ptr->valid & PNG_INFO_pHYs) != 0)
197
0
   {
198
0
      if (info_ptr->x_pixels_per_unit != 0)
199
0
         return (float)info_ptr->y_pixels_per_unit
200
0
              / (float)info_ptr->x_pixels_per_unit;
201
0
   }
202
#else
203
   PNG_UNUSED(png_ptr)
204
   PNG_UNUSED(info_ptr)
205
#endif
206
207
0
   return (float)0.0;
208
0
}
209
#endif
210
211
#ifdef PNG_FIXED_POINT_SUPPORTED
212
png_fixed_point PNGAPI
213
png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
214
    png_const_inforp info_ptr)
215
0
{
216
0
#ifdef PNG_READ_pHYs_SUPPORTED
217
0
   png_debug(1, "in png_get_pixel_aspect_ratio_fixed");
218
219
0
   if (png_ptr != NULL && info_ptr != NULL &&
220
0
       (info_ptr->valid & PNG_INFO_pHYs) != 0 &&
221
0
       info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&
222
0
       info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX &&
223
0
       info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
224
0
   {
225
0
      png_fixed_point res;
226
227
      /* The following casts work because a PNG 4 byte integer only has a valid
228
       * range of 0..2^31-1; otherwise the cast might overflow.
229
       */
230
0
      if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
231
0
          (png_int_32)info_ptr->x_pixels_per_unit) != 0)
232
0
         return res;
233
0
   }
234
#else
235
   PNG_UNUSED(png_ptr)
236
   PNG_UNUSED(info_ptr)
237
#endif
238
239
0
   return 0;
240
0
}
241
#endif
242
243
png_int_32 PNGAPI
244
png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
245
0
{
246
0
#ifdef PNG_oFFs_SUPPORTED
247
0
   png_debug(1, "in png_get_x_offset_microns");
248
249
0
   if (png_ptr != NULL && info_ptr != NULL &&
250
0
       (info_ptr->valid & PNG_INFO_oFFs) != 0)
251
0
   {
252
0
      if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
253
0
         return info_ptr->x_offset;
254
0
   }
255
#else
256
   PNG_UNUSED(png_ptr)
257
   PNG_UNUSED(info_ptr)
258
#endif
259
260
0
   return 0;
261
0
}
262
263
png_int_32 PNGAPI
264
png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
265
0
{
266
0
#ifdef PNG_oFFs_SUPPORTED
267
0
   png_debug(1, "in png_get_y_offset_microns");
268
269
0
   if (png_ptr != NULL && info_ptr != NULL &&
270
0
       (info_ptr->valid & PNG_INFO_oFFs) != 0)
271
0
   {
272
0
      if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
273
0
         return info_ptr->y_offset;
274
0
   }
275
#else
276
   PNG_UNUSED(png_ptr)
277
   PNG_UNUSED(info_ptr)
278
#endif
279
280
0
   return 0;
281
0
}
282
283
png_int_32 PNGAPI
284
png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
285
0
{
286
0
#ifdef PNG_oFFs_SUPPORTED
287
0
   png_debug(1, "in png_get_x_offset_pixels");
288
289
0
   if (png_ptr != NULL && info_ptr != NULL &&
290
0
       (info_ptr->valid & PNG_INFO_oFFs) != 0)
291
0
   {
292
0
      if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
293
0
         return info_ptr->x_offset;
294
0
   }
295
#else
296
   PNG_UNUSED(png_ptr)
297
   PNG_UNUSED(info_ptr)
298
#endif
299
300
0
   return 0;
301
0
}
302
303
png_int_32 PNGAPI
304
png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
305
0
{
306
0
#ifdef PNG_oFFs_SUPPORTED
307
0
   png_debug(1, "in png_get_y_offset_pixels");
308
309
0
   if (png_ptr != NULL && info_ptr != NULL &&
310
0
       (info_ptr->valid & PNG_INFO_oFFs) != 0)
311
0
   {
312
0
      if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
313
0
         return info_ptr->y_offset;
314
0
   }
315
#else
316
   PNG_UNUSED(png_ptr)
317
   PNG_UNUSED(info_ptr)
318
#endif
319
320
0
   return 0;
321
0
}
322
323
#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
324
static png_uint_32
325
ppi_from_ppm(png_uint_32 ppm)
326
0
{
327
#if 0
328
   /* The conversion is *(2.54/100), in binary (32 digits):
329
    * .00000110100000001001110101001001
330
    */
331
   png_uint_32 t1001, t1101;
332
   ppm >>= 1;                  /* .1 */
333
   t1001 = ppm + (ppm >> 3);   /* .1001 */
334
   t1101 = t1001 + (ppm >> 1); /* .1101 */
335
   ppm >>= 20;                 /* .000000000000000000001 */
336
   t1101 += t1101 >> 15;       /* .1101000000000001101 */
337
   t1001 >>= 11;               /* .000000000001001 */
338
   t1001 += t1001 >> 12;       /* .000000000001001000000001001 */
339
   ppm += t1001;               /* .000000000001001000001001001 */
340
   ppm += t1101;               /* .110100000001001110101001001 */
341
   return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
342
#else
343
   /* The argument is a PNG unsigned integer, so it is not permitted
344
    * to be bigger than 2^31.
345
    */
346
0
   png_fixed_point result;
347
0
   if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
348
0
       5000) != 0)
349
0
      return (png_uint_32)result;
350
351
   /* Overflow. */
352
0
   return 0;
353
0
#endif
354
0
}
355
356
png_uint_32 PNGAPI
357
png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
358
0
{
359
0
   return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));
360
0
}
361
362
png_uint_32 PNGAPI
363
png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
364
0
{
365
0
   return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));
366
0
}
367
368
png_uint_32 PNGAPI
369
png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
370
0
{
371
0
   return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));
372
0
}
373
374
#ifdef PNG_FIXED_POINT_SUPPORTED
375
static png_fixed_point
376
png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
377
0
{
378
   /* Convert from meters * 1,000,000 to inches * 100,000, meters to
379
    * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
380
    * Notice that this can overflow - a warning is output and 0 is
381
    * returned.
382
    */
383
0
   png_fixed_point result;
384
385
0
   if (png_muldiv(&result, microns, 500, 127) != 0)
386
0
      return result;
387
388
0
   png_warning(png_ptr, "fixed point overflow ignored");
389
0
   return 0;
390
0
}
391
392
png_fixed_point PNGAPI
393
png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
394
    png_const_inforp info_ptr)
395
0
{
396
0
   return png_fixed_inches_from_microns(png_ptr,
397
0
       png_get_x_offset_microns(png_ptr, info_ptr));
398
0
}
399
#endif /* FIXED_POINT */
400
401
#ifdef PNG_FIXED_POINT_SUPPORTED
402
png_fixed_point PNGAPI
403
png_get_y_offset_inches_fixed(png_const_structrp png_ptr,
404
    png_const_inforp info_ptr)
405
0
{
406
0
   return png_fixed_inches_from_microns(png_ptr,
407
0
       png_get_y_offset_microns(png_ptr, info_ptr));
408
0
}
409
#endif
410
411
#ifdef PNG_FLOATING_POINT_SUPPORTED
412
float PNGAPI
413
png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
414
0
{
415
   /* To avoid the overflow do the conversion directly in floating
416
    * point.
417
    */
418
0
   return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
419
0
}
420
#endif
421
422
#ifdef PNG_FLOATING_POINT_SUPPORTED
423
float PNGAPI
424
png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
425
0
{
426
   /* To avoid the overflow do the conversion directly in floating
427
    * point.
428
    */
429
0
   return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
430
0
}
431
#endif
432
433
#ifdef PNG_pHYs_SUPPORTED
434
png_uint_32 PNGAPI
435
png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
436
    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
437
0
{
438
0
   png_uint_32 retval = 0;
439
440
0
   png_debug1(1, "in %s retrieval function", "pHYs");
441
442
0
   if (png_ptr != NULL && info_ptr != NULL &&
443
0
       (info_ptr->valid & PNG_INFO_pHYs) != 0)
444
0
   {
445
0
      if (res_x != NULL)
446
0
      {
447
0
         *res_x = info_ptr->x_pixels_per_unit;
448
0
         retval |= PNG_INFO_pHYs;
449
0
      }
450
451
0
      if (res_y != NULL)
452
0
      {
453
0
         *res_y = info_ptr->y_pixels_per_unit;
454
0
         retval |= PNG_INFO_pHYs;
455
0
      }
456
457
0
      if (unit_type != NULL)
458
0
      {
459
0
         *unit_type = (int)info_ptr->phys_unit_type;
460
0
         retval |= PNG_INFO_pHYs;
461
462
0
         if (*unit_type == 1)
463
0
         {
464
0
            if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
465
0
            if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
466
0
         }
467
0
      }
468
0
   }
469
470
0
   return retval;
471
0
}
472
#endif /* pHYs */
473
#endif /* INCH_CONVERSIONS */
474
475
/* png_get_channels really belongs in here, too, but it's been around longer */
476
477
#endif /* EASY_ACCESS */
478
479
480
png_byte PNGAPI
481
png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
482
0
{
483
0
   if (png_ptr != NULL && info_ptr != NULL)
484
0
      return info_ptr->channels;
485
486
0
   return 0;
487
0
}
488
489
#ifdef PNG_READ_SUPPORTED
490
png_const_bytep PNGAPI
491
png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
492
0
{
493
0
   if (png_ptr != NULL && info_ptr != NULL)
494
0
      return info_ptr->signature;
495
496
0
   return NULL;
497
0
}
498
#endif
499
500
#ifdef PNG_bKGD_SUPPORTED
501
png_uint_32 PNGAPI
502
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
503
    png_color_16p *background)
504
0
{
505
0
   png_debug1(1, "in %s retrieval function", "bKGD");
506
507
0
   if (png_ptr != NULL && info_ptr != NULL &&
508
0
       (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
509
0
       background != NULL)
510
0
   {
511
0
      *background = &(info_ptr->background);
512
0
      return PNG_INFO_bKGD;
513
0
   }
514
515
0
   return 0;
516
0
}
517
#endif
518
519
#ifdef PNG_cHRM_SUPPORTED
520
/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
521
 * same time to correct the rgb grayscale coefficient defaults obtained from the
522
 * cHRM chunk in 1.5.4
523
 */
524
#  ifdef PNG_FLOATING_POINT_SUPPORTED
525
png_uint_32 PNGAPI
526
png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
527
    double *whitex, double *whitey, double *redx, double *redy,
528
    double *greenx, double *greeny, double *bluex, double *bluey)
529
0
{
530
0
   png_debug1(1, "in %s retrieval function", "cHRM");
531
532
   /* PNGv3: this just returns the values store from the cHRM, if any. */
533
0
   if (png_ptr != NULL && info_ptr != NULL &&
534
0
       (info_ptr->valid & PNG_INFO_cHRM) != 0)
535
0
   {
536
0
      if (whitex != NULL)
537
0
         *whitex = png_float(png_ptr, info_ptr->cHRM.whitex, "cHRM wx");
538
0
      if (whitey != NULL)
539
0
         *whitey = png_float(png_ptr, info_ptr->cHRM.whitey, "cHRM wy");
540
0
      if (redx   != NULL)
541
0
         *redx   = png_float(png_ptr, info_ptr->cHRM.redx,   "cHRM rx");
542
0
      if (redy   != NULL)
543
0
         *redy   = png_float(png_ptr, info_ptr->cHRM.redy,   "cHRM ry");
544
0
      if (greenx != NULL)
545
0
         *greenx = png_float(png_ptr, info_ptr->cHRM.greenx, "cHRM gx");
546
0
      if (greeny != NULL)
547
0
         *greeny = png_float(png_ptr, info_ptr->cHRM.greeny, "cHRM gy");
548
0
      if (bluex  != NULL)
549
0
         *bluex  = png_float(png_ptr, info_ptr->cHRM.bluex,  "cHRM bx");
550
0
      if (bluey  != NULL)
551
0
         *bluey  = png_float(png_ptr, info_ptr->cHRM.bluey,  "cHRM by");
552
0
      return PNG_INFO_cHRM;
553
0
   }
554
555
0
   return 0;
556
0
}
557
558
png_uint_32 PNGAPI
559
png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
560
    double *red_X, double *red_Y, double *red_Z, double *green_X,
561
    double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
562
    double *blue_Z)
563
0
{
564
0
   png_XYZ XYZ;
565
0
   png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
566
567
0
   if (png_ptr != NULL && info_ptr != NULL &&
568
0
       (info_ptr->valid & PNG_INFO_cHRM) != 0 &&
569
0
       png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0)
570
0
   {
571
0
      if (red_X != NULL)
572
0
         *red_X = png_float(png_ptr, XYZ.red_X, "cHRM red X");
573
0
      if (red_Y != NULL)
574
0
         *red_Y = png_float(png_ptr, XYZ.red_Y, "cHRM red Y");
575
0
      if (red_Z != NULL)
576
0
         *red_Z = png_float(png_ptr, XYZ.red_Z, "cHRM red Z");
577
0
      if (green_X != NULL)
578
0
         *green_X = png_float(png_ptr, XYZ.green_X, "cHRM green X");
579
0
      if (green_Y != NULL)
580
0
         *green_Y = png_float(png_ptr, XYZ.green_Y, "cHRM green Y");
581
0
      if (green_Z != NULL)
582
0
         *green_Z = png_float(png_ptr, XYZ.green_Z, "cHRM green Z");
583
0
      if (blue_X != NULL)
584
0
         *blue_X = png_float(png_ptr, XYZ.blue_X, "cHRM blue X");
585
0
      if (blue_Y != NULL)
586
0
         *blue_Y = png_float(png_ptr, XYZ.blue_Y, "cHRM blue Y");
587
0
      if (blue_Z != NULL)
588
0
         *blue_Z = png_float(png_ptr, XYZ.blue_Z, "cHRM blue Z");
589
0
      return PNG_INFO_cHRM;
590
0
   }
591
592
0
   return 0;
593
0
}
594
#  endif
595
596
#  ifdef PNG_FIXED_POINT_SUPPORTED
597
png_uint_32 PNGAPI
598
png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
599
    png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
600
    png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
601
    png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
602
    png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
603
    png_fixed_point *int_blue_Z)
604
0
{
605
0
   png_XYZ XYZ;
606
0
   png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
607
608
0
   if (png_ptr != NULL && info_ptr != NULL &&
609
0
       (info_ptr->valid & PNG_INFO_cHRM) != 0U &&
610
0
       png_XYZ_from_xy(&XYZ, &info_ptr->cHRM) == 0)
611
0
   {
612
0
      if (int_red_X != NULL) *int_red_X = XYZ.red_X;
613
0
      if (int_red_Y != NULL) *int_red_Y = XYZ.red_Y;
614
0
      if (int_red_Z != NULL) *int_red_Z = XYZ.red_Z;
615
0
      if (int_green_X != NULL) *int_green_X = XYZ.green_X;
616
0
      if (int_green_Y != NULL) *int_green_Y = XYZ.green_Y;
617
0
      if (int_green_Z != NULL) *int_green_Z = XYZ.green_Z;
618
0
      if (int_blue_X != NULL) *int_blue_X = XYZ.blue_X;
619
0
      if (int_blue_Y != NULL) *int_blue_Y = XYZ.blue_Y;
620
0
      if (int_blue_Z != NULL) *int_blue_Z = XYZ.blue_Z;
621
0
      return PNG_INFO_cHRM;
622
0
   }
623
624
0
   return 0;
625
0
}
626
627
png_uint_32 PNGAPI
628
png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
629
    png_fixed_point *whitex, png_fixed_point *whitey, png_fixed_point *redx,
630
    png_fixed_point *redy, png_fixed_point *greenx, png_fixed_point *greeny,
631
    png_fixed_point *bluex, png_fixed_point *bluey)
632
0
{
633
0
   png_debug1(1, "in %s retrieval function", "cHRM");
634
635
   /* PNGv3: this just returns the values store from the cHRM, if any. */
636
0
   if (png_ptr != NULL && info_ptr != NULL &&
637
0
       (info_ptr->valid & PNG_INFO_cHRM) != 0)
638
0
   {
639
0
      if (whitex != NULL) *whitex = info_ptr->cHRM.whitex;
640
0
      if (whitey != NULL) *whitey = info_ptr->cHRM.whitey;
641
0
      if (redx   != NULL) *redx   = info_ptr->cHRM.redx;
642
0
      if (redy   != NULL) *redy   = info_ptr->cHRM.redy;
643
0
      if (greenx != NULL) *greenx = info_ptr->cHRM.greenx;
644
0
      if (greeny != NULL) *greeny = info_ptr->cHRM.greeny;
645
0
      if (bluex  != NULL) *bluex  = info_ptr->cHRM.bluex;
646
0
      if (bluey  != NULL) *bluey  = info_ptr->cHRM.bluey;
647
0
      return PNG_INFO_cHRM;
648
0
   }
649
650
0
   return 0;
651
0
}
652
#  endif
653
#endif
654
655
#ifdef PNG_gAMA_SUPPORTED
656
#  ifdef PNG_FIXED_POINT_SUPPORTED
657
png_uint_32 PNGAPI
658
png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
659
    png_fixed_point *file_gamma)
660
0
{
661
0
   png_debug1(1, "in %s retrieval function", "gAMA");
662
663
   /* PNGv3 compatibility: only report gAMA if it is really present. */
664
0
   if (png_ptr != NULL && info_ptr != NULL &&
665
0
       (info_ptr->valid & PNG_INFO_gAMA) != 0)
666
0
   {
667
0
      if (file_gamma != NULL) *file_gamma = info_ptr->gamma;
668
0
      return PNG_INFO_gAMA;
669
0
   }
670
671
0
   return 0;
672
0
}
673
#  endif
674
675
#  ifdef PNG_FLOATING_POINT_SUPPORTED
676
png_uint_32 PNGAPI
677
png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
678
    double *file_gamma)
679
0
{
680
0
   png_debug1(1, "in %s retrieval function", "gAMA(float)");
681
682
   /* PNGv3 compatibility: only report gAMA if it is really present. */
683
0
   if (png_ptr != NULL && info_ptr != NULL &&
684
0
       (info_ptr->valid & PNG_INFO_gAMA) != 0)
685
0
   {
686
0
      if (file_gamma != NULL)
687
0
         *file_gamma = png_float(png_ptr, info_ptr->gamma, "gAMA");
688
689
0
      return PNG_INFO_gAMA;
690
0
   }
691
692
0
   return 0;
693
0
}
694
#  endif
695
#endif
696
697
#ifdef PNG_sRGB_SUPPORTED
698
png_uint_32 PNGAPI
699
png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
700
    int *file_srgb_intent)
701
0
{
702
0
   png_debug1(1, "in %s retrieval function", "sRGB");
703
704
0
   if (png_ptr != NULL && info_ptr != NULL &&
705
0
      (info_ptr->valid & PNG_INFO_sRGB) != 0)
706
0
   {
707
0
      if (file_srgb_intent != NULL)
708
0
         *file_srgb_intent = info_ptr->rendering_intent;
709
0
      return PNG_INFO_sRGB;
710
0
   }
711
712
0
   return 0;
713
0
}
714
#endif
715
716
#ifdef PNG_iCCP_SUPPORTED
717
png_uint_32 PNGAPI
718
png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
719
    png_charpp name, int *compression_type,
720
    png_bytepp profile, png_uint_32 *proflen)
721
0
{
722
0
   png_debug1(1, "in %s retrieval function", "iCCP");
723
724
0
   if (png_ptr != NULL && info_ptr != NULL &&
725
0
       (info_ptr->valid & PNG_INFO_iCCP) != 0 &&
726
0
       name != NULL && profile != NULL && proflen != NULL)
727
0
   {
728
0
      *name = info_ptr->iccp_name;
729
0
      *profile = info_ptr->iccp_profile;
730
0
      *proflen = png_get_uint_32(info_ptr->iccp_profile);
731
      /* This is somewhat irrelevant since the profile data returned has
732
       * actually been uncompressed.
733
       */
734
0
      if (compression_type != NULL)
735
0
         *compression_type = PNG_COMPRESSION_TYPE_BASE;
736
0
      return PNG_INFO_iCCP;
737
0
   }
738
739
0
   return 0;
740
741
0
}
742
#endif
743
744
#ifdef PNG_sPLT_SUPPORTED
745
int PNGAPI
746
png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
747
    png_sPLT_tpp spalettes)
748
0
{
749
0
   png_debug1(1, "in %s retrieval function", "sPLT");
750
751
0
   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
752
0
   {
753
0
      *spalettes = info_ptr->splt_palettes;
754
0
      return info_ptr->splt_palettes_num;
755
0
   }
756
757
0
   return 0;
758
0
}
759
#endif
760
761
#ifdef PNG_cICP_SUPPORTED
762
png_uint_32 PNGAPI
763
png_get_cICP(png_const_structrp png_ptr,
764
             png_const_inforp info_ptr, png_bytep colour_primaries,
765
             png_bytep transfer_function, png_bytep matrix_coefficients,
766
             png_bytep video_full_range_flag)
767
0
{
768
0
    png_debug1(1, "in %s retrieval function", "cICP");
769
770
0
    if (png_ptr != NULL && info_ptr != NULL &&
771
0
        (info_ptr->valid & PNG_INFO_cICP) != 0 &&
772
0
        colour_primaries != NULL && transfer_function != NULL &&
773
0
        matrix_coefficients != NULL && video_full_range_flag != NULL)
774
0
    {
775
0
        *colour_primaries = info_ptr->cicp_colour_primaries;
776
0
        *transfer_function = info_ptr->cicp_transfer_function;
777
0
        *matrix_coefficients = info_ptr->cicp_matrix_coefficients;
778
0
        *video_full_range_flag = info_ptr->cicp_video_full_range_flag;
779
0
        return (PNG_INFO_cICP);
780
0
    }
781
782
0
    return 0;
783
0
}
784
#endif
785
786
#ifdef PNG_cLLI_SUPPORTED
787
#  ifdef PNG_FIXED_POINT_SUPPORTED
788
png_uint_32 PNGAPI
789
png_get_cLLI_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
790
    png_uint_32p maxCLL,
791
    png_uint_32p maxFALL)
792
0
{
793
0
   png_debug1(1, "in %s retrieval function", "cLLI");
794
795
0
   if (png_ptr != NULL && info_ptr != NULL &&
796
0
       (info_ptr->valid & PNG_INFO_cLLI) != 0)
797
0
   {
798
0
      if (maxCLL != NULL) *maxCLL = info_ptr->maxCLL;
799
0
      if (maxFALL != NULL) *maxFALL = info_ptr->maxFALL;
800
0
      return PNG_INFO_cLLI;
801
0
   }
802
803
0
   return 0;
804
0
}
805
#  endif
806
807
#  ifdef PNG_FLOATING_POINT_SUPPORTED
808
png_uint_32 PNGAPI
809
png_get_cLLI(png_const_structrp png_ptr, png_const_inforp info_ptr,
810
      double *maxCLL, double *maxFALL)
811
0
{
812
0
   png_debug1(1, "in %s retrieval function", "cLLI(float)");
813
814
0
   if (png_ptr != NULL && info_ptr != NULL &&
815
0
       (info_ptr->valid & PNG_INFO_cLLI) != 0)
816
0
   {
817
0
      if (maxCLL != NULL) *maxCLL = info_ptr->maxCLL * .0001;
818
0
      if (maxFALL != NULL) *maxFALL = info_ptr->maxFALL * .0001;
819
0
      return PNG_INFO_cLLI;
820
0
   }
821
822
0
   return 0;
823
0
}
824
#  endif
825
#endif /* cLLI */
826
827
#ifdef PNG_mDCV_SUPPORTED
828
#  ifdef PNG_FIXED_POINT_SUPPORTED
829
png_uint_32 PNGAPI
830
png_get_mDCV_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
831
    png_fixed_point *white_x, png_fixed_point *white_y,
832
    png_fixed_point *red_x, png_fixed_point *red_y,
833
    png_fixed_point *green_x, png_fixed_point *green_y,
834
    png_fixed_point *blue_x, png_fixed_point *blue_y,
835
    png_uint_32p mastering_maxDL, png_uint_32p mastering_minDL)
836
0
{
837
0
   png_debug1(1, "in %s retrieval function", "mDCV");
838
839
0
   if (png_ptr != NULL && info_ptr != NULL &&
840
0
       (info_ptr->valid & PNG_INFO_mDCV) != 0)
841
0
   {
842
0
      if (white_x != NULL) *white_x = info_ptr->mastering_white_x * 2;
843
0
      if (white_y != NULL) *white_y = info_ptr->mastering_white_y * 2;
844
0
      if (red_x != NULL) *red_x = info_ptr->mastering_red_x * 2;
845
0
      if (red_y != NULL) *red_y = info_ptr->mastering_red_y * 2;
846
0
      if (green_x != NULL) *green_x = info_ptr->mastering_green_x * 2;
847
0
      if (green_y != NULL) *green_y = info_ptr->mastering_green_y * 2;
848
0
      if (blue_x != NULL) *blue_x = info_ptr->mastering_blue_x * 2;
849
0
      if (blue_y != NULL) *blue_y = info_ptr->mastering_blue_y * 2;
850
0
      if (mastering_maxDL != NULL) *mastering_maxDL = info_ptr->mastering_maxDL;
851
0
      if (mastering_minDL != NULL) *mastering_minDL = info_ptr->mastering_minDL;
852
0
      return PNG_INFO_mDCV;
853
0
   }
854
855
0
   return 0;
856
0
}
857
#  endif
858
859
#  ifdef PNG_FLOATING_POINT_SUPPORTED
860
png_uint_32 PNGAPI
861
png_get_mDCV(png_const_structrp png_ptr, png_const_inforp info_ptr,
862
    double *white_x, double *white_y, double *red_x, double *red_y,
863
    double *green_x, double *green_y, double *blue_x, double *blue_y,
864
    double *mastering_maxDL, double *mastering_minDL)
865
0
{
866
0
   png_debug1(1, "in %s retrieval function", "mDCV(float)");
867
868
0
   if (png_ptr != NULL && info_ptr != NULL &&
869
0
       (info_ptr->valid & PNG_INFO_mDCV) != 0)
870
0
   {
871
0
      if (white_x != NULL) *white_x = info_ptr->mastering_white_x * .00002;
872
0
      if (white_y != NULL) *white_y = info_ptr->mastering_white_y * .00002;
873
0
      if (red_x != NULL) *red_x = info_ptr->mastering_red_x * .00002;
874
0
      if (red_y != NULL) *red_y = info_ptr->mastering_red_y * .00002;
875
0
      if (green_x != NULL) *green_x = info_ptr->mastering_green_x * .00002;
876
0
      if (green_y != NULL) *green_y = info_ptr->mastering_green_y * .00002;
877
0
      if (blue_x != NULL) *blue_x = info_ptr->mastering_blue_x * .00002;
878
0
      if (blue_y != NULL) *blue_y = info_ptr->mastering_blue_y * .00002;
879
0
      if (mastering_maxDL != NULL)
880
0
         *mastering_maxDL = info_ptr->mastering_maxDL * .0001;
881
0
      if (mastering_minDL != NULL)
882
0
         *mastering_minDL = info_ptr->mastering_minDL * .0001;
883
0
      return PNG_INFO_mDCV;
884
0
   }
885
886
0
   return 0;
887
0
}
888
#  endif /* FLOATING_POINT */
889
#endif /* mDCV */
890
891
#ifdef PNG_eXIf_SUPPORTED
892
png_uint_32 PNGAPI
893
png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
894
    png_bytep *exif)
895
0
{
896
0
  png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
897
0
  PNG_UNUSED(info_ptr)
898
0
  PNG_UNUSED(exif)
899
0
  return 0;
900
0
}
901
902
png_uint_32 PNGAPI
903
png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
904
    png_uint_32 *num_exif, png_bytep *exif)
905
0
{
906
0
   png_debug1(1, "in %s retrieval function", "eXIf");
907
908
0
   if (png_ptr != NULL && info_ptr != NULL &&
909
0
       (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
910
0
   {
911
0
      *num_exif = info_ptr->num_exif;
912
0
      *exif = info_ptr->exif;
913
0
      return PNG_INFO_eXIf;
914
0
   }
915
916
0
   return 0;
917
0
}
918
#endif
919
920
#ifdef PNG_hIST_SUPPORTED
921
png_uint_32 PNGAPI
922
png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
923
    png_uint_16p *hist)
924
0
{
925
0
   png_debug1(1, "in %s retrieval function", "hIST");
926
927
0
   if (png_ptr != NULL && info_ptr != NULL &&
928
0
       (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
929
0
   {
930
0
      *hist = info_ptr->hist;
931
0
      return PNG_INFO_hIST;
932
0
   }
933
934
0
   return 0;
935
0
}
936
#endif
937
938
png_uint_32 PNGAPI
939
png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
940
    png_uint_32 *width, png_uint_32 *height, int *bit_depth,
941
    int *color_type, int *interlace_type, int *compression_type,
942
    int *filter_type)
943
970
{
944
970
   png_debug1(1, "in %s retrieval function", "IHDR");
945
946
970
   if (png_ptr == NULL || info_ptr == NULL)
947
0
      return 0;
948
949
970
   if (width != NULL)
950
970
       *width = info_ptr->width;
951
952
970
   if (height != NULL)
953
970
       *height = info_ptr->height;
954
955
970
   if (bit_depth != NULL)
956
970
       *bit_depth = info_ptr->bit_depth;
957
958
970
   if (color_type != NULL)
959
970
       *color_type = info_ptr->color_type;
960
961
970
   if (compression_type != NULL)
962
970
      *compression_type = info_ptr->compression_type;
963
964
970
   if (filter_type != NULL)
965
970
      *filter_type = info_ptr->filter_type;
966
967
970
   if (interlace_type != NULL)
968
970
      *interlace_type = info_ptr->interlace_type;
969
970
   /* This is redundant if we can be sure that the info_ptr values were all
971
    * assigned in png_set_IHDR().  We do the check anyhow in case an
972
    * application has ignored our advice not to mess with the members
973
    * of info_ptr directly.
974
    */
975
970
   png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
976
970
       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
977
970
       info_ptr->compression_type, info_ptr->filter_type);
978
979
970
   return 1;
980
970
}
981
982
#ifdef PNG_oFFs_SUPPORTED
983
png_uint_32 PNGAPI
984
png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
985
    png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
986
0
{
987
0
   png_debug1(1, "in %s retrieval function", "oFFs");
988
989
0
   if (png_ptr != NULL && info_ptr != NULL &&
990
0
       (info_ptr->valid & PNG_INFO_oFFs) != 0 &&
991
0
       offset_x != NULL && offset_y != NULL && unit_type != NULL)
992
0
   {
993
0
      *offset_x = info_ptr->x_offset;
994
0
      *offset_y = info_ptr->y_offset;
995
0
      *unit_type = (int)info_ptr->offset_unit_type;
996
0
      return PNG_INFO_oFFs;
997
0
   }
998
999
0
   return 0;
1000
0
}
1001
#endif
1002
1003
#ifdef PNG_pCAL_SUPPORTED
1004
png_uint_32 PNGAPI
1005
png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
1006
    png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
1007
    png_charp *units, png_charpp *params)
1008
0
{
1009
0
   png_debug1(1, "in %s retrieval function", "pCAL");
1010
1011
0
   if (png_ptr != NULL && info_ptr != NULL &&
1012
0
       (info_ptr->valid & PNG_INFO_pCAL) != 0 &&
1013
0
       purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
1014
0
       nparams != NULL && units != NULL && params != NULL)
1015
0
   {
1016
0
      *purpose = info_ptr->pcal_purpose;
1017
0
      *X0 = info_ptr->pcal_X0;
1018
0
      *X1 = info_ptr->pcal_X1;
1019
0
      *type = (int)info_ptr->pcal_type;
1020
0
      *nparams = (int)info_ptr->pcal_nparams;
1021
0
      *units = info_ptr->pcal_units;
1022
0
      *params = info_ptr->pcal_params;
1023
0
      return PNG_INFO_pCAL;
1024
0
   }
1025
1026
0
   return 0;
1027
0
}
1028
#endif
1029
1030
#ifdef PNG_sCAL_SUPPORTED
1031
#  ifdef PNG_FIXED_POINT_SUPPORTED
1032
#    if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
1033
         defined(PNG_FLOATING_POINT_SUPPORTED)
1034
png_uint_32 PNGAPI
1035
png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
1036
    int *unit, png_fixed_point *width, png_fixed_point *height)
1037
0
{
1038
0
   png_debug1(1, "in %s retrieval function", "sCAL");
1039
1040
0
   if (png_ptr != NULL && info_ptr != NULL &&
1041
0
       (info_ptr->valid & PNG_INFO_sCAL) != 0)
1042
0
   {
1043
0
      *unit = info_ptr->scal_unit;
1044
      /*TODO: make this work without FP support; the API is currently eliminated
1045
       * if neither floating point APIs nor internal floating point arithmetic
1046
       * are enabled.
1047
       */
1048
0
      *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
1049
0
      *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
1050
0
          "sCAL height");
1051
0
      return PNG_INFO_sCAL;
1052
0
   }
1053
1054
0
   return 0;
1055
0
}
1056
#    endif /* FLOATING_ARITHMETIC */
1057
#  endif /* FIXED_POINT */
1058
#  ifdef PNG_FLOATING_POINT_SUPPORTED
1059
png_uint_32 PNGAPI
1060
png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
1061
    int *unit, double *width, double *height)
1062
0
{
1063
0
   png_debug1(1, "in %s retrieval function", "sCAL(float)");
1064
1065
0
   if (png_ptr != NULL && info_ptr != NULL &&
1066
0
       (info_ptr->valid & PNG_INFO_sCAL) != 0)
1067
0
   {
1068
0
      *unit = info_ptr->scal_unit;
1069
0
      *width = atof(info_ptr->scal_s_width);
1070
0
      *height = atof(info_ptr->scal_s_height);
1071
0
      return PNG_INFO_sCAL;
1072
0
   }
1073
1074
0
   return 0;
1075
0
}
1076
#  endif /* FLOATING POINT */
1077
png_uint_32 PNGAPI
1078
png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
1079
    int *unit, png_charpp width, png_charpp height)
1080
0
{
1081
0
   png_debug1(1, "in %s retrieval function", "sCAL(str)");
1082
1083
0
   if (png_ptr != NULL && info_ptr != NULL &&
1084
0
       (info_ptr->valid & PNG_INFO_sCAL) != 0)
1085
0
   {
1086
0
      *unit = info_ptr->scal_unit;
1087
0
      *width = info_ptr->scal_s_width;
1088
0
      *height = info_ptr->scal_s_height;
1089
0
      return PNG_INFO_sCAL;
1090
0
   }
1091
1092
0
   return 0;
1093
0
}
1094
#endif /* sCAL */
1095
1096
#ifdef PNG_pHYs_SUPPORTED
1097
png_uint_32 PNGAPI
1098
png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
1099
    png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
1100
0
{
1101
0
   png_uint_32 retval = 0;
1102
1103
0
   png_debug1(1, "in %s retrieval function", "pHYs");
1104
1105
0
   if (png_ptr != NULL && info_ptr != NULL &&
1106
0
       (info_ptr->valid & PNG_INFO_pHYs) != 0)
1107
0
   {
1108
0
      if (res_x != NULL)
1109
0
      {
1110
0
         *res_x = info_ptr->x_pixels_per_unit;
1111
0
         retval |= PNG_INFO_pHYs;
1112
0
      }
1113
1114
0
      if (res_y != NULL)
1115
0
      {
1116
0
         *res_y = info_ptr->y_pixels_per_unit;
1117
0
         retval |= PNG_INFO_pHYs;
1118
0
      }
1119
1120
0
      if (unit_type != NULL)
1121
0
      {
1122
0
         *unit_type = (int)info_ptr->phys_unit_type;
1123
0
         retval |= PNG_INFO_pHYs;
1124
0
      }
1125
0
   }
1126
1127
0
   return retval;
1128
0
}
1129
#endif /* pHYs */
1130
1131
png_uint_32 PNGAPI
1132
png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
1133
    png_colorp *palette, int *num_palette)
1134
0
{
1135
0
   png_debug1(1, "in %s retrieval function", "PLTE");
1136
1137
0
   if (png_ptr != NULL && info_ptr != NULL &&
1138
0
       (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)
1139
0
   {
1140
0
      *palette = info_ptr->palette;
1141
0
      *num_palette = info_ptr->num_palette;
1142
0
      png_debug1(3, "num_palette = %d", *num_palette);
1143
0
      return PNG_INFO_PLTE;
1144
0
   }
1145
1146
0
   return 0;
1147
0
}
1148
1149
#ifdef PNG_sBIT_SUPPORTED
1150
png_uint_32 PNGAPI
1151
png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
1152
    png_color_8p *sig_bit)
1153
0
{
1154
0
   png_debug1(1, "in %s retrieval function", "sBIT");
1155
1156
0
   if (png_ptr != NULL && info_ptr != NULL &&
1157
0
       (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
1158
0
   {
1159
0
      *sig_bit = &(info_ptr->sig_bit);
1160
0
      return PNG_INFO_sBIT;
1161
0
   }
1162
1163
0
   return 0;
1164
0
}
1165
#endif
1166
1167
#ifdef PNG_TEXT_SUPPORTED
1168
int PNGAPI
1169
png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
1170
    png_textp *text_ptr, int *num_text)
1171
0
{
1172
0
   if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
1173
0
   {
1174
0
      png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx",
1175
0
         (unsigned long)png_ptr->chunk_name);
1176
1177
0
      if (text_ptr != NULL)
1178
0
         *text_ptr = info_ptr->text;
1179
1180
0
      if (num_text != NULL)
1181
0
         *num_text = info_ptr->num_text;
1182
1183
0
      return info_ptr->num_text;
1184
0
   }
1185
1186
0
   if (num_text != NULL)
1187
0
      *num_text = 0;
1188
1189
0
   return 0;
1190
0
}
1191
#endif
1192
1193
#ifdef PNG_tIME_SUPPORTED
1194
png_uint_32 PNGAPI
1195
png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
1196
    png_timep *mod_time)
1197
0
{
1198
0
   png_debug1(1, "in %s retrieval function", "tIME");
1199
1200
0
   if (png_ptr != NULL && info_ptr != NULL &&
1201
0
       (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
1202
0
   {
1203
0
      *mod_time = &(info_ptr->mod_time);
1204
0
      return PNG_INFO_tIME;
1205
0
   }
1206
1207
0
   return 0;
1208
0
}
1209
#endif
1210
1211
#ifdef PNG_tRNS_SUPPORTED
1212
png_uint_32 PNGAPI
1213
png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
1214
    png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
1215
0
{
1216
0
   png_uint_32 retval = 0;
1217
1218
0
   png_debug1(1, "in %s retrieval function", "tRNS");
1219
1220
0
   if (png_ptr != NULL && info_ptr != NULL &&
1221
0
       (info_ptr->valid & PNG_INFO_tRNS) != 0)
1222
0
   {
1223
0
      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1224
0
      {
1225
0
         if (trans_alpha != NULL)
1226
0
         {
1227
0
            *trans_alpha = info_ptr->trans_alpha;
1228
0
            retval |= PNG_INFO_tRNS;
1229
0
         }
1230
1231
0
         if (trans_color != NULL)
1232
0
            *trans_color = &(info_ptr->trans_color);
1233
0
      }
1234
1235
0
      else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
1236
0
      {
1237
0
         if (trans_color != NULL)
1238
0
         {
1239
0
            *trans_color = &(info_ptr->trans_color);
1240
0
            retval |= PNG_INFO_tRNS;
1241
0
         }
1242
1243
0
         if (trans_alpha != NULL)
1244
0
            *trans_alpha = NULL;
1245
0
      }
1246
1247
0
      if (num_trans != NULL)
1248
0
      {
1249
0
         *num_trans = info_ptr->num_trans;
1250
0
         retval |= PNG_INFO_tRNS;
1251
0
      }
1252
0
   }
1253
1254
0
   return retval;
1255
0
}
1256
#endif
1257
1258
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1259
int PNGAPI
1260
png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
1261
    png_unknown_chunkpp unknowns)
1262
0
{
1263
0
   if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
1264
0
   {
1265
0
      *unknowns = info_ptr->unknown_chunks;
1266
0
      return info_ptr->unknown_chunks_num;
1267
0
   }
1268
1269
0
   return 0;
1270
0
}
1271
#endif
1272
1273
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1274
png_byte PNGAPI
1275
png_get_rgb_to_gray_status(png_const_structrp png_ptr)
1276
0
{
1277
0
   return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
1278
0
}
1279
#endif
1280
1281
#ifdef PNG_USER_CHUNKS_SUPPORTED
1282
png_voidp PNGAPI
1283
png_get_user_chunk_ptr(png_const_structrp png_ptr)
1284
0
{
1285
0
   return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
1286
0
}
1287
#endif
1288
1289
size_t PNGAPI
1290
png_get_compression_buffer_size(png_const_structrp png_ptr)
1291
0
{
1292
0
   if (png_ptr == NULL)
1293
0
      return 0;
1294
1295
#ifdef PNG_WRITE_SUPPORTED
1296
   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1297
#endif
1298
0
   {
1299
0
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1300
0
      return png_ptr->IDAT_read_size;
1301
#else
1302
      return PNG_IDAT_READ_SIZE;
1303
#endif
1304
0
   }
1305
1306
#ifdef PNG_WRITE_SUPPORTED
1307
   else
1308
      return png_ptr->zbuffer_size;
1309
#endif
1310
0
}
1311
1312
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1313
/* These functions were added to libpng 1.2.6 and were enabled
1314
 * by default in libpng-1.4.0 */
1315
png_uint_32 PNGAPI
1316
png_get_user_width_max(png_const_structrp png_ptr)
1317
0
{
1318
0
   return (png_ptr ? png_ptr->user_width_max : 0);
1319
0
}
1320
1321
png_uint_32 PNGAPI
1322
png_get_user_height_max(png_const_structrp png_ptr)
1323
0
{
1324
0
   return (png_ptr ? png_ptr->user_height_max : 0);
1325
0
}
1326
1327
/* This function was added to libpng 1.4.0 */
1328
png_uint_32 PNGAPI
1329
png_get_chunk_cache_max(png_const_structrp png_ptr)
1330
0
{
1331
0
   return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
1332
0
}
1333
1334
/* This function was added to libpng 1.4.1 */
1335
png_alloc_size_t PNGAPI
1336
png_get_chunk_malloc_max(png_const_structrp png_ptr)
1337
0
{
1338
0
   return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
1339
0
}
1340
#endif /* SET_USER_LIMITS */
1341
1342
/* These functions were added to libpng 1.4.0 */
1343
#ifdef PNG_IO_STATE_SUPPORTED
1344
png_uint_32 PNGAPI
1345
png_get_io_state(png_const_structrp png_ptr)
1346
0
{
1347
0
   return png_ptr->io_state;
1348
0
}
1349
1350
png_uint_32 PNGAPI
1351
png_get_io_chunk_type(png_const_structrp png_ptr)
1352
0
{
1353
0
   return png_ptr->chunk_name;
1354
0
}
1355
#endif /* IO_STATE */
1356
1357
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
1358
#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
1359
int PNGAPI
1360
png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
1361
0
{
1362
0
   if (png_ptr != NULL && info_ptr != NULL)
1363
0
      return png_ptr->num_palette_max;
1364
1365
0
   return -1;
1366
0
}
1367
#  endif
1368
#endif
1369
1370
#endif /* READ || WRITE */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pnglibconf.h.html b/part1/report/w_corpus/src/libpng/pnglibconf.h.html new file mode 100644 index 0000000..7f3306e --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pnglibconf.h.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pnglibconf.h
Line
Count
Source (jump to first uncovered line)
1
/* pnglibconf.h - library build configuration */
2
3
/* libpng version 1.6.48 */
4
5
/* Copyright (c) 2018-2025 Cosmin Truta */
6
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
7
8
/* This code is released under the libpng license. */
9
/* For conditions of distribution and use, see the disclaimer */
10
/* and license in png.h */
11
12
/* pnglibconf.h */
13
/* Machine generated file: DO NOT EDIT */
14
/* Derived from: scripts/pnglibconf.dfa */
15
#ifndef PNGLCONF_H
16
#define PNGLCONF_H
17
/* options */
18
#define PNG_16BIT_SUPPORTED
19
#define PNG_ALIGNED_MEMORY_SUPPORTED
20
/*#undef PNG_ARM_NEON_API_SUPPORTED*/
21
/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
22
#define PNG_BENIGN_ERRORS_SUPPORTED
23
#define PNG_BENIGN_READ_ERRORS_SUPPORTED
24
/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
25
#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
26
#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
27
#define PNG_COLORSPACE_SUPPORTED
28
/*#undef PNG_CONSOLE_IO_SUPPORTED*/
29
/*#undef PNG_CONVERT_tIME_SUPPORTED*/
30
/*#undef PNG_DISABLE_ADLER32_CHECK_SUPPORTED*/
31
#define PNG_EASY_ACCESS_SUPPORTED
32
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
33
#define PNG_ERROR_TEXT_SUPPORTED
34
#define PNG_FIXED_POINT_SUPPORTED
35
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
36
#define PNG_FLOATING_POINT_SUPPORTED
37
#define PNG_FORMAT_AFIRST_SUPPORTED
38
#define PNG_FORMAT_BGR_SUPPORTED
39
#define PNG_GAMMA_SUPPORTED
40
#define PNG_GET_PALETTE_MAX_SUPPORTED
41
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
42
#define PNG_INCH_CONVERSIONS_SUPPORTED
43
#define PNG_INFO_IMAGE_SUPPORTED
44
#define PNG_IO_STATE_SUPPORTED
45
/*#undef PNG_MIPS_MMI_API_SUPPORTED*/
46
/*#undef PNG_MIPS_MMI_CHECK_SUPPORTED*/
47
/*#undef PNG_MIPS_MSA_API_SUPPORTED*/
48
/*#undef PNG_MIPS_MSA_CHECK_SUPPORTED*/
49
#define PNG_MNG_FEATURES_SUPPORTED
50
#define PNG_POINTER_INDEXING_SUPPORTED
51
/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
52
/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
53
#define PNG_PROGRESSIVE_READ_SUPPORTED
54
#define PNG_READ_16BIT_SUPPORTED
55
#define PNG_READ_ALPHA_MODE_SUPPORTED
56
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
57
#define PNG_READ_BACKGROUND_SUPPORTED
58
#define PNG_READ_BGR_SUPPORTED
59
#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
60
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
61
#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
62
#define PNG_READ_EXPAND_16_SUPPORTED
63
#define PNG_READ_EXPAND_SUPPORTED
64
#define PNG_READ_FILLER_SUPPORTED
65
#define PNG_READ_GAMMA_SUPPORTED
66
#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
67
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
68
#define PNG_READ_INTERLACING_SUPPORTED
69
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
70
#define PNG_READ_INVERT_ALPHA_SUPPORTED
71
#define PNG_READ_INVERT_SUPPORTED
72
#define PNG_READ_OPT_PLTE_SUPPORTED
73
#define PNG_READ_PACKSWAP_SUPPORTED
74
#define PNG_READ_PACK_SUPPORTED
75
#define PNG_READ_QUANTIZE_SUPPORTED
76
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
77
#define PNG_READ_SCALE_16_TO_8_SUPPORTED
78
#define PNG_READ_SHIFT_SUPPORTED
79
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
80
#define PNG_READ_STRIP_ALPHA_SUPPORTED
81
#define PNG_READ_SUPPORTED
82
#define PNG_READ_SWAP_ALPHA_SUPPORTED
83
#define PNG_READ_SWAP_SUPPORTED
84
#define PNG_READ_TEXT_SUPPORTED
85
#define PNG_READ_TRANSFORMS_SUPPORTED
86
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
87
#define PNG_READ_USER_CHUNKS_SUPPORTED
88
#define PNG_READ_USER_TRANSFORM_SUPPORTED
89
#define PNG_READ_bKGD_SUPPORTED
90
#define PNG_READ_cHRM_SUPPORTED
91
#define PNG_READ_cICP_SUPPORTED
92
#define PNG_READ_cLLI_SUPPORTED
93
#define PNG_READ_eXIf_SUPPORTED
94
#define PNG_READ_gAMA_SUPPORTED
95
#define PNG_READ_hIST_SUPPORTED
96
#define PNG_READ_iCCP_SUPPORTED
97
#define PNG_READ_iTXt_SUPPORTED
98
#define PNG_READ_mDCV_SUPPORTED
99
#define PNG_READ_oFFs_SUPPORTED
100
#define PNG_READ_pCAL_SUPPORTED
101
#define PNG_READ_pHYs_SUPPORTED
102
#define PNG_READ_sBIT_SUPPORTED
103
#define PNG_READ_sCAL_SUPPORTED
104
#define PNG_READ_sPLT_SUPPORTED
105
#define PNG_READ_sRGB_SUPPORTED
106
#define PNG_READ_tEXt_SUPPORTED
107
#define PNG_READ_tIME_SUPPORTED
108
#define PNG_READ_tRNS_SUPPORTED
109
#define PNG_READ_zTXt_SUPPORTED
110
/*#undef PNG_SAVE_INT_32_SUPPORTED*/
111
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
112
#define PNG_SEQUENTIAL_READ_SUPPORTED
113
#define PNG_SETJMP_SUPPORTED
114
#define PNG_SET_OPTION_SUPPORTED
115
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
116
#define PNG_SET_USER_LIMITS_SUPPORTED
117
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
118
#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
119
#define PNG_SIMPLIFIED_READ_SUPPORTED
120
/*#undef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED*/
121
/*#undef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED*/
122
/*#undef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED*/
123
/*#undef PNG_SIMPLIFIED_WRITE_SUPPORTED*/
124
/*#undef PNG_STDIO_SUPPORTED*/
125
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
126
#define PNG_TEXT_SUPPORTED
127
#define PNG_TIME_RFC1123_SUPPORTED
128
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
129
#define PNG_USER_CHUNKS_SUPPORTED
130
#define PNG_USER_LIMITS_SUPPORTED
131
#define PNG_USER_MEM_SUPPORTED
132
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
133
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
134
#define PNG_WARNINGS_SUPPORTED
135
/*#undef PNG_WRITE_16BIT_SUPPORTED*/
136
/*#undef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED*/
137
/*#undef PNG_WRITE_BGR_SUPPORTED*/
138
/*#undef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED*/
139
/*#undef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED*/
140
/*#undef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED*/
141
/*#undef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED*/
142
/*#undef PNG_WRITE_FILLER_SUPPORTED*/
143
/*#undef PNG_WRITE_FILTER_SUPPORTED*/
144
/*#undef PNG_WRITE_FLUSH_SUPPORTED*/
145
/*#undef PNG_WRITE_GET_PALETTE_MAX_SUPPORTED*/
146
/*#undef PNG_WRITE_INTERLACING_SUPPORTED*/
147
/*#undef PNG_WRITE_INT_FUNCTIONS_SUPPORTED*/
148
/*#undef PNG_WRITE_INVERT_ALPHA_SUPPORTED*/
149
/*#undef PNG_WRITE_INVERT_SUPPORTED*/
150
/*#undef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED*/
151
/*#undef PNG_WRITE_PACKSWAP_SUPPORTED*/
152
/*#undef PNG_WRITE_PACK_SUPPORTED*/
153
/*#undef PNG_WRITE_SHIFT_SUPPORTED*/
154
/*#undef PNG_WRITE_SUPPORTED*/
155
/*#undef PNG_WRITE_SWAP_ALPHA_SUPPORTED*/
156
/*#undef PNG_WRITE_SWAP_SUPPORTED*/
157
/*#undef PNG_WRITE_TEXT_SUPPORTED*/
158
/*#undef PNG_WRITE_TRANSFORMS_SUPPORTED*/
159
/*#undef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED*/
160
/*#undef PNG_WRITE_USER_TRANSFORM_SUPPORTED*/
161
/*#undef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED*/
162
/*#undef PNG_WRITE_bKGD_SUPPORTED*/
163
/*#undef PNG_WRITE_cHRM_SUPPORTED*/
164
/*#undef PNG_WRITE_cICP_SUPPORTED*/
165
/*#undef PNG_WRITE_cLLI_SUPPORTED*/
166
/*#undef PNG_WRITE_eXIf_SUPPORTED*/
167
/*#undef PNG_WRITE_gAMA_SUPPORTED*/
168
/*#undef PNG_WRITE_hIST_SUPPORTED*/
169
/*#undef PNG_WRITE_iCCP_SUPPORTED*/
170
/*#undef PNG_WRITE_iTXt_SUPPORTED*/
171
/*#undef PNG_WRITE_mDCV_SUPPORTED*/
172
/*#undef PNG_WRITE_oFFs_SUPPORTED*/
173
/*#undef PNG_WRITE_pCAL_SUPPORTED*/
174
/*#undef PNG_WRITE_pHYs_SUPPORTED*/
175
/*#undef PNG_WRITE_sBIT_SUPPORTED*/
176
/*#undef PNG_WRITE_sCAL_SUPPORTED*/
177
/*#undef PNG_WRITE_sPLT_SUPPORTED*/
178
/*#undef PNG_WRITE_sRGB_SUPPORTED*/
179
/*#undef PNG_WRITE_tEXt_SUPPORTED*/
180
/*#undef PNG_WRITE_tIME_SUPPORTED*/
181
/*#undef PNG_WRITE_tRNS_SUPPORTED*/
182
/*#undef PNG_WRITE_zTXt_SUPPORTED*/
183
#define PNG_bKGD_SUPPORTED
184
#define PNG_cHRM_SUPPORTED
185
#define PNG_cICP_SUPPORTED
186
#define PNG_cLLI_SUPPORTED
187
#define PNG_eXIf_SUPPORTED
188
#define PNG_gAMA_SUPPORTED
189
#define PNG_hIST_SUPPORTED
190
#define PNG_iCCP_SUPPORTED
191
#define PNG_iTXt_SUPPORTED
192
#define PNG_mDCV_SUPPORTED
193
#define PNG_oFFs_SUPPORTED
194
#define PNG_pCAL_SUPPORTED
195
#define PNG_pHYs_SUPPORTED
196
#define PNG_sBIT_SUPPORTED
197
#define PNG_sCAL_SUPPORTED
198
#define PNG_sPLT_SUPPORTED
199
#define PNG_sRGB_SUPPORTED
200
#define PNG_tEXt_SUPPORTED
201
#define PNG_tIME_SUPPORTED
202
#define PNG_tRNS_SUPPORTED
203
#define PNG_zTXt_SUPPORTED
204
/* end of options */
205
/* settings */
206
#define PNG_API_RULE 0
207
#define PNG_DEFAULT_READ_MACROS 1
208
5.67k
#define PNG_GAMMA_THRESHOLD_FIXED 5000
209
2.22k
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
210
#define PNG_INFLATE_BUF_SIZE 1024
211
#define PNG_LINKAGE_API extern
212
#define PNG_LINKAGE_CALLBACK extern
213
#define PNG_LINKAGE_DATA extern
214
#define PNG_LINKAGE_FUNCTION extern
215
78
#define PNG_MAX_GAMMA_8 11
216
#define PNG_PREFIX OSS_FUZZ_
217
0
#define PNG_QUANTIZE_BLUE_BITS 5
218
0
#define PNG_QUANTIZE_GREEN_BITS 5
219
0
#define PNG_QUANTIZE_RED_BITS 5
220
#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
221
#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
222
2.22k
#define PNG_USER_CHUNK_CACHE_MAX 1000
223
2.22k
#define PNG_USER_CHUNK_MALLOC_MAX 8000000
224
2.22k
#define PNG_USER_HEIGHT_MAX 1000000
225
2.22k
#define PNG_USER_WIDTH_MAX 1000000
226
2.22k
#define PNG_ZBUF_SIZE 8192
227
#define PNG_ZLIB_VERNUM 0x12b0
228
#define PNG_Z_DEFAULT_COMPRESSION (-1)
229
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
230
#define PNG_Z_DEFAULT_STRATEGY 1
231
0
#define PNG_sCAL_PRECISION 5
232
#define PNG_sRGB_PROFILE_CHECKS 2
233
/* end of settings */
234
#define png_access_version_number OSS_FUZZ_png_access_version_number
235
303
#define png_benign_error OSS_FUZZ_png_benign_error
236
#define png_build_grayscale_palette OSS_FUZZ_png_build_grayscale_palette
237
446
#define png_calloc OSS_FUZZ_png_calloc
238
19.2k
#define png_chunk_benign_error OSS_FUZZ_png_chunk_benign_error
239
417
#define png_chunk_error OSS_FUZZ_png_chunk_error
240
23.1k
#define png_chunk_warning OSS_FUZZ_png_chunk_warning
241
#define png_convert_to_rfc1123 OSS_FUZZ_png_convert_to_rfc1123
242
0
#define png_convert_to_rfc1123_buffer OSS_FUZZ_png_convert_to_rfc1123_buffer
243
4.02k
#define png_create_info_struct OSS_FUZZ_png_create_info_struct
244
2.22k
#define png_create_read_struct OSS_FUZZ_png_create_read_struct
245
2.22k
#define png_create_read_struct_2 OSS_FUZZ_png_create_read_struct_2
246
#define png_create_write_struct OSS_FUZZ_png_create_write_struct
247
#define png_create_write_struct_2 OSS_FUZZ_png_create_write_struct_2
248
#define png_data_freer OSS_FUZZ_png_data_freer
249
4.45k
#define png_destroy_info_struct OSS_FUZZ_png_destroy_info_struct
250
4.02k
#define png_destroy_read_struct OSS_FUZZ_png_destroy_read_struct
251
#define png_destroy_write_struct OSS_FUZZ_png_destroy_write_struct
252
2.64k
#define png_error OSS_FUZZ_png_error
253
53.6k
#define png_free OSS_FUZZ_png_free
254
5.01k
#define png_free_data OSS_FUZZ_png_free_data
255
5.80k
#define png_free_default OSS_FUZZ_png_free_default
256
426
#define png_get_IHDR OSS_FUZZ_png_get_IHDR
257
#define png_get_PLTE OSS_FUZZ_png_get_PLTE
258
#define png_get_bKGD OSS_FUZZ_png_get_bKGD
259
#define png_get_bit_depth OSS_FUZZ_png_get_bit_depth
260
#define png_get_cHRM OSS_FUZZ_png_get_cHRM
261
#define png_get_cHRM_XYZ OSS_FUZZ_png_get_cHRM_XYZ
262
#define png_get_cHRM_XYZ_fixed OSS_FUZZ_png_get_cHRM_XYZ_fixed
263
#define png_get_cHRM_fixed OSS_FUZZ_png_get_cHRM_fixed
264
#define png_get_cICP OSS_FUZZ_png_get_cICP
265
#define png_get_cLLI OSS_FUZZ_png_get_cLLI
266
#define png_get_cLLI_fixed OSS_FUZZ_png_get_cLLI_fixed
267
0
#define png_get_channels OSS_FUZZ_png_get_channels
268
#define png_get_chunk_cache_max OSS_FUZZ_png_get_chunk_cache_max
269
#define png_get_chunk_malloc_max OSS_FUZZ_png_get_chunk_malloc_max
270
#define png_get_color_type OSS_FUZZ_png_get_color_type
271
#define png_get_compression_buffer_size OSS_FUZZ_png_get_compression_buffer_size
272
#define png_get_compression_type OSS_FUZZ_png_get_compression_type
273
#define png_get_copyright OSS_FUZZ_png_get_copyright
274
#define png_get_current_pass_number OSS_FUZZ_png_get_current_pass_number
275
#define png_get_current_row_number OSS_FUZZ_png_get_current_row_number
276
#define png_get_eXIf OSS_FUZZ_png_get_eXIf
277
#define png_get_eXIf_1 OSS_FUZZ_png_get_eXIf_1
278
#define png_get_error_ptr OSS_FUZZ_png_get_error_ptr
279
#define png_get_filter_type OSS_FUZZ_png_get_filter_type
280
#define png_get_gAMA OSS_FUZZ_png_get_gAMA
281
#define png_get_gAMA_fixed OSS_FUZZ_png_get_gAMA_fixed
282
#define png_get_hIST OSS_FUZZ_png_get_hIST
283
0
#define png_get_header_ver OSS_FUZZ_png_get_header_ver
284
#define png_get_header_version OSS_FUZZ_png_get_header_version
285
#define png_get_iCCP OSS_FUZZ_png_get_iCCP
286
#define png_get_image_height OSS_FUZZ_png_get_image_height
287
#define png_get_image_width OSS_FUZZ_png_get_image_width
288
3.30k
#define png_get_int_32 OSS_FUZZ_png_get_int_32
289
#define png_get_interlace_type OSS_FUZZ_png_get_interlace_type
290
#define png_get_io_chunk_type OSS_FUZZ_png_get_io_chunk_type
291
91.1k
#define png_get_io_ptr OSS_FUZZ_png_get_io_ptr
292
#define png_get_io_state OSS_FUZZ_png_get_io_state
293
#define png_get_libpng_ver OSS_FUZZ_png_get_libpng_ver
294
#define png_get_mDCV OSS_FUZZ_png_get_mDCV
295
#define png_get_mDCV_fixed OSS_FUZZ_png_get_mDCV_fixed
296
#define png_get_mem_ptr OSS_FUZZ_png_get_mem_ptr
297
#define png_get_oFFs OSS_FUZZ_png_get_oFFs
298
#define png_get_pCAL OSS_FUZZ_png_get_pCAL
299
#define png_get_pHYs OSS_FUZZ_png_get_pHYs
300
#define png_get_pHYs_dpi OSS_FUZZ_png_get_pHYs_dpi
301
#define png_get_palette_max OSS_FUZZ_png_get_palette_max
302
#define png_get_pixel_aspect_ratio OSS_FUZZ_png_get_pixel_aspect_ratio
303
#define png_get_pixel_aspect_ratio_fixed OSS_FUZZ_png_get_pixel_aspect_ratio_fixed
304
#define png_get_pixels_per_inch OSS_FUZZ_png_get_pixels_per_inch
305
0
#define png_get_pixels_per_meter OSS_FUZZ_png_get_pixels_per_meter
306
#define png_get_progressive_ptr OSS_FUZZ_png_get_progressive_ptr
307
#define png_get_rgb_to_gray_status OSS_FUZZ_png_get_rgb_to_gray_status
308
425
#define png_get_rowbytes OSS_FUZZ_png_get_rowbytes
309
#define png_get_rows OSS_FUZZ_png_get_rows
310
#define png_get_sBIT OSS_FUZZ_png_get_sBIT
311
#define png_get_sCAL OSS_FUZZ_png_get_sCAL
312
#define png_get_sCAL_fixed OSS_FUZZ_png_get_sCAL_fixed
313
#define png_get_sCAL_s OSS_FUZZ_png_get_sCAL_s
314
#define png_get_sPLT OSS_FUZZ_png_get_sPLT
315
#define png_get_sRGB OSS_FUZZ_png_get_sRGB
316
#define png_get_signature OSS_FUZZ_png_get_signature
317
#define png_get_tIME OSS_FUZZ_png_get_tIME
318
#define png_get_tRNS OSS_FUZZ_png_get_tRNS
319
#define png_get_text OSS_FUZZ_png_get_text
320
18.7k
#define png_get_uint_16 OSS_FUZZ_png_get_uint_16
321
42.5k
#define png_get_uint_31 OSS_FUZZ_png_get_uint_31
322
68.5k
#define png_get_uint_32 OSS_FUZZ_png_get_uint_32
323
#define png_get_unknown_chunks OSS_FUZZ_png_get_unknown_chunks
324
#define png_get_user_chunk_ptr OSS_FUZZ_png_get_user_chunk_ptr
325
#define png_get_user_height_max OSS_FUZZ_png_get_user_height_max
326
#define png_get_user_transform_ptr OSS_FUZZ_png_get_user_transform_ptr
327
#define png_get_user_width_max OSS_FUZZ_png_get_user_width_max
328
#define png_get_valid OSS_FUZZ_png_get_valid
329
#define png_get_x_offset_inches OSS_FUZZ_png_get_x_offset_inches
330
#define png_get_x_offset_inches_fixed OSS_FUZZ_png_get_x_offset_inches_fixed
331
0
#define png_get_x_offset_microns OSS_FUZZ_png_get_x_offset_microns
332
#define png_get_x_offset_pixels OSS_FUZZ_png_get_x_offset_pixels
333
#define png_get_x_pixels_per_inch OSS_FUZZ_png_get_x_pixels_per_inch
334
0
#define png_get_x_pixels_per_meter OSS_FUZZ_png_get_x_pixels_per_meter
335
#define png_get_y_offset_inches OSS_FUZZ_png_get_y_offset_inches
336
#define png_get_y_offset_inches_fixed OSS_FUZZ_png_get_y_offset_inches_fixed
337
0
#define png_get_y_offset_microns OSS_FUZZ_png_get_y_offset_microns
338
#define png_get_y_offset_pixels OSS_FUZZ_png_get_y_offset_pixels
339
#define png_get_y_pixels_per_inch OSS_FUZZ_png_get_y_pixels_per_inch
340
0
#define png_get_y_pixels_per_meter OSS_FUZZ_png_get_y_pixels_per_meter
341
35.2k
#define png_handle_as_unknown OSS_FUZZ_png_handle_as_unknown
342
425
#define png_image_begin_read_from_memory OSS_FUZZ_png_image_begin_read_from_memory
343
419
#define png_image_finish_read OSS_FUZZ_png_image_finish_read
344
530
#define png_image_free OSS_FUZZ_png_image_free
345
#define png_info_init_3 OSS_FUZZ_png_info_init_3
346
2.74k
#define png_longjmp OSS_FUZZ_png_longjmp
347
4.05k
#define png_malloc OSS_FUZZ_png_malloc
348
#define png_malloc_default OSS_FUZZ_png_malloc_default
349
3.32k
#define png_malloc_warn OSS_FUZZ_png_malloc_warn
350
#define png_permit_mng_features OSS_FUZZ_png_permit_mng_features
351
#define png_process_data OSS_FUZZ_png_process_data
352
#define png_process_data_pause OSS_FUZZ_png_process_data_pause
353
#define png_process_data_skip OSS_FUZZ_png_process_data_skip
354
#define png_progressive_combine_row OSS_FUZZ_png_progressive_combine_row
355
425
#define png_read_end OSS_FUZZ_png_read_end
356
0
#define png_read_image OSS_FUZZ_png_read_image
357
1.39k
#define png_read_info OSS_FUZZ_png_read_info
358
#define png_read_png OSS_FUZZ_png_read_png
359
495k
#define png_read_row OSS_FUZZ_png_read_row
360
#define png_read_rows OSS_FUZZ_png_read_rows
361
844
#define png_read_update_info OSS_FUZZ_png_read_update_info
362
#define png_reset_zstream OSS_FUZZ_png_reset_zstream
363
2.20k
#define png_set_IHDR OSS_FUZZ_png_set_IHDR
364
376
#define png_set_PLTE OSS_FUZZ_png_set_PLTE
365
179
#define png_set_add_alpha OSS_FUZZ_png_set_add_alpha
366
#define png_set_alpha_mode OSS_FUZZ_png_set_alpha_mode
367
838
#define png_set_alpha_mode_fixed OSS_FUZZ_png_set_alpha_mode_fixed
368
262
#define png_set_bKGD OSS_FUZZ_png_set_bKGD
369
#define png_set_background OSS_FUZZ_png_set_background
370
0
#define png_set_background_fixed OSS_FUZZ_png_set_background_fixed
371
425
#define png_set_benign_errors OSS_FUZZ_png_set_benign_errors
372
0
#define png_set_bgr OSS_FUZZ_png_set_bgr
373
#define png_set_cHRM OSS_FUZZ_png_set_cHRM
374
#define png_set_cHRM_XYZ OSS_FUZZ_png_set_cHRM_XYZ
375
0
#define png_set_cHRM_XYZ_fixed OSS_FUZZ_png_set_cHRM_XYZ_fixed
376
589
#define png_set_cHRM_fixed OSS_FUZZ_png_set_cHRM_fixed
377
132
#define png_set_cICP OSS_FUZZ_png_set_cICP
378
#define png_set_cLLI OSS_FUZZ_png_set_cLLI
379
220
#define png_set_cLLI_fixed OSS_FUZZ_png_set_cLLI_fixed
380
#define png_set_check_for_invalid_index OSS_FUZZ_png_set_check_for_invalid_index
381
#define png_set_chunk_cache_max OSS_FUZZ_png_set_chunk_cache_max
382
#define png_set_chunk_malloc_max OSS_FUZZ_png_set_chunk_malloc_max
383
#define png_set_compression_buffer_size OSS_FUZZ_png_set_compression_buffer_size
384
1.80k
#define png_set_crc_action OSS_FUZZ_png_set_crc_action
385
#define png_set_eXIf OSS_FUZZ_png_set_eXIf
386
28
#define png_set_eXIf_1 OSS_FUZZ_png_set_eXIf_1
387
2.22k
#define png_set_error_fn OSS_FUZZ_png_set_error_fn
388
844
#define png_set_expand OSS_FUZZ_png_set_expand
389
0
#define png_set_expand_16 OSS_FUZZ_png_set_expand_16
390
1.17k
#define png_set_expand_gray_1_2_4_to_8 OSS_FUZZ_png_set_expand_gray_1_2_4_to_8
391
179
#define png_set_filler OSS_FUZZ_png_set_filler
392
#define png_set_gAMA OSS_FUZZ_png_set_gAMA
393
775
#define png_set_gAMA_fixed OSS_FUZZ_png_set_gAMA_fixed
394
#define png_set_gamma OSS_FUZZ_png_set_gamma
395
0
#define png_set_gamma_fixed OSS_FUZZ_png_set_gamma_fixed
396
635
#define png_set_gray_to_rgb OSS_FUZZ_png_set_gray_to_rgb
397
1
#define png_set_hIST OSS_FUZZ_png_set_hIST
398
#define png_set_iCCP OSS_FUZZ_png_set_iCCP
399
844
#define png_set_interlace_handling OSS_FUZZ_png_set_interlace_handling
400
#define png_set_invalid OSS_FUZZ_png_set_invalid
401
0
#define png_set_invert_alpha OSS_FUZZ_png_set_invert_alpha
402
0
#define png_set_invert_mono OSS_FUZZ_png_set_invert_mono
403
838
#define png_set_keep_unknown_chunks OSS_FUZZ_png_set_keep_unknown_chunks
404
#define png_set_longjmp_fn OSS_FUZZ_png_set_longjmp_fn
405
#define png_set_mDCV OSS_FUZZ_png_set_mDCV
406
154
#define png_set_mDCV_fixed OSS_FUZZ_png_set_mDCV_fixed
407
4.02k
#define png_set_mem_fn OSS_FUZZ_png_set_mem_fn
408
171
#define png_set_oFFs OSS_FUZZ_png_set_oFFs
409
#define png_set_option OSS_FUZZ_png_set_option
410
122
#define png_set_pCAL OSS_FUZZ_png_set_pCAL
411
59
#define png_set_pHYs OSS_FUZZ_png_set_pHYs
412
425
#define png_set_packing OSS_FUZZ_png_set_packing
413
0
#define png_set_packswap OSS_FUZZ_png_set_packswap
414
#define png_set_palette_to_rgb OSS_FUZZ_png_set_palette_to_rgb
415
#define png_set_progressive_read_fn OSS_FUZZ_png_set_progressive_read_fn
416
#define png_set_quantize OSS_FUZZ_png_set_quantize
417
4.02k
#define png_set_read_fn OSS_FUZZ_png_set_read_fn
418
#define png_set_read_status_fn OSS_FUZZ_png_set_read_status_fn
419
#define png_set_read_user_chunk_fn OSS_FUZZ_png_set_read_user_chunk_fn
420
#define png_set_read_user_transform_fn OSS_FUZZ_png_set_read_user_transform_fn
421
#define png_set_rgb_to_gray OSS_FUZZ_png_set_rgb_to_gray
422
0
#define png_set_rgb_to_gray_fixed OSS_FUZZ_png_set_rgb_to_gray_fixed
423
#define png_set_rows OSS_FUZZ_png_set_rows
424
187
#define png_set_sBIT OSS_FUZZ_png_set_sBIT
425
#define png_set_sCAL OSS_FUZZ_png_set_sCAL
426
#define png_set_sCAL_fixed OSS_FUZZ_png_set_sCAL_fixed
427
89
#define png_set_sCAL_s OSS_FUZZ_png_set_sCAL_s
428
409
#define png_set_sPLT OSS_FUZZ_png_set_sPLT
429
226
#define png_set_sRGB OSS_FUZZ_png_set_sRGB
430
#define png_set_sRGB_gAMA_and_cHRM OSS_FUZZ_png_set_sRGB_gAMA_and_cHRM
431
470
#define png_set_scale_16 OSS_FUZZ_png_set_scale_16
432
0
#define png_set_shift OSS_FUZZ_png_set_shift
433
1.80k
#define png_set_sig_bytes OSS_FUZZ_png_set_sig_bytes
434
0
#define png_set_strip_16 OSS_FUZZ_png_set_strip_16
435
0
#define png_set_strip_alpha OSS_FUZZ_png_set_strip_alpha
436
0
#define png_set_swap OSS_FUZZ_png_set_swap
437
0
#define png_set_swap_alpha OSS_FUZZ_png_set_swap_alpha
438
69
#define png_set_tIME OSS_FUZZ_png_set_tIME
439
597
#define png_set_tRNS OSS_FUZZ_png_set_tRNS
440
425
#define png_set_tRNS_to_alpha OSS_FUZZ_png_set_tRNS_to_alpha
441
#define png_set_text OSS_FUZZ_png_set_text
442
#define png_set_unknown_chunk_location OSS_FUZZ_png_set_unknown_chunk_location
443
0
#define png_set_unknown_chunks OSS_FUZZ_png_set_unknown_chunks
444
#define png_set_user_limits OSS_FUZZ_png_set_user_limits
445
#define png_set_user_transform_info OSS_FUZZ_png_set_user_transform_info
446
#define png_set_write_fn OSS_FUZZ_png_set_write_fn
447
#define png_set_write_status_fn OSS_FUZZ_png_set_write_status_fn
448
2.22k
#define png_sig_cmp OSS_FUZZ_png_sig_cmp
449
0
#define png_start_read_image OSS_FUZZ_png_start_read_image
450
23.5k
#define png_warning OSS_FUZZ_png_warning
451
#define png_write_chunk OSS_FUZZ_png_write_chunk
452
#define png_write_chunk_data OSS_FUZZ_png_write_chunk_data
453
#define png_write_chunk_end OSS_FUZZ_png_write_chunk_end
454
#define png_write_chunk_start OSS_FUZZ_png_write_chunk_start
455
#define png_write_end OSS_FUZZ_png_write_end
456
#define png_write_image OSS_FUZZ_png_write_image
457
#define png_write_info OSS_FUZZ_png_write_info
458
#define png_write_info_before_PLTE OSS_FUZZ_png_write_info_before_PLTE
459
#define png_write_row OSS_FUZZ_png_write_row
460
#define png_write_rows OSS_FUZZ_png_write_rows
461
#define png_write_sig OSS_FUZZ_png_write_sig
462
68.5k
#define OSS_FUZZ_png_get_uint_32(buf) PNG_get_uint_32(buf)
463
18.7k
#define OSS_FUZZ_png_get_uint_16(buf) PNG_get_uint_16(buf)
464
3.30k
#define OSS_FUZZ_png_get_int_32(buf) PNG_get_int_32(buf)
465
#endif /* PNGLCONF_H */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngmem.c.html b/part1/report/w_corpus/src/libpng/pngmem.c.html new file mode 100644 index 0000000..2801976 --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngmem.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngmem.c
Line
Count
Source (jump to first uncovered line)
1
/* pngmem.c - stub functions for memory allocation
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 * This file provides a location for all memory allocation.  Users who
13
 * need special memory handling are expected to supply replacement
14
 * functions for png_malloc() and png_free(), and to use
15
 * png_create_read_struct_2() and png_create_write_struct_2() to
16
 * identify the replacement functions.
17
 */
18
19
#include "pngpriv.h"
20
21
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
22
/* Free a png_struct */
23
void /* PRIVATE */
24
png_destroy_png_struct(png_structrp png_ptr)
25
2.22k
{
26
2.22k
   if (png_ptr != NULL)
27
2.22k
   {
28
      /* png_free might call png_error and may certainly call
29
       * png_get_mem_ptr, so fake a temporary png_struct to support this.
30
       */
31
2.22k
      png_struct dummy_struct = *png_ptr;
32
2.22k
      memset(png_ptr, 0, (sizeof *png_ptr));
33
2.22k
      png_free(&dummy_struct, png_ptr);
34
35
2.22k
#     ifdef PNG_SETJMP_SUPPORTED
36
         /* We may have a jmp_buf left to deallocate. */
37
2.22k
         png_free_jmpbuf(&dummy_struct);
38
2.22k
#     endif
39
2.22k
   }
40
2.22k
}
41
42
/* Allocate memory.  For reasonable files, size should never exceed
43
 * 64K.  However, zlib may allocate more than 64K if you don't tell
44
 * it not to.  See zconf.h and png.h for more information.  zlib does
45
 * need to allocate exactly 64K, so whatever you call here must
46
 * have the ability to do that.
47
 */
48
PNG_FUNCTION(png_voidp,PNGAPI
49
png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
50
815
{
51
815
   png_voidp ret;
52
53
815
   ret = png_malloc(png_ptr, size);
54
55
815
   if (ret != NULL)
56
814
      memset(ret, 0, size);
57
58
815
   return ret;
59
815
}
60
61
/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
62
 * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
63
 * Checking and error handling must happen outside this routine; it returns NULL
64
 * if the allocation cannot be done (for any reason.)
65
 */
66
PNG_FUNCTION(png_voidp /* PRIVATE */,
67
png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
68
    PNG_ALLOCATED)
69
28.4k
{
70
   /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
71
    * allocators have also been removed in 1.6.0, so any 16-bit system now has
72
    * to implement a user memory handler.  This checks to be sure it isn't
73
    * called with big numbers.
74
    */
75
#  ifdef PNG_MAX_MALLOC_64K
76
      /* This is support for legacy systems which had segmented addressing
77
       * limiting the maximum allocation size to 65536.  It takes precedence
78
       * over PNG_SIZE_MAX which is set to 65535 on true 16-bit systems.
79
       *
80
       * TODO: libpng-1.8: finally remove both cases.
81
       */
82
      if (size > 65536U) return NULL;
83
#  endif
84
85
   /* This is checked too because the system malloc call below takes a (size_t).
86
    */
87
28.4k
   if (size > PNG_SIZE_MAX) return NULL;
88
89
28.4k
#  ifdef PNG_USER_MEM_SUPPORTED
90
28.4k
      if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
91
17.2k
         return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
92
#  else
93
      PNG_UNUSED(png_ptr)
94
#  endif
95
96
   /* Use the system malloc */
97
11.2k
   return malloc((size_t)/*SAFE*/size); /* checked for truncation above */
98
28.4k
}
99
100
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
101
   defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
102
/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
103
 * that arises because of the checks in png_realloc_array that are repeated in
104
 * png_malloc_array.
105
 */
106
static png_voidp
107
png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
108
    size_t element_size)
109
2.06k
{
110
2.06k
   png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
111
112
2.06k
   if (req <= PNG_SIZE_MAX/element_size)
113
2.06k
      return png_malloc_base(png_ptr, req * element_size);
114
115
   /* The failure case when the request is too large */
116
0
   return NULL;
117
2.06k
}
118
119
PNG_FUNCTION(png_voidp /* PRIVATE */,
120
png_malloc_array,(png_const_structrp png_ptr, int nelements,
121
    size_t element_size),PNG_ALLOCATED)
122
401
{
123
401
   if (nelements <= 0 || element_size == 0)
124
0
      png_error(png_ptr, "internal error: array alloc");
125
126
401
   return png_malloc_array_checked(png_ptr, nelements, element_size);
127
401
}
128
129
PNG_FUNCTION(png_voidp /* PRIVATE */,
130
png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
131
    int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
132
1.66k
{
133
   /* These are internal errors: */
134
1.66k
   if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
135
1.66k
      (old_array == NULL && old_elements > 0))
136
0
      png_error(png_ptr, "internal error: array realloc");
137
138
   /* Check for overflow on the elements count (so the caller does not have to
139
    * check.)
140
    */
141
1.66k
   if (add_elements <= INT_MAX - old_elements)
142
1.66k
   {
143
1.66k
      png_voidp new_array = png_malloc_array_checked(png_ptr,
144
1.66k
          old_elements+add_elements, element_size);
145
146
1.66k
      if (new_array != NULL)
147
1.66k
      {
148
         /* Because png_malloc_array worked the size calculations below cannot
149
          * overflow.
150
          */
151
1.66k
         if (old_elements > 0)
152
787
            memcpy(new_array, old_array, element_size*(unsigned)old_elements);
153
154
1.66k
         memset((char*)new_array + element_size*(unsigned)old_elements, 0,
155
1.66k
             element_size*(unsigned)add_elements);
156
157
1.66k
         return new_array;
158
1.66k
      }
159
1.66k
   }
160
161
0
   return NULL; /* error */
162
1.66k
}
163
#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
164
165
/* Various functions that have different error handling are derived from this.
166
 * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
167
 * function png_malloc_default is also provided.
168
 */
169
PNG_FUNCTION(png_voidp,PNGAPI
170
png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
171
5.61k
{
172
5.61k
   png_voidp ret;
173
174
5.61k
   if (png_ptr == NULL)
175
0
      return NULL;
176
177
5.61k
   ret = png_malloc_base(png_ptr, size);
178
179
5.61k
   if (ret == NULL)
180
2
       png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
181
182
5.61k
   return ret;
183
5.61k
}
184
185
#ifdef PNG_USER_MEM_SUPPORTED
186
PNG_FUNCTION(png_voidp,PNGAPI
187
png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
188
    PNG_ALLOCATED PNG_DEPRECATED)
189
0
{
190
0
   png_voidp ret;
191
192
0
   if (png_ptr == NULL)
193
0
      return NULL;
194
195
   /* Passing 'NULL' here bypasses the application provided memory handler. */
196
0
   ret = png_malloc_base(NULL/*use malloc*/, size);
197
198
0
   if (ret == NULL)
199
0
      png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
200
201
0
   return ret;
202
0
}
203
#endif /* USER_MEM */
204
205
/* This function was added at libpng version 1.2.3.  The png_malloc_warn()
206
 * function will issue a png_warning and return NULL instead of issuing a
207
 * png_error, if it fails to allocate the requested memory.
208
 */
209
PNG_FUNCTION(png_voidp,PNGAPI
210
png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
211
    PNG_ALLOCATED)
212
6.93k
{
213
6.93k
   if (png_ptr != NULL)
214
6.93k
   {
215
6.93k
      png_voidp ret = png_malloc_base(png_ptr, size);
216
217
6.93k
      if (ret != NULL)
218
6.93k
         return ret;
219
220
0
      png_warning(png_ptr, "Out of memory");
221
0
   }
222
223
0
   return NULL;
224
6.93k
}
225
226
/* Free a pointer allocated by png_malloc().  If ptr is NULL, return
227
 * without taking any action.
228
 */
229
void PNGAPI
230
png_free(png_const_structrp png_ptr, png_voidp ptr)
231
53.6k
{
232
53.6k
   if (png_ptr == NULL || ptr == NULL)
233
25.1k
      return;
234
235
28.4k
#ifdef PNG_USER_MEM_SUPPORTED
236
28.4k
   if (png_ptr->free_fn != NULL)
237
22.6k
      png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
238
239
5.80k
   else
240
5.80k
      png_free_default(png_ptr, ptr);
241
28.4k
}
242
243
PNG_FUNCTION(void,PNGAPI
244
png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
245
5.80k
{
246
5.80k
   if (png_ptr == NULL || ptr == NULL)
247
0
      return;
248
5.80k
#endif /* USER_MEM */
249
250
5.80k
   free(ptr);
251
5.80k
}
252
253
#ifdef PNG_USER_MEM_SUPPORTED
254
/* This function is called when the application wants to use another method
255
 * of allocating and freeing memory.
256
 */
257
void PNGAPI
258
png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
259
  malloc_fn, png_free_ptr free_fn)
260
4.02k
{
261
4.02k
   if (png_ptr != NULL)
262
4.02k
   {
263
4.02k
      png_ptr->mem_ptr = mem_ptr;
264
4.02k
      png_ptr->malloc_fn = malloc_fn;
265
4.02k
      png_ptr->free_fn = free_fn;
266
4.02k
   }
267
4.02k
}
268
269
/* This function returns a pointer to the mem_ptr associated with the user
270
 * functions.  The application should free any memory associated with this
271
 * pointer before png_write_destroy and png_read_destroy are called.
272
 */
273
png_voidp PNGAPI
274
png_get_mem_ptr(png_const_structrp png_ptr)
275
0
{
276
0
   if (png_ptr == NULL)
277
0
      return NULL;
278
279
0
   return png_ptr->mem_ptr;
280
0
}
281
#endif /* USER_MEM */
282
#endif /* READ || WRITE */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngprefix.h.html b/part1/report/w_corpus/src/libpng/pngprefix.h.html new file mode 100644 index 0000000..7cfbbb9 --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngprefix.h.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngprefix.h
Line
Count
Source (jump to first uncovered line)
1
0
#define png_sRGB_table OSS_FUZZ_png_sRGB_table
2
0
#define png_sRGB_base OSS_FUZZ_png_sRGB_base
3
0
#define png_sRGB_delta OSS_FUZZ_png_sRGB_delta
4
2.62k
#define png_zstream_error OSS_FUZZ_png_zstream_error
5
0
#define png_fixed OSS_FUZZ_png_fixed
6
0
#define png_fixed_ITU OSS_FUZZ_png_fixed_ITU
7
2.22k
#define png_user_version_check OSS_FUZZ_png_user_version_check
8
14.6k
#define png_malloc_base OSS_FUZZ_png_malloc_base
9
#define png_malloc_array OSS_FUZZ_png_malloc_array
10
#define png_realloc_array OSS_FUZZ_png_realloc_array
11
2.22k
#define png_create_png_struct OSS_FUZZ_png_create_png_struct
12
2.22k
#define png_destroy_png_struct OSS_FUZZ_png_destroy_png_struct
13
2.22k
#define png_free_jmpbuf OSS_FUZZ_png_free_jmpbuf
14
2.22k
#define png_zalloc OSS_FUZZ_png_zalloc
15
2.22k
#define png_zfree OSS_FUZZ_png_zfree
16
#define png_default_read_data OSS_FUZZ_png_default_read_data
17
#define png_push_fill_buffer OSS_FUZZ_png_push_fill_buffer
18
#define png_default_write_data OSS_FUZZ_png_default_write_data
19
38.1k
#define png_reset_crc OSS_FUZZ_png_reset_crc
20
#define png_write_data OSS_FUZZ_png_write_data
21
2.22k
#define png_read_sig OSS_FUZZ_png_read_sig
22
38.1k
#define png_read_chunk_header OSS_FUZZ_png_read_chunk_header
23
112k
#define png_read_data OSS_FUZZ_png_read_data
24
37.6k
#define png_crc_read OSS_FUZZ_png_crc_read
25
35.1k
#define png_crc_finish OSS_FUZZ_png_crc_finish
26
75.7k
#define png_calculate_crc OSS_FUZZ_png_calculate_crc
27
#define png_write_IHDR OSS_FUZZ_png_write_IHDR
28
#define png_write_PLTE OSS_FUZZ_png_write_PLTE
29
#define png_compress_IDAT OSS_FUZZ_png_compress_IDAT
30
#define png_write_IEND OSS_FUZZ_png_write_IEND
31
5.40k
#define png_set_text_2 OSS_FUZZ_png_set_text_2
32
#define png_write_finish_row OSS_FUZZ_png_write_finish_row
33
#define png_write_start_row OSS_FUZZ_png_write_start_row
34
118k
#define png_combine_row OSS_FUZZ_png_combine_row
35
46.4k
#define png_do_read_interlace OSS_FUZZ_png_do_read_interlace
36
66.4k
#define png_read_filter_row OSS_FUZZ_png_read_filter_row
37
#define png_write_find_filter OSS_FUZZ_png_write_find_filter
38
118k
#define png_read_IDAT_data OSS_FUZZ_png_read_IDAT_data
39
1.45k
#define png_read_finish_IDAT OSS_FUZZ_png_read_finish_IDAT
40
494k
#define png_read_finish_row OSS_FUZZ_png_read_finish_row
41
1.38k
#define png_read_start_row OSS_FUZZ_png_read_start_row
42
137k
#define png_zlib_inflate OSS_FUZZ_png_zlib_inflate
43
1.38k
#define png_read_transform_info OSS_FUZZ_png_read_transform_info
44
0
#define png_do_strip_channel OSS_FUZZ_png_do_strip_channel
45
0
#define png_do_swap OSS_FUZZ_png_do_swap
46
0
#define png_do_packswap OSS_FUZZ_png_do_packswap
47
0
#define png_do_invert OSS_FUZZ_png_do_invert
48
0
#define png_do_bgr OSS_FUZZ_png_do_bgr
49
1.84k
#define png_handle_unknown OSS_FUZZ_png_handle_unknown
50
36.4k
#define png_handle_chunk OSS_FUZZ_png_handle_chunk
51
35.9k
#define png_chunk_unknown_handling OSS_FUZZ_png_chunk_unknown_handling
52
118k
#define png_do_read_transformations OSS_FUZZ_png_do_read_transformations
53
1.38k
#define png_init_read_transformations OSS_FUZZ_png_init_read_transformations
54
#define png_push_read_chunk OSS_FUZZ_png_push_read_chunk
55
#define png_push_read_sig OSS_FUZZ_png_push_read_sig
56
#define png_push_check_crc OSS_FUZZ_png_push_check_crc
57
#define png_push_save_buffer OSS_FUZZ_png_push_save_buffer
58
#define png_push_restore_buffer OSS_FUZZ_png_push_restore_buffer
59
#define png_push_read_IDAT OSS_FUZZ_png_push_read_IDAT
60
#define png_process_IDAT_data OSS_FUZZ_png_process_IDAT_data
61
#define png_push_process_row OSS_FUZZ_png_push_process_row
62
#define png_push_have_info OSS_FUZZ_png_push_have_info
63
#define png_push_have_end OSS_FUZZ_png_push_have_end
64
#define png_push_have_row OSS_FUZZ_png_push_have_row
65
#define png_push_read_end OSS_FUZZ_png_push_read_end
66
#define png_process_some_data OSS_FUZZ_png_process_some_data
67
#define png_read_push_finish_row OSS_FUZZ_png_read_push_finish_row
68
47
#define png_icc_check_length OSS_FUZZ_png_icc_check_length
69
17
#define png_icc_check_header OSS_FUZZ_png_icc_check_header
70
0
#define png_icc_check_tag_table OSS_FUZZ_png_icc_check_tag_table
71
#define png_set_rgb_coefficients OSS_FUZZ_png_set_rgb_coefficients
72
3.17k
#define png_check_IHDR OSS_FUZZ_png_check_IHDR
73
0
#define png_do_check_palette_indexes OSS_FUZZ_png_do_check_palette_indexes
74
0
#define png_fixed_error OSS_FUZZ_png_fixed_error
75
597
#define png_safecat OSS_FUZZ_png_safecat
76
35
#define png_format_number OSS_FUZZ_png_format_number
77
0
#define png_warning_parameter OSS_FUZZ_png_warning_parameter
78
#define png_warning_parameter_unsigned OSS_FUZZ_png_warning_parameter_unsigned
79
0
#define png_warning_parameter_signed OSS_FUZZ_png_warning_parameter_signed
80
0
#define png_formatted_warning OSS_FUZZ_png_formatted_warning
81
0
#define png_app_warning OSS_FUZZ_png_app_warning
82
0
#define png_app_error OSS_FUZZ_png_app_error
83
80
#define png_chunk_report OSS_FUZZ_png_chunk_report
84
0
#define png_ascii_from_fp OSS_FUZZ_png_ascii_from_fp
85
0
#define png_ascii_from_fixed OSS_FUZZ_png_ascii_from_fixed
86
1.68k
#define png_check_fp_number OSS_FUZZ_png_check_fp_number
87
364
#define png_check_fp_string OSS_FUZZ_png_check_fp_string
88
419
#define png_muldiv OSS_FUZZ_png_muldiv
89
1.30k
#define png_reciprocal OSS_FUZZ_png_reciprocal
90
177
#define png_reciprocal2 OSS_FUZZ_png_reciprocal2
91
1.94k
#define png_gamma_significant OSS_FUZZ_png_gamma_significant
92
1.38k
#define png_resolve_file_gamma OSS_FUZZ_png_resolve_file_gamma
93
0
#define png_gamma_correct OSS_FUZZ_png_gamma_correct
94
9.94k
#define png_gamma_16bit_correct OSS_FUZZ_png_gamma_16bit_correct
95
35.3k
#define png_gamma_8bit_correct OSS_FUZZ_png_gamma_8bit_correct
96
2.22k
#define png_destroy_gamma_table OSS_FUZZ_png_destroy_gamma_table
97
177
#define png_build_gamma_table OSS_FUZZ_png_build_gamma_table
98
0
#define png_set_rgb_coefficients OSS_FUZZ_png_set_rgb_coefficients
99
0
#define png_XYZ_from_xy OSS_FUZZ_png_XYZ_from_xy
100
0
#define png_xy_from_XYZ OSS_FUZZ_png_xy_from_XYZ
101
425
#define png_safe_error OSS_FUZZ_png_safe_error
102
425
#define png_safe_warning OSS_FUZZ_png_safe_warning
103
844
#define png_safe_execute OSS_FUZZ_png_safe_execute
104
0
#define png_image_error OSS_FUZZ_png_image_error
105
#define png_check_keyword OSS_FUZZ_png_check_keyword
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngpriv.h.html b/part1/report/w_corpus/src/libpng/pngpriv.h.html new file mode 100644 index 0000000..c42ce57 --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngpriv.h.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngpriv.h
Line
Count
Source (jump to first uncovered line)
1
/* pngpriv.h - private declarations for use inside libpng
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 */
12
13
/* The symbols declared in this file (including the functions declared
14
 * as extern) are PRIVATE.  They are not part of the libpng public
15
 * interface, and are not recommended for use by regular applications.
16
 * Some of them may become public in the future; others may stay private,
17
 * change in an incompatible way, or even disappear.
18
 * Although the libpng users are not forbidden to include this header,
19
 * they should be well aware of the issues that may arise from doing so.
20
 */
21
22
23
/* pngpriv.h must be included first in each translation unit inside libpng.
24
 * On the other hand, it must not be included at all, directly or indirectly,
25
 * by any application code that uses the libpng API.
26
 */
27
#ifndef PNGPRIV_H
28
#  define PNGPRIV_H
29
#else
30
#  error Duplicate inclusion of pngpriv.h; please check the libpng source files
31
#endif
32
33
#if defined(PNG_H) || defined(PNGCONF_H) || defined(PNGLCONF_H)
34
#  error This file must not be included by applications; please include <png.h>
35
#endif
36
37
/* Feature Test Macros.  The following are defined here to ensure that correctly
38
 * implemented libraries reveal the APIs libpng needs to build and hide those
39
 * that are not needed and potentially damaging to the compilation.
40
 *
41
 * Feature Test Macros must be defined before any system header is included (see
42
 * POSIX 1003.1 2.8.2 "POSIX Symbols."
43
 *
44
 * These macros only have an effect if the operating system supports either
45
 * POSIX 1003.1 or C99, or both.  On other operating systems (particularly
46
 * Windows/Visual Studio) there is no effect; the OS specific tests below are
47
 * still required (as of 2011-05-02.)
48
 */
49
#ifndef _POSIX_SOURCE
50
#  define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
51
#endif
52
53
#ifndef PNG_VERSION_INFO_ONLY
54
/* Standard library headers not required by png.h: */
55
#  include <stdlib.h>
56
#  include <string.h>
57
#endif
58
59
#define PNGLIB_BUILD /*libpng is being built, not used*/
60
61
/* If HAVE_CONFIG_H is defined during the build then the build system must
62
 * provide an appropriate "config.h" file on the include path.  The header file
63
 * must provide definitions as required below (search for "HAVE_CONFIG_H");
64
 * see configure.ac for more details of the requirements.  The macro
65
 * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on
66
 * 'configure'; define this macro to prevent the configure build including the
67
 * configure generated config.h.  Libpng is expected to compile without *any*
68
 * special build system support on a reasonably ANSI-C compliant system.
69
 */
70
#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
71
#  include <config.h>
72
   /* Pick up the definition of 'restrict' from config.h if it was read: */
73
#  define PNG_RESTRICT restrict
74
#endif
75
76
/* To support symbol prefixing it is necessary to know *before* including png.h
77
 * whether the fixed point (and maybe other) APIs are exported, because if they
78
 * are not internal definitions may be required.  This is handled below just
79
 * before png.h is included, but load the configuration now if it is available.
80
 */
81
#include "pnglibconf.h"
82
83
/* Local renames may change non-exported API functions from png.h */
84
#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H)
85
#  include "pngprefix.h"
86
#endif
87
88
#ifdef PNG_USER_CONFIG
89
#  include "pngusr.h"
90
   /* These should have been defined in pngusr.h */
91
#  ifndef PNG_USER_PRIVATEBUILD
92
#    define PNG_USER_PRIVATEBUILD "Custom libpng build"
93
#  endif
94
#  ifndef PNG_USER_DLLFNAME_POSTFIX
95
#    define PNG_USER_DLLFNAME_POSTFIX "Cb"
96
#  endif
97
#endif
98
99
/* Compile time options.
100
 * =====================
101
 * In a multi-arch build the compiler may compile the code several times for the
102
 * same object module, producing different binaries for different architectures.
103
 * When this happens configure-time setting of the target host options cannot be
104
 * done and this interferes with the handling of the ARM NEON optimizations, and
105
 * possibly other similar optimizations.  Put additional tests here; in general
106
 * this is needed when the same option can be changed at both compile time and
107
 * run time depending on the target OS (i.e. iOS vs Android.)
108
 *
109
 * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because
110
 * this is not possible with certain compilers (Oracle SUN OS CC), as a result
111
 * it is necessary to ensure that all extern functions that *might* be used
112
 * regardless of $(CFLAGS) get declared in this file.  The test on __ARM_NEON__
113
 * below is one example of this behavior because it is controlled by the
114
 * presence or not of -mfpu=neon on the GCC command line, it is possible to do
115
 * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely
116
 * do this.
117
 */
118
#ifndef PNG_ARM_NEON_OPT
119
   /* ARM NEON optimizations are being controlled by the compiler settings,
120
    * typically the target FPU.  If the FPU has been set to NEON (-mfpu=neon
121
    * with GCC) then the compiler will define __ARM_NEON__ and we can rely
122
    * unconditionally on NEON instructions not crashing, otherwise we must
123
    * disable use of NEON instructions.
124
    *
125
    * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they
126
    * can only be turned on automatically if that is supported too.  If
127
    * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail
128
    * to compile with an appropriate #error if ALIGNED_MEMORY has been turned
129
    * off.
130
    *
131
    * Note that gcc-4.9 defines __ARM_NEON instead of the deprecated
132
    * __ARM_NEON__, so we check both variants.
133
    *
134
    * To disable ARM_NEON optimizations entirely, and skip compiling the
135
    * associated assembler code, pass --enable-arm-neon=no to configure
136
    * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS.
137
    */
138
#  if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \
139
   defined(PNG_ALIGNED_MEMORY_SUPPORTED)
140
#     define PNG_ARM_NEON_OPT 2
141
#  else
142
#     define PNG_ARM_NEON_OPT 0
143
#  endif
144
#endif
145
146
#if PNG_ARM_NEON_OPT > 0
147
   /* NEON optimizations are to be at least considered by libpng, so enable the
148
    * callbacks to do this.
149
    */
150
#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
151
#  ifndef PNG_ARM_NEON_IMPLEMENTATION
152
      /* Use the intrinsics code by default. */
153
#     define PNG_ARM_NEON_IMPLEMENTATION 1
154
#  endif
155
#else /* PNG_ARM_NEON_OPT == 0 */
156
#     define PNG_ARM_NEON_IMPLEMENTATION 0
157
#endif /* PNG_ARM_NEON_OPT > 0 */
158
159
#ifndef PNG_MIPS_MSA_OPT
160
#  if defined(__mips_msa) && (__mips_isa_rev >= 5) && \
161
   defined(PNG_ALIGNED_MEMORY_SUPPORTED)
162
#     define PNG_MIPS_MSA_OPT 2
163
#  else
164
#     define PNG_MIPS_MSA_OPT 0
165
#  endif
166
#endif
167
168
#ifndef PNG_MIPS_MMI_OPT
169
#  ifdef PNG_MIPS_MMI
170
#    if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \
171
     defined(PNG_ALIGNED_MEMORY_SUPPORTED)
172
#       define PNG_MIPS_MMI_OPT 1
173
#    else
174
#       define PNG_MIPS_MMI_OPT 0
175
#    endif
176
#  else
177
#    define PNG_MIPS_MMI_OPT 0
178
#  endif
179
#endif
180
181
#ifndef PNG_POWERPC_VSX_OPT
182
#  if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
183
#     define PNG_POWERPC_VSX_OPT 2
184
#  else
185
#     define PNG_POWERPC_VSX_OPT 0
186
#  endif
187
#endif
188
189
#ifndef PNG_LOONGARCH_LSX_OPT
190
#  if defined(__loongarch_sx)
191
#     define PNG_LOONGARCH_LSX_OPT 1
192
#  else
193
#     define PNG_LOONGARCH_LSX_OPT 0
194
#  endif
195
#endif
196
197
#ifndef PNG_INTEL_SSE_OPT
198
#   ifdef PNG_INTEL_SSE
199
      /* Only check for SSE if the build configuration has been modified to
200
       * enable SSE optimizations.  This means that these optimizations will
201
       * be off by default.  See contrib/intel for more details.
202
       */
203
#      if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
204
       defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
205
       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
206
#         define PNG_INTEL_SSE_OPT 1
207
#      else
208
#         define PNG_INTEL_SSE_OPT 0
209
#      endif
210
#   else
211
#      define PNG_INTEL_SSE_OPT 0
212
#   endif
213
#endif
214
215
#if PNG_INTEL_SSE_OPT > 0
216
#   ifndef PNG_INTEL_SSE_IMPLEMENTATION
217
#      if defined(__SSE4_1__) || defined(__AVX__)
218
          /* We are not actually using AVX, but checking for AVX is the best
219
             way we can detect SSE4.1 and SSSE3 on MSVC.
220
          */
221
#         define PNG_INTEL_SSE_IMPLEMENTATION 3
222
#      elif defined(__SSSE3__)
223
#         define PNG_INTEL_SSE_IMPLEMENTATION 2
224
#      elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
225
       (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
226
#         define PNG_INTEL_SSE_IMPLEMENTATION 1
227
#      else
228
#         define PNG_INTEL_SSE_IMPLEMENTATION 0
229
#      endif
230
#   endif
231
232
#   if PNG_INTEL_SSE_IMPLEMENTATION > 0
233
#      define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
234
#   endif
235
#else
236
#   define PNG_INTEL_SSE_IMPLEMENTATION 0
237
#endif
238
239
#if PNG_MIPS_MSA_OPT > 0
240
#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
241
#     if defined(__mips_msa)
242
#        if defined(__clang__)
243
#        elif defined(__GNUC__)
244
#           if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
245
#              define PNG_MIPS_MSA_IMPLEMENTATION 2
246
#           endif /* no GNUC support */
247
#        endif /* __GNUC__ */
248
#     else /* !defined __mips_msa */
249
#        define PNG_MIPS_MSA_IMPLEMENTATION 2
250
#     endif /* __mips_msa */
251
#  endif /* !PNG_MIPS_MSA_IMPLEMENTATION */
252
253
#  ifndef PNG_MIPS_MSA_IMPLEMENTATION
254
#     define PNG_MIPS_MSA_IMPLEMENTATION 1
255
#     define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips
256
#  endif
257
#else
258
#  define PNG_MIPS_MSA_IMPLEMENTATION 0
259
#endif /* PNG_MIPS_MSA_OPT > 0 */
260
261
#if PNG_MIPS_MMI_OPT > 0
262
#  ifndef PNG_MIPS_MMI_IMPLEMENTATION
263
#     if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64)
264
#        define PNG_MIPS_MMI_IMPLEMENTATION 2
265
#     else /* !defined __mips_loongson_mmi  || _MIPS_SIM != _ABI64 */
266
#        define PNG_MIPS_MMI_IMPLEMENTATION 0
267
#     endif /* __mips_loongson_mmi  && _MIPS_SIM == _ABI64 */
268
#  endif /* !PNG_MIPS_MMI_IMPLEMENTATION */
269
270
#   if PNG_MIPS_MMI_IMPLEMENTATION > 0
271
#      define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips
272
#   endif
273
#else
274
#   define PNG_MIPS_MMI_IMPLEMENTATION 0
275
#endif /* PNG_MIPS_MMI_OPT > 0 */
276
277
#if PNG_POWERPC_VSX_OPT > 0
278
#  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
279
#  define PNG_POWERPC_VSX_IMPLEMENTATION 1
280
#else
281
#  define PNG_POWERPC_VSX_IMPLEMENTATION 0
282
#endif
283
284
#if PNG_LOONGARCH_LSX_OPT > 0
285
#   define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx
286
#   define PNG_LOONGARCH_LSX_IMPLEMENTATION 1
287
#else
288
#   define PNG_LOONGARCH_LSX_IMPLEMENTATION 0
289
#endif
290
291
/* Is this a build of a DLL where compilation of the object modules requires
292
 * different preprocessor settings to those required for a simple library?  If
293
 * so PNG_BUILD_DLL must be set.
294
 *
295
 * If libpng is used inside a DLL but that DLL does not export the libpng APIs
296
 * PNG_BUILD_DLL must not be set.  To avoid the code below kicking in build a
297
 * static library of libpng then link the DLL against that.
298
 */
299
#ifndef PNG_BUILD_DLL
300
#  ifdef DLL_EXPORT
301
      /* This is set by libtool when files are compiled for a DLL; libtool
302
       * always compiles twice, even on systems where it isn't necessary.  Set
303
       * PNG_BUILD_DLL in case it is necessary:
304
       */
305
#     define PNG_BUILD_DLL
306
#  else
307
#     ifdef _WINDLL
308
         /* This is set by the Microsoft Visual Studio IDE in projects that
309
          * build a DLL.  It can't easily be removed from those projects (it
310
          * isn't visible in the Visual Studio UI) so it is a fairly reliable
311
          * indication that PNG_IMPEXP needs to be set to the DLL export
312
          * attributes.
313
          */
314
#        define PNG_BUILD_DLL
315
#     else
316
#        ifdef __DLL__
317
            /* This is set by the Borland C system when compiling for a DLL
318
             * (as above.)
319
             */
320
#           define PNG_BUILD_DLL
321
#        else
322
            /* Add additional compiler cases here. */
323
#        endif
324
#     endif
325
#  endif
326
#endif /* Setting PNG_BUILD_DLL if required */
327
328
/* See pngconf.h for more details: the builder of the library may set this on
329
 * the command line to the right thing for the specific compilation system or it
330
 * may be automagically set above (at present we know of no system where it does
331
 * need to be set on the command line.)
332
 *
333
 * PNG_IMPEXP must be set here when building the library to prevent pngconf.h
334
 * setting it to the "import" setting for a DLL build.
335
 */
336
#ifndef PNG_IMPEXP
337
#  ifdef PNG_BUILD_DLL
338
#     define PNG_IMPEXP PNG_DLL_EXPORT
339
#  else
340
      /* Not building a DLL, or the DLL doesn't require specific export
341
       * definitions.
342
       */
343
#     define PNG_IMPEXP
344
#  endif
345
#endif
346
347
/* No warnings for private or deprecated functions in the build: */
348
#ifndef PNG_DEPRECATED
349
#  define PNG_DEPRECATED
350
#endif
351
#ifndef PNG_PRIVATE
352
#  define PNG_PRIVATE
353
#endif
354
355
/* Symbol preprocessing support.
356
 *
357
 * To enable listing global, but internal, symbols the following macros should
358
 * always be used to declare an extern data or function object in this file.
359
 */
360
#ifndef PNG_INTERNAL_DATA
361
#  define PNG_INTERNAL_DATA(type, name, array) PNG_LINKAGE_DATA type name array
362
#endif
363
364
#ifndef PNG_INTERNAL_FUNCTION
365
#  define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\
366
      PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)
367
#endif
368
369
#ifndef PNG_INTERNAL_CALLBACK
370
#  define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\
371
      PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\
372
         PNG_EMPTY attributes)
373
#endif
374
375
/* If floating or fixed point APIs are disabled they may still be compiled
376
 * internally.  To handle this make sure they are declared as the appropriate
377
 * internal extern function (otherwise the symbol prefixing stuff won't work and
378
 * the functions will be used without definitions.)
379
 *
380
 * NOTE: although all the API functions are declared here they are not all
381
 * actually built!  Because the declarations are still made it is necessary to
382
 * fake out types that they depend on.
383
 */
384
#ifndef PNG_FP_EXPORT
385
#  ifndef PNG_FLOATING_POINT_SUPPORTED
386
#     define PNG_FP_EXPORT(ordinal, type, name, args)\
387
         PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);
388
#     ifndef PNG_VERSION_INFO_ONLY
389
         typedef struct png_incomplete png_double;
390
         typedef png_double*           png_doublep;
391
         typedef const png_double*     png_const_doublep;
392
         typedef png_double**          png_doublepp;
393
#     endif
394
#  endif
395
#endif
396
#ifndef PNG_FIXED_EXPORT
397
#  ifndef PNG_FIXED_POINT_SUPPORTED
398
#     define PNG_FIXED_EXPORT(ordinal, type, name, args)\
399
         PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);
400
#  endif
401
#endif
402
403
#include "png.h"
404
405
/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */
406
#ifndef PNG_DLL_EXPORT
407
#  define PNG_DLL_EXPORT
408
#endif
409
410
/* This is a global switch to set the compilation for an installed system
411
 * (a release build).  It can be set for testing debug builds to ensure that
412
 * they will compile when the build type is switched to RC or STABLE, the
413
 * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE.  Set this in CPPFLAGS
414
 * with either:
415
 *
416
 *   -DPNG_RELEASE_BUILD Turns on the release compile path
417
 *   -DPNG_RELEASE_BUILD=0 Turns it off
418
 * or in your pngusr.h with
419
 *   #define PNG_RELEASE_BUILD=1 Turns on the release compile path
420
 *   #define PNG_RELEASE_BUILD=0 Turns it off
421
 */
422
#ifndef PNG_RELEASE_BUILD
423
#  define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)
424
#endif
425
426
/* SECURITY and SAFETY:
427
 *
428
 * libpng is built with support for internal limits on image dimensions and
429
 * memory usage.  These are documented in scripts/pnglibconf.dfa of the
430
 * source and recorded in the machine generated header file pnglibconf.h.
431
 */
432
433
/* If you are running on a machine where you cannot allocate more
434
 * than 64K of memory at once, uncomment this.  While libpng will not
435
 * normally need that much memory in a chunk (unless you load up a very
436
 * large file), zlib needs to know how big of a chunk it can use, and
437
 * libpng thus makes sure to check any memory allocation to verify it
438
 * will fit into memory.
439
 *
440
 * zlib provides 'MAXSEG_64K' which, if defined, indicates the
441
 * same limit and pngconf.h (already included) sets the limit
442
 * if certain operating systems are detected.
443
 */
444
#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
445
#  define PNG_MAX_MALLOC_64K
446
#endif
447
448
#ifndef PNG_UNUSED
449
/* Unused formal parameter warnings are silenced using the following macro
450
 * which is expected to have no bad effects on performance (optimizing
451
 * compilers will probably remove it entirely).  Note that if you replace
452
 * it with something other than whitespace, you must include the terminating
453
 * semicolon.
454
 */
455
57.7k
#  define PNG_UNUSED(param) (void)param;
456
#endif
457
458
/* Just a little check that someone hasn't tried to define something
459
 * contradictory.
460
 */
461
#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
462
#  undef PNG_ZBUF_SIZE
463
#  define PNG_ZBUF_SIZE 65536L
464
#endif
465
466
/* If warnings or errors are turned off the code is disabled or redirected here.
467
 * From 1.5.4 functions have been added to allow very limited formatting of
468
 * error and warning messages - this code will also be disabled here.
469
 */
470
#ifdef PNG_WARNINGS_SUPPORTED
471
0
#  define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;
472
#else
473
#  define png_warning_parameter(p,number,string) ((void)0)
474
#  define png_warning_parameter_unsigned(p,number,format,value) ((void)0)
475
#  define png_warning_parameter_signed(p,number,format,value) ((void)0)
476
#  define png_formatted_warning(pp,p,message) ((void)(pp))
477
#  define PNG_WARNING_PARAMETERS(p)
478
#endif
479
#ifndef PNG_ERROR_TEXT_SUPPORTED
480
#  define png_fixed_error(s1,s2) png_err(s1)
481
#endif
482
483
/* Some fixed point APIs are still required even if not exported because
484
 * they get used by the corresponding floating point APIs.  This magic
485
 * deals with this:
486
 */
487
#ifdef PNG_FIXED_POINT_SUPPORTED
488
#  define PNGFAPI PNGAPI
489
#else
490
#  define PNGFAPI /* PRIVATE */
491
#endif
492
493
#ifndef PNG_VERSION_INFO_ONLY
494
/* Other defines specific to compilers can go here.  Try to keep
495
 * them inside an appropriate ifdef/endif pair for portability.
496
 */
497
498
/* C allows up-casts from (void*) to any pointer and (const void*) to any
499
 * pointer to a const object.  C++ regards this as a type error and requires an
500
 * explicit, static, cast and provides the static_cast<> rune to ensure that
501
 * const is not cast away.
502
 */
503
#ifdef __cplusplus
504
#  define png_voidcast(type, value) static_cast<type>(value)
505
#  define png_constcast(type, value) const_cast<type>(value)
506
#  define png_aligncast(type, value) \
507
   static_cast<type>(static_cast<void*>(value))
508
#  define png_aligncastconst(type, value) \
509
   static_cast<type>(static_cast<const void*>(value))
510
#else
511
56.7k
#  define png_voidcast(type, value) (value)
512
45.7k
#  define png_constcast(type, value) ((type)(void*)(const void*)(value))
513
19.2k
#  define png_aligncast(type, value) ((void*)(value))
514
19.2k
#  define png_aligncastconst(type, value) ((const void*)(value))
515
#endif /* __cplusplus */
516
517
#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
518
    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
519
   /* png.c requires the following ANSI-C constants if the conversion of
520
    * floating point to ASCII is implemented therein:
521
    *
522
    *  DBL_DIG  Maximum number of decimal digits (can be set to any constant)
523
    *  DBL_MIN  Smallest normalized fp number (can be set to an arbitrary value)
524
    *  DBL_MAX  Maximum floating point number (can be set to an arbitrary value)
525
    */
526
#  include <float.h>
527
528
#  include <math.h>
529
530
#  if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
531
   /* Amiga SAS/C: We must include builtin FPU functions when compiling using
532
    * MATH=68881
533
    */
534
#    include <m68881.h>
535
#  endif
536
#endif
537
538
/* This provides the non-ANSI (far) memory allocation routines. */
539
#if defined(__TURBOC__) && defined(__MSDOS__)
540
#  include <mem.h>
541
#  include <alloc.h>
542
#endif
543
544
#if defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
545
#  include <windows.h>
546
#endif
547
#endif /* PNG_VERSION_INFO_ONLY */
548
549
/* Moved here around 1.5.0beta36 from pngconf.h */
550
/* Users may want to use these so they are not private.  Any library
551
 * functions that are passed far data must be model-independent.
552
 */
553
554
/* Platform-independent functions */
555
#ifndef PNG_ABORT
556
1.37k
#  define PNG_ABORT() abort()
557
#endif
558
559
/* These macros may need to be architecture dependent. */
560
#define PNG_ALIGN_NONE      0 /* do not use data alignment */
561
#define PNG_ALIGN_ALWAYS    1 /* assume unaligned accesses are OK */
562
#ifdef offsetof
563
#  define PNG_ALIGN_OFFSET  2 /* use offsetof to determine alignment */
564
#else
565
#  define PNG_ALIGN_OFFSET -1 /* prevent the use of this */
566
#endif
567
#define PNG_ALIGN_SIZE      3 /* use sizeof to determine alignment */
568
569
#ifndef PNG_ALIGN_TYPE
570
   /* Default to using aligned access optimizations and requiring alignment to a
571
    * multiple of the data type size.  Override in a compiler specific fashion
572
    * if necessary by inserting tests here:
573
    */
574
#  define PNG_ALIGN_TYPE PNG_ALIGN_SIZE
575
#endif
576
577
#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE
578
   /* This is used because in some compiler implementations non-aligned
579
    * structure members are supported, so the offsetof approach below fails.
580
    * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access
581
    * is good for performance.  Do not do this unless you have tested the
582
    * result and understand it.
583
    */
584
76.9k
#  define png_alignof(type) (sizeof(type))
585
#else
586
#  if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET
587
#    define png_alignof(type) offsetof(struct{char c; type t;}, t)
588
#  else
589
#    if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
590
#      define png_alignof(type) 1
591
#    endif
592
     /* Else leave png_alignof undefined to prevent use thereof */
593
#  endif
594
#endif
595
596
/* This implicitly assumes alignment is always a multiple of 2. */
597
#ifdef png_alignof
598
#  define png_isaligned(ptr, type) \
599
153k
   (((type)(size_t)((const void*)(ptr)) & (type)(png_alignof(type)-1)) == 0)
600
#else
601
#  define png_isaligned(ptr, type) 0
602
#endif
603
604
/* End of memory model/platform independent support */
605
/* End of 1.5.0beta36 move from pngconf.h */
606
607
/* CONSTANTS and UTILITY MACROS
608
 * These are used internally by libpng and not exposed in the API
609
 */
610
611
/* Various modes of operation.  Note that after an init, mode is set to
612
 * zero automatically when the structure is created.  Three of these
613
 * are defined in png.h because they need to be visible to applications
614
 * that call png_set_unknown_chunk().
615
 */
616
/* #define PNG_HAVE_IHDR            0x01U (defined in png.h) */
617
/* #define PNG_HAVE_PLTE            0x02U (defined in png.h) */
618
161k
#define PNG_HAVE_IDAT               0x04U
619
/* #define PNG_AFTER_IDAT           0x08U (defined in png.h) */
620
5.02k
#define PNG_HAVE_IEND               0x10U
621
                   /*               0x20U (unused) */
622
                   /*               0x40U (unused) */
623
                   /*               0x80U (unused) */
624
#define PNG_HAVE_CHUNK_HEADER      0x100U
625
68
#define PNG_WROTE_tIME             0x200U
626
#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
627
199k
#define PNG_BACKGROUND_IS_GRAY     0x800U
628
3.60k
#define PNG_HAVE_PNG_SIGNATURE    0x1000U
629
4.54k
#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
630
22
#define PNG_WROTE_eXIf            0x4000U
631
2.70k
#define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
632
633
/* Flags for the transformations the PNG library does on the image data */
634
118k
#define PNG_BGR                 0x0001U
635
536k
#define PNG_INTERLACE           0x0002U
636
121k
#define PNG_PACK                0x0004U
637
119k
#define PNG_SHIFT               0x0008U
638
118k
#define PNG_SWAP_BYTES          0x0010U
639
118k
#define PNG_INVERT_MONO         0x0020U
640
119k
#define PNG_QUANTIZE            0x0040U
641
134k
#define PNG_COMPOSE             0x0080U    /* Was PNG_BACKGROUND */
642
3.41k
#define PNG_BACKGROUND_EXPAND   0x0100U
643
122k
#define PNG_EXPAND_16           0x0200U    /* Added to libpng 1.5.2 */
644
119k
#define PNG_16_TO_8             0x0400U    /* Becomes 'chop' in 1.5.4 */
645
#define PNG_RGBA                0x0800U
646
125k
#define PNG_EXPAND              0x1000U
647
121k
#define PNG_GAMMA               0x2000U
648
240k
#define PNG_GRAY_TO_RGB         0x4000U
649
122k
#define PNG_FILLER              0x8000U
650
118k
#define PNG_PACKSWAP           0x10000U
651
118k
#define PNG_SWAP_ALPHA         0x20000U
652
239k
#define PNG_STRIP_ALPHA        0x40000U
653
118k
#define PNG_INVERT_ALPHA       0x80000U
654
121k
#define PNG_USER_TRANSFORM    0x100000U
655
0
#define PNG_RGB_TO_GRAY_ERR   0x200000U
656
0
#define PNG_RGB_TO_GRAY_WARN  0x400000U
657
131k
#define PNG_RGB_TO_GRAY       0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
658
122k
#define PNG_ENCODE_ALPHA      0x800000U /* Added to libpng-1.5.4 */
659
777
#define PNG_ADD_ALPHA        0x1000000U /* Added to libpng-1.2.7 */
660
14.1k
#define PNG_EXPAND_tRNS      0x2000000U /* Added to libpng-1.2.9 */
661
120k
#define PNG_SCALE_16_TO_8    0x4000000U /* Added to libpng-1.5.4 */
662
                       /*    0x8000000U unused */
663
                       /*   0x10000000U unused */
664
                       /*   0x20000000U unused */
665
                       /*   0x40000000U unused */
666
/* Flags for png_create_struct */
667
#define PNG_STRUCT_PNG   0x0001U
668
#define PNG_STRUCT_INFO  0x0002U
669
670
/* Flags for the png_ptr->flags rather than declaring a byte for each one */
671
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY     0x0001U
672
4.61k
#define PNG_FLAG_ZSTREAM_INITIALIZED      0x0002U /* Added to libpng-1.6.0 */
673
                                  /*      0x0004U    unused */
674
3.00k
#define PNG_FLAG_ZSTREAM_ENDED            0x0008U /* Added to libpng-1.6.0 */
675
                                  /*      0x0010U    unused */
676
                                  /*      0x0020U    unused */
677
622k
#define PNG_FLAG_ROW_INIT                 0x0040U
678
9.39k
#define PNG_FLAG_FILLER_AFTER             0x0080U
679
194k
#define PNG_FLAG_CRC_ANCILLARY_USE        0x0100U
680
198k
#define PNG_FLAG_CRC_ANCILLARY_NOWARN     0x0200U
681
3.71k
#define PNG_FLAG_CRC_CRITICAL_USE         0x0400U
682
21.2k
#define PNG_FLAG_CRC_CRITICAL_IGNORE      0x0800U
683
/*      PNG_FLAG_ASSUME_sRGB unused       0x1000U  * Added to libpng-1.5.4 */
684
2.63k
#define PNG_FLAG_OPTIMIZE_ALPHA           0x2000U /* Added to libpng-1.5.4 */
685
124k
#define PNG_FLAG_DETECT_UNINITIALIZED     0x4000U /* Added to libpng-1.5.4 */
686
/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS      0x8000U */
687
/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS      0x10000U */
688
2.22k
#define PNG_FLAG_LIBRARY_MISMATCH        0x20000U
689
#define PNG_FLAG_STRIP_ERROR_NUMBERS     0x40000U
690
#define PNG_FLAG_STRIP_ERROR_TEXT        0x80000U
691
22.1k
#define PNG_FLAG_BENIGN_ERRORS_WARN     0x100000U /* Added to libpng-1.4.0 */
692
2.65k
#define PNG_FLAG_APP_WARNINGS_WARN      0x200000U /* Added to libpng-1.6.0 */
693
425
#define PNG_FLAG_APP_ERRORS_WARN        0x400000U /* Added to libpng-1.6.0 */
694
                                  /*    0x800000U    unused */
695
                                  /*   0x1000000U    unused */
696
                                  /*   0x2000000U    unused */
697
                                  /*   0x4000000U    unused */
698
                                  /*   0x8000000U    unused */
699
                                  /*  0x10000000U    unused */
700
                                  /*  0x20000000U    unused */
701
                                  /*  0x40000000U    unused */
702
703
97.4k
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
704
97.4k
                                     PNG_FLAG_CRC_ANCILLARY_NOWARN)
705
706
1.80k
#define PNG_FLAG_CRC_CRITICAL_MASK  (PNG_FLAG_CRC_CRITICAL_USE | \
707
1.80k
                                     PNG_FLAG_CRC_CRITICAL_IGNORE)
708
709
#define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
710
                                     PNG_FLAG_CRC_CRITICAL_MASK)
711
712
/* Save typing and make code easier to understand */
713
714
0
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
715
0
   abs((int)((c1).green) - (int)((c2).green)) + \
716
0
   abs((int)((c1).blue) - (int)((c2).blue)))
717
718
/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255
719
 * by dividing by 257 *with rounding*.  This macro is exact for the given range.
720
 * See the discourse in pngrtran.c png_do_scale_16_to_8.  The values in the
721
 * macro were established by experiment (modifying the added value).  The macro
722
 * has a second variant that takes a value already scaled by 255 and divides by
723
 * 65535 - this has a maximum error of .502.  Over the range 0..65535*65535 it
724
 * only gives off-by-one errors and only for 0.5% (1 in 200) of the values.
725
 */
726
0
#define PNG_DIV65535(v24) (((v24) + 32895) >> 16)
727
0
#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255)
728
729
/* Added to libpng-1.2.6 JB */
730
#define PNG_ROWBYTES(pixel_bits, width) \
731
818k
    ((pixel_bits) >= 8 ? \
732
818k
    ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \
733
818k
    (( ((size_t)(width) * ((size_t)(pixel_bits))) + 7) >> 3) )
734
735
/* This returns the number of trailing bits in the last byte of a row, 0 if the
736
 * last byte is completely full of pixels.  It is, in principle, (pixel_bits x
737
 * width) % 8, but that would overflow for large 'width'.  The second macro is
738
 * the same except that it returns the number of unused bits in the last byte;
739
 * (8-TRAILBITS), but 0 when TRAILBITS is 0.
740
 *
741
 * NOTE: these macros are intended to be self-evidently correct and never
742
 * overflow on the assumption that pixel_bits is in the range 0..255.  The
743
 * arguments are evaluated only once and they can be signed (e.g. as a result of
744
 * the integral promotions).  The result of the expression always has type
745
 * (png_uint_32), however the compiler always knows it is in the range 0..7.
746
 */
747
#define PNG_TRAILBITS(pixel_bits, width) \
748
0
    (((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
749
750
#define PNG_PADBITS(pixel_bits, width) \
751
0
    ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
752
753
/* PNG_OUT_OF_RANGE returns true if value is outside the range
754
 * ideal-delta..ideal+delta.  Each argument is evaluated twice.
755
 * "ideal" and "delta" should be constants, normally simple
756
 * integers, "value" a variable. Added to libpng-1.2.6 JB
757
 */
758
#define PNG_OUT_OF_RANGE(value, ideal, delta) \
759
875
   ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
760
761
/* Conversions between fixed and floating point, only defined if
762
 * required (to make sure the code doesn't accidentally use float
763
 * when it is supposedly disabled.)
764
 */
765
#ifdef PNG_FLOATING_POINT_SUPPORTED
766
/* The floating point conversion can't overflow, though it can and
767
 * does lose accuracy relative to the original fixed point value.
768
 * In practice this doesn't matter because png_fixed_point only
769
 * stores numbers with very low precision.  The png_ptr and s
770
 * arguments are unused by default but are there in case error
771
 * checking becomes a requirement.
772
 */
773
0
#define png_float(png_ptr, fixed, s) (.00001 * (fixed))
774
775
/* The fixed point conversion performs range checking and evaluates
776
 * its argument multiple times, so must be used with care.  The
777
 * range checking uses the PNG specification values for a signed
778
 * 32-bit fixed point value except that the values are deliberately
779
 * rounded-to-zero to an integral value - 21474 (21474.83 is roughly
780
 * (2^31-1) * 100000). 's' is a string that describes the value being
781
 * converted.
782
 *
783
 * NOTE: this macro will raise a png_error if the range check fails,
784
 * therefore it is normally only appropriate to use this on values
785
 * that come from API calls or other sources where an out of range
786
 * error indicates a programming error, not a data error!
787
 *
788
 * NOTE: by default this is off - the macro is not used - because the
789
 * function call saves a lot of code.
790
 */
791
#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED
792
#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\
793
    ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0))
794
#define png_fixed_ITU(png_ptr, fp, s) ((fp) <= 214748 && (fp) >= 0 ?\
795
    ((png_uint_32)(10000 * (fp))) : (png_fixed_error(png_ptr, s),0))
796
#endif
797
/* else the corresponding function is defined below, inside the scope of the
798
 * cplusplus test.
799
 */
800
#endif
801
802
/* Constants for known chunk types.  If you need to add a chunk, define the name
803
 * here.  For historical reasons these constants have the form png_<name>; i.e.
804
 * the prefix is lower case.  Please use decimal values as the parameters to
805
 * match the ISO PNG specification and to avoid relying on the C locale
806
 * interpretation of character values.
807
 *
808
 * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values
809
 * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string
810
 * to be generated if required.
811
 *
812
 * PNG_32b correctly produces a value shifted by up to 24 bits, even on
813
 * architectures where (int) is only 16 bits.
814
 *
815
 * 1.6.47: PNG_32b was made into a preprocessor evaluable macro by replacing the
816
 * static_cast with a promoting binary operation using a guaranteed 32-bit
817
 * (minimum) unsigned value.
818
 */
819
1.34M
#define PNG_32b(b,s) (((0xFFFFFFFFU)&(b)) << (s))
820
#define PNG_U32(b1,b2,b3,b4) \
821
335k
   (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
822
823
/* Chunk name validation.  When using these macros all the arguments should be
824
 * constants, otherwise code bloat may well occur.  The macros are provided
825
 * primarily for use in #if checks.
826
 *
827
 * PNG_32to8 produces a byte value with the right shift; used to extract the
828
 * byte value from a chunk name.
829
 */
830
#define PNG_32to8(cn,s) (((cn) >> (s)) & 0xffU)
831
#define PNG_CN_VALID_UPPER(b) ((b) >= 65 && (b) <= 90) /* upper-case ASCII */
832
#define PNG_CN_VALID_ASCII(b) PNG_CN_VALID_UPPER((b) & ~32U)
833
#define PNG_CHUNK_NAME_VALID(cn) (\
834
   PNG_CN_VALID_ASCII(PNG_32to8(cn,24)) && /* critical, !ancillary */\
835
   PNG_CN_VALID_ASCII(PNG_32to8(cn,16)) && /* public, !privately defined */\
836
   PNG_CN_VALID_UPPER(PNG_32to8(cn, 8)) && /* VALID, !reserved */\
837
   PNG_CN_VALID_ASCII(PNG_32to8(cn, 0))   /* data-dependent, !copy ok */)
838
839
/* Constants for known chunk types.
840
 *
841
 * MAINTAINERS: If you need to add a chunk, define the name here.
842
 * For historical reasons these constants have the form png_<name>; i.e.
843
 * the prefix is lower case.  Please use decimal values as the parameters to
844
 * match the ISO PNG specification and to avoid relying on the C locale
845
 * interpretation of character values.  Please keep the list sorted.
846
 *
847
 * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk
848
 * type.  In fact the specification does not express chunk types this way,
849
 * however using a 32-bit value means that the chunk type can be read from the
850
 * stream using exactly the same code as used for a 32-bit unsigned value and
851
 * can be examined far more efficiently (using one arithmetic compare).
852
 *
853
 * Prior to 1.5.6 the chunk type constants were expressed as C strings.  The
854
 * libpng API still uses strings for 'unknown' chunks and a macro,
855
 * PNG_STRING_FROM_CHUNK, allows a string to be generated if required.  Notice
856
 * that for portable code numeric values must still be used; the string "IHDR"
857
 * is not portable and neither is PNG_U32('I', 'H', 'D', 'R').
858
 *
859
 * In 1.7.0 the definitions will be made public in png.h to avoid having to
860
 * duplicate the same definitions in application code.
861
 */
862
76.9k
#define png_IDAT PNG_U32( 73,  68,  65,  84)
863
36.3k
#define png_IEND PNG_U32( 73,  69,  78,  68)
864
39.8k
#define png_IHDR PNG_U32( 73,  72,  68,  82)
865
1.40k
#define png_PLTE PNG_U32( 80,  76,  84,  69)
866
105
#define png_acTL PNG_U32( 97,  99,  84,  76) /* PNGv3: APNG */
867
1.77k
#define png_bKGD PNG_U32( 98,  75,  71,  68)
868
5.42k
#define png_cHRM PNG_U32( 99,  72,  82,  77)
869
794
#define png_cICP PNG_U32( 99,  73,  67,  80) /* PNGv3 */
870
1.16k
#define png_cLLI PNG_U32( 99,  76,  76,  73) /* PNGv3 */
871
117
#define png_eXIf PNG_U32(101,  88,  73, 102) /* registered July 2017 */
872
3
#define png_fcTL PNG_U32(102,  99,  84,  76) /* PNGv3: APNG */
873
3
#define png_fdAT PNG_U32(102, 100,  65,  84) /* PNGv3: APNG */
874
#define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
875
1.81k
#define png_gAMA PNG_U32(103,  65,  77,  65)
876
#define png_gIFg PNG_U32(103,  73,  70, 103)
877
#define png_gIFt PNG_U32(103,  73,  70, 116) /* deprecated */
878
#define png_gIFx PNG_U32(103,  73,  70, 120)
879
23
#define png_hIST PNG_U32(104,  73,  83,  84)
880
1.06k
#define png_iCCP PNG_U32(105,  67,  67,  80)
881
1.69k
#define png_iTXt PNG_U32(105,  84,  88, 116)
882
921
#define png_mDCV PNG_U32(109,  68,  67,  86) /* PNGv3 */
883
972
#define png_oFFs PNG_U32(111,  70,  70, 115)
884
2.12k
#define png_pCAL PNG_U32(112,  67,  65,  76)
885
66
#define png_pHYs PNG_U32(112,  72,  89, 115)
886
1.67k
#define png_sBIT PNG_U32(115,  66,  73,  84)
887
1.05k
#define png_sCAL PNG_U32(115,  67,  65,  76)
888
857
#define png_sPLT PNG_U32(115,  80,  76,  84)
889
677
#define png_sRGB PNG_U32(115,  82,  71,  66)
890
#define png_sTER PNG_U32(115,  84,  69,  82)
891
5.54k
#define png_tEXt PNG_U32(116,  69,  88, 116)
892
73
#define png_tIME PNG_U32(116,  73,  77,  69)
893
2.17k
#define png_tRNS PNG_U32(116,  82,  78,  83)
894
349
#define png_zTXt PNG_U32(122,  84,  88, 116)
895
896
/* The following will work on (signed char*) strings, whereas the get_uint_32
897
 * macro will fail on top-bit-set values because of the sign extension.
898
 */
899
#define PNG_CHUNK_FROM_STRING(s)\
900
38.1k
   PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3])
901
902
/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
903
 * signed and the argument is a (char[])  This macro will fail miserably on
904
 * systems where (char) is more than 8 bits.
905
 */
906
#define PNG_STRING_FROM_CHUNK(s,c)\
907
35.2k
   (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \
908
35.2k
   ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\
909
35.2k
   ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \
910
35.2k
   ((char*)(s))[3]=(char)((c & 0xff)))
911
912
/* Do the same but terminate with a null character. */
913
#define PNG_CSTRING_FROM_CHUNK(s,c)\
914
35.2k
   (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0)
915
916
/* Test on flag values as defined in the spec (section 5.4): */
917
127k
#define PNG_CHUNK_ANCILLARY(c)   (1 & ((c) >> 29))
918
12.3k
#define PNG_CHUNK_CRITICAL(c)     (!PNG_CHUNK_ANCILLARY(c))
919
#define PNG_CHUNK_PRIVATE(c)      (1 & ((c) >> 21))
920
#define PNG_CHUNK_RESERVED(c)     (1 & ((c) >> 13))
921
#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >>  5))
922
923
/* Known chunks.  All supported chunks must be listed here.  The macro PNG_CHUNK
924
 * contains the four character ASCII name by which the chunk is identified.  The
925
 * macro is implemented as required to build tables or switch statements which
926
 * require entries for every known chunk.  The macro also contains an index
927
 * value which should be in order (this is checked in png.c).
928
 *
929
 * Notice that "known" does not require "SUPPORTED"; tables should be built in
930
 * such a way that chunks unsupported in a build require no more than the table
931
 * entry (which should be small.)  In particular function pointers for
932
 * unsupported chunks should be NULL.
933
 *
934
 * At present these index values are not exported (not part of the public API)
935
 * so can be changed at will.  For convenience the names are in lexical sort
936
 * order but with the critical chunks at the start in the order of occurence in
937
 * a PNG.
938
 *
939
 * PNG_INFO_ values do not exist for every one of these chunk handles; for
940
 * example PNG_INFO_{IDAT,IEND,tEXt,iTXt,zTXt} and possibly other chunks in the
941
 * future.
942
 */
943
#define PNG_KNOWN_CHUNKS\
944
2.20k
   PNG_CHUNK(IHDR,  0)\
945
2.20k
   PNG_CHUNK(PLTE,  1)\
946
1.40k
   PNG_CHUNK(IDAT,  2)\
947
427
   PNG_CHUNK(IEND,  3)\
948
427
   PNG_CHUNK(acTL,  4)\
949
1.77k
   PNG_CHUNK(bKGD,  5)\
950
5.42k
   PNG_CHUNK(cHRM,  6)\
951
5.42k
   PNG_CHUNK(cICP,  7)\
952
1.16k
   PNG_CHUNK(cLLI,  8)\
953
1.16k
   PNG_CHUNK(eXIf,  9)\
954
117
   PNG_CHUNK(fcTL, 10)\
955
3
   PNG_CHUNK(fdAT, 11)\
956
1.81k
   PNG_CHUNK(gAMA, 12)\
957
1.81k
   PNG_CHUNK(hIST, 13)\
958
556
   PNG_CHUNK(iCCP, 14)\
959
1.69k
   PNG_CHUNK(iTXt, 15)\
960
1.69k
   PNG_CHUNK(mDCV, 16)\
961
972
   PNG_CHUNK(oFFs, 17)\
962
2.12k
   PNG_CHUNK(pCAL, 18)\
963
2.12k
   PNG_CHUNK(pHYs, 19)\
964
1.67k
   PNG_CHUNK(sBIT, 20)\
965
1.67k
   PNG_CHUNK(sCAL, 21)\
966
1.05k
   PNG_CHUNK(sPLT, 22)\
967
857
   PNG_CHUNK(sRGB, 23)\
968
5.54k
   PNG_CHUNK(tEXt, 24)\
969
5.54k
   PNG_CHUNK(tIME, 25)\
970
2.17k
   PNG_CHUNK(tRNS, 26)\
971
2.17k
   PNG_CHUNK(zTXt, 27)
972
973
/* Gamma values (new at libpng-1.5.4): */
974
0
#define PNG_GAMMA_MAC_OLD 151724  /* Assume '1.8' is really 2.2/1.45! */
975
0
#define PNG_GAMMA_MAC_INVERSE 65909
976
219
#define PNG_GAMMA_sRGB_INVERSE 45455
977
978
/* gamma sanity check.  libpng cannot implement gamma transforms outside a
979
 * certain limit because of its use of 16-bit fixed point intermediate values.
980
 * Gamma values that are too large or too small will zap the 16-bit values all
981
 * to 0 or 65535 resulting in an obvious 'bad' image.
982
 *
983
 * In libpng 1.6.0 the limits were changed from 0.07..3 to 0.01..100 to
984
 * accommodate the optimal 16-bit gamma of 36 and its reciprocal.
985
 *
986
 * These are png_fixed_point integral values:
987
 */
988
1.67k
#define PNG_LIB_GAMMA_MIN 1000
989
838
#define PNG_LIB_GAMMA_MAX 10000000
990
991
/* Almost everything below is C specific; the #defines above can be used in
992
 * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot.
993
 */
994
#ifndef PNG_VERSION_INFO_ONLY
995
996
#include "pngstruct.h"
997
#include "pnginfo.h"
998
999
/* Validate the include paths - the include path used to generate pnglibconf.h
1000
 * must match that used in the build, or we must be using pnglibconf.h.prebuilt:
1001
 */
1002
#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM
1003
#  error The include path of <zlib.h> is incorrect
1004
   /* When pnglibconf.h was built, the copy of zlib.h that it used was not the
1005
    * same as the one being used here.  Considering how libpng makes decisions
1006
    * to use the zlib API based on the zlib version number, the -I options must
1007
    * match.
1008
    *
1009
    * A possible cause of this mismatch is that you passed an -I option in
1010
    * CFLAGS, which is unlikely to work.  All the preprocessor options, and all
1011
    * the -I options in particular, should be in CPPFLAGS.
1012
    */
1013
#endif
1014
1015
/* This is used for 16-bit gamma tables -- only the top level pointers are
1016
 * const; this could be changed:
1017
 */
1018
typedef const png_uint_16p * png_const_uint_16pp;
1019
1020
/* Added to libpng-1.5.7: sRGB conversion tables */
1021
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
1022
   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
1023
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
1024
PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]);
1025
   /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value,
1026
    * 0..65535.  This table gives the closest 16-bit answers (no errors).
1027
    */
1028
#endif
1029
1030
PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]);
1031
PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]);
1032
1033
#define PNG_sRGB_FROM_LINEAR(linear) \
1034
0
  ((png_byte)(0xff & ((png_sRGB_base[(linear)>>15] \
1035
0
   + ((((linear) & 0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)))
1036
   /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
1037
    * encoded value with maximum error 0.646365.  Note that the input is not a
1038
    * 16-bit value; it has been multiplied by 255! */
1039
#endif /* SIMPLIFIED_READ/WRITE */
1040
1041
1042
/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
1043
#ifdef __cplusplus
1044
extern "C" {
1045
#endif /* __cplusplus */
1046
1047
/* Internal functions; these are not exported from a DLL however because they
1048
 * are used within several of the C source files they have to be C extern.
1049
 *
1050
 * All of these functions must be declared with PNG_INTERNAL_FUNCTION.
1051
 */
1052
/* Zlib support */
1053
0
#define PNG_UNEXPECTED_ZLIB_RETURN (-7)
1054
PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
1055
   PNG_EMPTY);
1056
   /* Used by the zlib handling functions to ensure that z_stream::msg is always
1057
    * set before they return.
1058
    */
1059
1060
#ifdef PNG_WRITE_SUPPORTED
1061
PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
1062
   png_compression_bufferp *list),PNG_EMPTY);
1063
   /* Free the buffer list used by the compressed write code. */
1064
#endif
1065
1066
#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
1067
   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
1068
   (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
1069
   defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
1070
   defined(PNG_mDCV_SUPPORTED) || \
1071
   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
1072
   (defined(PNG_sCAL_SUPPORTED) && \
1073
   defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
1074
PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,
1075
   double fp, png_const_charp text),PNG_EMPTY);
1076
#endif
1077
1078
#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
1079
   !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
1080
   (defined(PNG_cLLI_SUPPORTED) || defined(PNG_mDCV_SUPPORTED))
1081
PNG_INTERNAL_FUNCTION(png_uint_32,png_fixed_ITU,(png_const_structrp png_ptr,
1082
   double fp, png_const_charp text),PNG_EMPTY);
1083
#endif
1084
1085
/* Check the user version string for compatibility, returns false if the version
1086
 * numbers aren't compatible.
1087
 */
1088
PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
1089
   png_const_charp user_png_ver),PNG_EMPTY);
1090
1091
#ifdef PNG_READ_SUPPORTED /* should only be used on read */
1092
/* Security: read limits on the largest allocations while reading a PNG.  This
1093
 * avoids very large allocations caused by PNG files with damaged or altered
1094
 * chunk 'length' fields.
1095
 */
1096
#ifdef PNG_SET_USER_LIMITS_SUPPORTED /* run-time limit */
1097
16.7k
#  define png_chunk_max(png_ptr) ((png_ptr)->user_chunk_malloc_max)
1098
1099
#elif PNG_USER_CHUNK_MALLOC_MAX > 0 /* compile-time limit */
1100
#  define png_chunk_max(png_ptr) ((void)png_ptr, PNG_USER_CHUNK_MALLOC_MAX)
1101
1102
#elif (defined PNG_MAX_MALLOC_64K)  /* legacy system limit */
1103
#  define png_chunk_max(png_ptr) ((void)png_ptr, 65536U)
1104
1105
#else                               /* modern system limit SIZE_MAX (C99) */
1106
#  define png_chunk_max(png_ptr) ((void)png_ptr, PNG_SIZE_MAX)
1107
#endif
1108
#endif /* READ */
1109
1110
/* Internal base allocator - no messages, NULL on failure to allocate.  This
1111
 * does, however, call the application provided allocator and that could call
1112
 * png_error (although that would be a bug in the application implementation.)
1113
 */
1114
PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr,
1115
   png_alloc_size_t size),PNG_ALLOCATED);
1116
1117
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
1118
   defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
1119
/* Internal array allocator, outputs no error or warning messages on failure,
1120
 * just returns NULL.
1121
 */
1122
PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr,
1123
   int nelements, size_t element_size),PNG_ALLOCATED);
1124
1125
/* The same but an existing array is extended by add_elements.  This function
1126
 * also memsets the new elements to 0 and copies the old elements.  The old
1127
 * array is not freed or altered.
1128
 */
1129
PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr,
1130
   png_const_voidp array, int old_elements, int add_elements,
1131
   size_t element_size),PNG_ALLOCATED);
1132
#endif /* text, sPLT or unknown chunks */
1133
1134
/* Magic to create a struct when there is no struct to call the user supplied
1135
 * memory allocators.  Because error handling has not been set up the memory
1136
 * handlers can't safely call png_error, but this is an obscure and undocumented
1137
 * restriction so libpng has to assume that the 'free' handler, at least, might
1138
 * call png_error.
1139
 */
1140
PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct,
1141
   (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
1142
    png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
1143
    png_free_ptr free_fn),PNG_ALLOCATED);
1144
1145
/* Free memory from internal libpng struct */
1146
PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr),
1147
   PNG_EMPTY);
1148
1149
/* Free an allocated jmp_buf (always succeeds) */
1150
PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY);
1151
1152
/* Function to allocate memory for zlib.  PNGAPI is disallowed. */
1153
PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size),
1154
   PNG_ALLOCATED);
1155
1156
/* Function to free memory for zlib.  PNGAPI is disallowed. */
1157
PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);
1158
1159
/* Next four functions are used internally as callbacks.  PNGCBAPI is required
1160
 * but not PNG_EXPORT.  PNGAPI added at libpng version 1.2.3, changed to
1161
 * PNGCBAPI at 1.5.0
1162
 */
1163
1164
PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
1165
    png_bytep data, size_t length),PNG_EMPTY);
1166
1167
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1168
PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
1169
    png_bytep buffer, size_t length),PNG_EMPTY);
1170
#endif
1171
1172
PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
1173
    png_bytep data, size_t length),PNG_EMPTY);
1174
1175
#ifdef PNG_WRITE_FLUSH_SUPPORTED
1176
#  ifdef PNG_STDIO_SUPPORTED
1177
PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr),
1178
   PNG_EMPTY);
1179
#  endif
1180
#endif
1181
1182
/* Reset the CRC variable */
1183
PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
1184
1185
/* Write the "data" buffer to whatever output you are using */
1186
PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
1187
    png_const_bytep data, size_t length),PNG_EMPTY);
1188
1189
/* Read and check the PNG file signature */
1190
PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,
1191
   png_inforp info_ptr),PNG_EMPTY);
1192
1193
/* Read the chunk header (length + type name) */
1194
PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),
1195
   PNG_EMPTY);
1196
1197
/* Read data from whatever input you are using into the "data" buffer */
1198
PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
1199
    size_t length),PNG_EMPTY);
1200
1201
/* Read bytes into buf, and update png_ptr->crc */
1202
PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
1203
    png_uint_32 length),PNG_EMPTY);
1204
1205
/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
1206
PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr,
1207
   png_uint_32 skip),PNG_EMPTY);
1208
1209
/* Calculate the CRC over a section of data.  Note that we are only
1210
 * passing a maximum of 64K on systems that have this as a memory limit,
1211
 * since this is the maximum buffer size we can specify.
1212
 */
1213
PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
1214
   png_const_bytep ptr, size_t length),PNG_EMPTY);
1215
1216
#ifdef PNG_WRITE_FLUSH_SUPPORTED
1217
PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
1218
#endif
1219
1220
/* Write various chunks */
1221
1222
/* Write the IHDR chunk, and update the png_struct with the necessary
1223
 * information.
1224
 */
1225
PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr,
1226
   png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
1227
   int compression_method, int filter_method, int interlace_method),PNG_EMPTY);
1228
1229
PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,
1230
   png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);
1231
1232
PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr,
1233
   png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
1234
   PNG_EMPTY);
1235
1236
PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);
1237
1238
#ifdef PNG_WRITE_gAMA_SUPPORTED
1239
PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr,
1240
    png_fixed_point file_gamma),PNG_EMPTY);
1241
#endif
1242
1243
#ifdef PNG_WRITE_sBIT_SUPPORTED
1244
PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
1245
    png_const_color_8p sbit, int color_type),PNG_EMPTY);
1246
#endif
1247
1248
#ifdef PNG_WRITE_cHRM_SUPPORTED
1249
PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
1250
    const png_xy *xy), PNG_EMPTY);
1251
   /* The xy value must have been previously validated */
1252
#endif
1253
1254
#ifdef PNG_WRITE_cICP_SUPPORTED
1255
PNG_INTERNAL_FUNCTION(void,png_write_cICP,(png_structrp png_ptr,
1256
    png_byte colour_primaries, png_byte transfer_function,
1257
    png_byte matrix_coefficients, png_byte video_full_range_flag), PNG_EMPTY);
1258
#endif
1259
1260
#ifdef PNG_WRITE_cLLI_SUPPORTED
1261
PNG_INTERNAL_FUNCTION(void,png_write_cLLI_fixed,(png_structrp png_ptr,
1262
   png_uint_32 maxCLL, png_uint_32 maxFALL), PNG_EMPTY);
1263
#endif
1264
1265
#ifdef PNG_WRITE_mDCV_SUPPORTED
1266
PNG_INTERNAL_FUNCTION(void,png_write_mDCV_fixed,(png_structrp png_ptr,
1267
   png_uint_16 red_x, png_uint_16 red_y,
1268
   png_uint_16 green_x, png_uint_16 green_y,
1269
   png_uint_16 blue_x, png_uint_16 blue_y,
1270
   png_uint_16 white_x, png_uint_16 white_y,
1271
   png_uint_32 maxDL, png_uint_32 minDL), PNG_EMPTY);
1272
#endif
1273
1274
#ifdef PNG_WRITE_sRGB_SUPPORTED
1275
PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
1276
    int intent),PNG_EMPTY);
1277
#endif
1278
1279
#ifdef PNG_WRITE_eXIf_SUPPORTED
1280
PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
1281
    png_bytep exif, int num_exif),PNG_EMPTY);
1282
#endif
1283
1284
#ifdef PNG_WRITE_iCCP_SUPPORTED
1285
PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
1286
   png_const_charp name, png_const_bytep profile, png_uint_32 proflen),
1287
   PNG_EMPTY);
1288
   /* Writes a previously 'set' profile.  The profile argument is **not**
1289
    * compressed.
1290
    */
1291
#endif
1292
1293
#ifdef PNG_WRITE_sPLT_SUPPORTED
1294
PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr,
1295
    png_const_sPLT_tp palette),PNG_EMPTY);
1296
#endif
1297
1298
#ifdef PNG_WRITE_tRNS_SUPPORTED
1299
PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr,
1300
    png_const_bytep trans, png_const_color_16p values, int number,
1301
    int color_type),PNG_EMPTY);
1302
#endif
1303
1304
#ifdef PNG_WRITE_bKGD_SUPPORTED
1305
PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr,
1306
    png_const_color_16p values, int color_type),PNG_EMPTY);
1307
#endif
1308
1309
#ifdef PNG_WRITE_hIST_SUPPORTED
1310
PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
1311
    png_const_uint_16p hist, int num_hist),PNG_EMPTY);
1312
#endif
1313
1314
/* Chunks that have keywords */
1315
#ifdef PNG_WRITE_tEXt_SUPPORTED
1316
PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
1317
   png_const_charp key, png_const_charp text, size_t text_len),PNG_EMPTY);
1318
#endif
1319
1320
#ifdef PNG_WRITE_zTXt_SUPPORTED
1321
PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp
1322
    key, png_const_charp text, int compression),PNG_EMPTY);
1323
#endif
1324
1325
#ifdef PNG_WRITE_iTXt_SUPPORTED
1326
PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr,
1327
    int compression, png_const_charp key, png_const_charp lang,
1328
    png_const_charp lang_key, png_const_charp text),PNG_EMPTY);
1329
#endif
1330
1331
#ifdef PNG_TEXT_SUPPORTED  /* Added at version 1.0.14 and 1.2.4 */
1332
PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr,
1333
    png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY);
1334
#endif
1335
1336
#ifdef PNG_WRITE_oFFs_SUPPORTED
1337
PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr,
1338
    png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY);
1339
#endif
1340
1341
#ifdef PNG_WRITE_pCAL_SUPPORTED
1342
PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr,
1343
    png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
1344
    png_const_charp units, png_charpp params),PNG_EMPTY);
1345
#endif
1346
1347
#ifdef PNG_WRITE_pHYs_SUPPORTED
1348
PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr,
1349
    png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
1350
    int unit_type),PNG_EMPTY);
1351
#endif
1352
1353
#ifdef PNG_WRITE_tIME_SUPPORTED
1354
PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr,
1355
    png_const_timep mod_time),PNG_EMPTY);
1356
#endif
1357
1358
#ifdef PNG_WRITE_sCAL_SUPPORTED
1359
PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr,
1360
    int unit, png_const_charp width, png_const_charp height),PNG_EMPTY);
1361
#endif
1362
1363
/* Called when finished processing a row of data */
1364
PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr),
1365
    PNG_EMPTY);
1366
1367
/* Internal use only.   Called before first row of data */
1368
PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr),
1369
    PNG_EMPTY);
1370
1371
/* Combine a row of data, dealing with alpha, etc. if requested.  'row' is an
1372
 * array of png_ptr->width pixels.  If the image is not interlaced or this
1373
 * is the final pass this just does a memcpy, otherwise the "display" flag
1374
 * is used to determine whether to copy pixels that are not in the current pass.
1375
 *
1376
 * Because 'png_do_read_interlace' (below) replicates pixels this allows this
1377
 * function to achieve the documented 'blocky' appearance during interlaced read
1378
 * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row'
1379
 * are not changed if they are not in the current pass, when display is 0.
1380
 *
1381
 * 'display' must be 0 or 1, otherwise the memcpy will be done regardless.
1382
 *
1383
 * The API always reads from the png_struct row buffer and always assumes that
1384
 * it is full width (png_do_read_interlace has already been called.)
1385
 *
1386
 * This function is only ever used to write to row buffers provided by the
1387
 * caller of the relevant libpng API and the row must have already been
1388
 * transformed by the read transformations.
1389
 *
1390
 * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed
1391
 * bitmasks for use within the code, otherwise runtime generated masks are used.
1392
 * The default is compile time masks.
1393
 */
1394
#ifndef PNG_USE_COMPILE_TIME_MASKS
1395
#  define PNG_USE_COMPILE_TIME_MASKS 1
1396
#endif
1397
PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr,
1398
    png_bytep row, int display),PNG_EMPTY);
1399
1400
#ifdef PNG_READ_INTERLACING_SUPPORTED
1401
/* Expand an interlaced row: the 'row_info' describes the pass data that has
1402
 * been read in and must correspond to the pixels in 'row', the pixels are
1403
 * expanded (moved apart) in 'row' to match the final layout, when doing this
1404
 * the pixels are *replicated* to the intervening space.  This is essential for
1405
 * the correct operation of png_combine_row, above.
1406
 */
1407
PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info,
1408
    png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY);
1409
#endif
1410
1411
/* GRR TO DO (2.0 or whenever):  simplify other internal calling interfaces */
1412
1413
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
1414
/* Grab pixels out of a row for an interlaced pass */
1415
PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
1416
    png_bytep row, int pass),PNG_EMPTY);
1417
#endif
1418
1419
/* Unfilter a row: check the filter value before calling this, there is no point
1420
 * calling it for PNG_FILTER_VALUE_NONE.
1421
 */
1422
PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
1423
    row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
1424
1425
#if PNG_ARM_NEON_OPT > 0
1426
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
1427
    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1428
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
1429
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1430
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop
1431
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1432
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop
1433
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1434
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop
1435
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1436
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
1437
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1438
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
1439
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1440
#endif
1441
1442
#if PNG_MIPS_MSA_IMPLEMENTATION == 1
1443
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
1444
    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1445
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
1446
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1447
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop
1448
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1449
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop
1450
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1451
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop
1452
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1453
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop
1454
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1455
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
1456
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1457
#endif
1458
1459
#if PNG_MIPS_MMI_IMPLEMENTATION > 0
1460
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_mmi,(png_row_infop row_info,
1461
    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1462
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_mmi,(png_row_infop
1463
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1464
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_mmi,(png_row_infop
1465
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1466
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_mmi,(png_row_infop
1467
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1468
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_mmi,(png_row_infop
1469
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1470
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_mmi,(png_row_infop
1471
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1472
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_mmi,(png_row_infop
1473
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1474
#endif
1475
1476
#if PNG_POWERPC_VSX_OPT > 0
1477
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
1478
    png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1479
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop
1480
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1481
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop
1482
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1483
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop
1484
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1485
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop
1486
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1487
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop
1488
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1489
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop
1490
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1491
#endif
1492
1493
#if PNG_INTEL_SSE_IMPLEMENTATION > 0
1494
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
1495
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1496
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
1497
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1498
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
1499
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1500
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
1501
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1502
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
1503
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1504
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
1505
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1506
#endif
1507
1508
#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1
1509
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_lsx,(png_row_infop
1510
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1511
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_lsx,(png_row_infop
1512
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1513
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_lsx,(png_row_infop
1514
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1515
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_lsx,(png_row_infop
1516
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1517
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_lsx,(png_row_infop
1518
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1519
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_lsx,(png_row_infop
1520
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1521
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop
1522
    row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
1523
#endif
1524
1525
/* Choose the best filter to use and filter the row data */
1526
PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
1527
    png_row_infop row_info),PNG_EMPTY);
1528
1529
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1530
PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
1531
   png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
1532
   /* Read 'avail_out' bytes of data from the IDAT stream.  If the output buffer
1533
    * is NULL the function checks, instead, for the end of the stream.  In this
1534
    * case a benign error will be issued if the stream end is not found or if
1535
    * extra data has to be consumed.
1536
    */
1537
PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr),
1538
   PNG_EMPTY);
1539
   /* This cleans up when the IDAT LZ stream does not end when the last image
1540
    * byte is read; there is still some pending input.
1541
    */
1542
1543
PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
1544
   PNG_EMPTY);
1545
   /* Finish a row while reading, dealing with interlacing passes, etc. */
1546
#endif /* SEQUENTIAL_READ */
1547
1548
/* Initialize the row buffers, etc. */
1549
PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
1550
1551
#if ZLIB_VERNUM >= 0x1240
1552
PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
1553
      PNG_EMPTY);
1554
137k
#  define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
1555
#else /* Zlib < 1.2.4 */
1556
#  define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)
1557
#endif /* Zlib < 1.2.4 */
1558
1559
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1560
/* Optional call to update the users info structure */
1561
PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
1562
    png_inforp info_ptr),PNG_EMPTY);
1563
#endif
1564
1565
/* Shared transform functions, defined in pngtran.c */
1566
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
1567
    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1568
PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info,
1569
    png_bytep row, int at_start),PNG_EMPTY);
1570
#endif
1571
1572
#ifdef PNG_16BIT_SUPPORTED
1573
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
1574
PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info,
1575
    png_bytep row),PNG_EMPTY);
1576
#endif
1577
#endif
1578
1579
#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
1580
    defined(PNG_WRITE_PACKSWAP_SUPPORTED)
1581
PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info,
1582
    png_bytep row),PNG_EMPTY);
1583
#endif
1584
1585
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
1586
PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info,
1587
    png_bytep row),PNG_EMPTY);
1588
#endif
1589
1590
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
1591
PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,
1592
    png_bytep row),PNG_EMPTY);
1593
#endif
1594
1595
/* The following decodes the appropriate chunks, and does error correction,
1596
 * then calls the appropriate callback for the chunk if it is valid.
1597
 */
1598
typedef enum
1599
{
1600
   /* Result of a call to png_handle_chunk made to handle the current chunk
1601
    * png_struct::chunk_name on read.  Always informational, either the stream
1602
    * is read for the next chunk or the routine will call png_error.
1603
    *
1604
    * NOTE: order is important internally.  handled_saved and above are regarded
1605
    * as handling the chunk.
1606
    */
1607
   handled_error = 0,  /* bad crc or known and bad format or too long */
1608
   handled_discarded,  /* not saved in the unknown chunk list */
1609
   handled_saved,      /* saved in the unknown chunk list */
1610
   handled_ok          /* known, supported and handled without error */
1611
} png_handle_result_code;
1612
1613
PNG_INTERNAL_FUNCTION(png_handle_result_code,png_handle_unknown,
1614
    (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep),
1615
    PNG_EMPTY);
1616
   /* This is the function that gets called for unknown chunks.  The 'keep'
1617
    * argument is either non-zero for a known chunk that has been set to be
1618
    * handled as unknown or zero for an unknown chunk.  By default the function
1619
    * just skips the chunk or errors out if it is critical.
1620
    */
1621
1622
PNG_INTERNAL_FUNCTION(png_handle_result_code,png_handle_chunk,
1623
    (png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
1624
   /* This handles the current chunk png_ptr->chunk_name with unread
1625
    * data[length] and returns one of the above result codes.
1626
    */
1627
1628
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
1629
    defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
1630
PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
1631
    (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);
1632
   /* Exactly as the API png_handle_as_unknown() except that the argument is a
1633
    * 32-bit chunk name, not a string.
1634
    */
1635
#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
1636
1637
/* Handle the transformations for reading and writing */
1638
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1639
PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,
1640
   png_row_infop row_info),PNG_EMPTY);
1641
#endif
1642
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
1643
PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,
1644
   png_row_infop row_info),PNG_EMPTY);
1645
#endif
1646
1647
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1648
PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr),
1649
    PNG_EMPTY);
1650
#endif
1651
1652
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1653
PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr,
1654
    png_inforp info_ptr),PNG_EMPTY);
1655
PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr,
1656
    png_inforp info_ptr),PNG_EMPTY);
1657
PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY);
1658
PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),
1659
    PNG_EMPTY);
1660
PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
1661
    png_bytep buffer, size_t buffer_length),PNG_EMPTY);
1662
PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);
1663
PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
1664
    png_bytep buffer, size_t buffer_length),PNG_EMPTY);
1665
PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
1666
    PNG_EMPTY);
1667
PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
1668
   png_inforp info_ptr),PNG_EMPTY);
1669
PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
1670
   png_inforp info_ptr),PNG_EMPTY);
1671
PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
1672
    png_bytep row),PNG_EMPTY);
1673
PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
1674
    png_inforp info_ptr),PNG_EMPTY);
1675
PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
1676
    png_inforp info_ptr),PNG_EMPTY);
1677
PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr),
1678
    PNG_EMPTY);
1679
#endif /* PROGRESSIVE_READ */
1680
1681
#ifdef PNG_iCCP_SUPPORTED
1682
/* Routines for checking parts of an ICC profile. */
1683
#ifdef PNG_READ_iCCP_SUPPORTED
1684
PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
1685
   png_const_charp name, png_uint_32 profile_length), PNG_EMPTY);
1686
#endif /* READ_iCCP */
1687
PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
1688
   png_const_charp name, png_uint_32 profile_length,
1689
   png_const_bytep profile /* first 132 bytes only */, int color_type),
1690
   PNG_EMPTY);
1691
PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr,
1692
   png_const_charp name, png_uint_32 profile_length,
1693
   png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);
1694
#endif /* iCCP */
1695
1696
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1697
PNG_INTERNAL_FUNCTION(void,png_set_rgb_coefficients, (png_structrp png_ptr),
1698
   PNG_EMPTY);
1699
   /* Set the rgb_to_gray coefficients from the cHRM Y values (if unset) */
1700
#endif /* READ_RGB_TO_GRAY */
1701
1702
/* Added at libpng version 1.4.0 */
1703
PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,
1704
    png_uint_32 width, png_uint_32 height, int bit_depth,
1705
    int color_type, int interlace_type, int compression_type,
1706
    int filter_type),PNG_EMPTY);
1707
1708
/* Added at libpng version 1.5.10 */
1709
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
1710
    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
1711
PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes,
1712
   (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY);
1713
#endif
1714
1715
#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
1716
PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,
1717
   png_const_charp name),PNG_NORETURN);
1718
#endif
1719
1720
/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite
1721
 * the end.  Always leaves the buffer nul terminated.  Never errors out (and
1722
 * there is no error code.)
1723
 */
1724
PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize,
1725
   size_t pos, png_const_charp string),PNG_EMPTY);
1726
1727
/* Various internal functions to handle formatted warning messages, currently
1728
 * only implemented for warnings.
1729
 */
1730
#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
1731
/* Utility to dump an unsigned value into a buffer, given a start pointer and
1732
 * and end pointer (which should point just *beyond* the end of the buffer!)
1733
 * Returns the pointer to the start of the formatted string.  This utility only
1734
 * does unsigned values.
1735
 */
1736
PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start,
1737
   png_charp end, int format, png_alloc_size_t number),PNG_EMPTY);
1738
1739
/* Convenience macro that takes an array: */
1740
#define PNG_FORMAT_NUMBER(buffer,format,number) \
1741
0
   png_format_number(buffer, buffer + (sizeof buffer), format, number)
1742
1743
/* Suggested size for a number buffer (enough for 64 bits and a sign!) */
1744
#define PNG_NUMBER_BUFFER_SIZE 24
1745
1746
/* These are the integer formats currently supported, the name is formed from
1747
 * the standard printf(3) format string.
1748
 */
1749
0
#define PNG_NUMBER_FORMAT_u     1 /* chose unsigned API! */
1750
0
#define PNG_NUMBER_FORMAT_02u   2
1751
#define PNG_NUMBER_FORMAT_d     1 /* chose signed API! */
1752
#define PNG_NUMBER_FORMAT_02d   2
1753
305
#define PNG_NUMBER_FORMAT_x     3
1754
0
#define PNG_NUMBER_FORMAT_02x   4
1755
270
#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */
1756
#endif
1757
1758
#ifdef PNG_WARNINGS_SUPPORTED
1759
/* New defines and members adding in libpng-1.5.4 */
1760
#  define PNG_WARNING_PARAMETER_SIZE 32
1761
0
#  define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */
1762
1763
/* An l-value of this type has to be passed to the APIs below to cache the
1764
 * values of the parameters to a formatted warning message.
1765
 */
1766
typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][
1767
   PNG_WARNING_PARAMETER_SIZE];
1768
1769
PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p,
1770
   int number, png_const_charp string),PNG_EMPTY);
1771
   /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters,
1772
    * including the trailing '\0'.
1773
    */
1774
PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned,
1775
   (png_warning_parameters p, int number, int format, png_alloc_size_t value),
1776
   PNG_EMPTY);
1777
   /* Use png_alloc_size_t because it is an unsigned type as big as any we
1778
    * need to output.  Use the following for a signed value.
1779
    */
1780
PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed,
1781
   (png_warning_parameters p, int number, int format, png_int_32 value),
1782
   PNG_EMPTY);
1783
1784
PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr,
1785
   png_warning_parameters p, png_const_charp message),PNG_EMPTY);
1786
   /* 'message' follows the X/Open approach of using @1, @2 to insert
1787
    * parameters previously supplied using the above functions.  Errors in
1788
    * specifying the parameters will simply result in garbage substitutions.
1789
    */
1790
#endif
1791
1792
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1793
/* Application errors (new in 1.6); use these functions (declared below) for
1794
 * errors in the parameters or order of API function calls on read.  The
1795
 * 'warning' should be used for an error that can be handled completely; the
1796
 * 'error' for one which can be handled safely but which may lose application
1797
 * information or settings.
1798
 *
1799
 * By default these both result in a png_error call prior to release, while in a
1800
 * released version the 'warning' is just a warning.  However if the application
1801
 * explicitly disables benign errors (explicitly permitting the code to lose
1802
 * information) they both turn into warnings.
1803
 *
1804
 * If benign errors aren't supported they end up as the corresponding base call
1805
 * (png_warning or png_error.)
1806
 */
1807
PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr,
1808
   png_const_charp message),PNG_EMPTY);
1809
   /* The application provided invalid parameters to an API function or called
1810
    * an API function at the wrong time, libpng can completely recover.
1811
    */
1812
1813
PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr,
1814
   png_const_charp message),PNG_EMPTY);
1815
   /* As above but libpng will ignore the call, or attempt some other partial
1816
    * recovery from the error.
1817
    */
1818
#else
1819
#  define png_app_warning(pp,s) png_warning(pp,s)
1820
#  define png_app_error(pp,s) png_error(pp,s)
1821
#endif
1822
1823
PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
1824
   png_const_charp message, int error),PNG_EMPTY);
1825
   /* Report a recoverable issue in chunk data.  On read this is used to report
1826
    * a problem found while reading a particular chunk and the
1827
    * png_chunk_benign_error or png_chunk_warning function is used as
1828
    * appropriate.  On write this is used to report an error that comes from
1829
    * data set via an application call to a png_set_ API and png_app_error or
1830
    * png_app_warning is used as appropriate.
1831
    *
1832
    * The 'error' parameter must have one of the following values:
1833
    */
1834
#define PNG_CHUNK_WARNING     0 /* never an error */
1835
80
#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */
1836
80
#define PNG_CHUNK_ERROR       2 /* always an error */
1837
1838
/* ASCII to FP interfaces, currently only implemented if sCAL
1839
 * support is required.
1840
 */
1841
#if defined(PNG_sCAL_SUPPORTED)
1842
/* MAX_DIGITS is actually the maximum number of characters in an sCAL
1843
 * width or height, derived from the precision (number of significant
1844
 * digits - a build time settable option) and assumptions about the
1845
 * maximum ridiculous exponent.
1846
 */
1847
#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/)
1848
1849
#ifdef PNG_FLOATING_POINT_SUPPORTED
1850
PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,
1851
   png_charp ascii, size_t size, double fp, unsigned int precision),
1852
   PNG_EMPTY);
1853
#endif /* FLOATING_POINT */
1854
1855
#ifdef PNG_FIXED_POINT_SUPPORTED
1856
PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
1857
   png_charp ascii, size_t size, png_fixed_point fp),PNG_EMPTY);
1858
#endif /* FIXED_POINT */
1859
#endif /* sCAL */
1860
1861
#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
1862
/* An internal API to validate the format of a floating point number.
1863
 * The result is the index of the next character.  If the number is
1864
 * not valid it will be the index of a character in the supposed number.
1865
 *
1866
 * The format of a number is defined in the PNG extensions specification
1867
 * and this API is strictly conformant to that spec, not anyone elses!
1868
 *
1869
 * The format as a regular expression is:
1870
 *
1871
 * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)?
1872
 *
1873
 * or:
1874
 *
1875
 * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)?
1876
 *
1877
 * The complexity is that either integer or fraction must be present and the
1878
 * fraction is permitted to have no digits only if the integer is present.
1879
 *
1880
 * NOTE: The dangling E problem.
1881
 *   There is a PNG valid floating point number in the following:
1882
 *
1883
 *       PNG floating point numbers are not greedy.
1884
 *
1885
 *   Working this out requires *TWO* character lookahead (because of the
1886
 *   sign), the parser does not do this - it will fail at the 'r' - this
1887
 *   doesn't matter for PNG sCAL chunk values, but it requires more care
1888
 *   if the value were ever to be embedded in something more complex.  Use
1889
 *   ANSI-C strtod if you need the lookahead.
1890
 */
1891
/* State table for the parser. */
1892
7.63k
#define PNG_FP_INTEGER    0  /* before or in integer */
1893
375
#define PNG_FP_FRACTION   1  /* before or in fraction */
1894
2.39k
#define PNG_FP_EXPONENT   2  /* before or in exponent */
1895
10.4k
#define PNG_FP_STATE      3  /* mask for the above */
1896
1.41k
#define PNG_FP_SAW_SIGN   4  /* Saw +/- in current state */
1897
21.3k
#define PNG_FP_SAW_DIGIT  8  /* Saw a digit in current state */
1898
7.12k
#define PNG_FP_SAW_DOT   16  /* Saw a dot in current state */
1899
2.00k
#define PNG_FP_SAW_E     32  /* Saw an E (or e) in current state */
1900
11.1k
#define PNG_FP_SAW_ANY   60  /* Saw any of the above 4 */
1901
1902
/* These three values don't affect the parser.  They are set but not used.
1903
 */
1904
#define PNG_FP_WAS_VALID 64  /* Preceding substring is a valid fp number */
1905
1.41k
#define PNG_FP_NEGATIVE 128  /* A negative number, including "-0" */
1906
9.56k
#define PNG_FP_NONZERO  256  /* A non-zero value */
1907
1.17k
#define PNG_FP_STICKY   448  /* The above three flags */
1908
1909
/* This is available for the caller to store in 'state' if required.  Do not
1910
 * call the parser after setting it (the parser sometimes clears it.)
1911
 */
1912
#define PNG_FP_INVALID  512  /* Available for callers as a distinct value */
1913
1914
/* Result codes for the parser (boolean - true means ok, false means
1915
 * not ok yet.)
1916
 */
1917
#define PNG_FP_MAYBE      0  /* The number may be valid in the future */
1918
#define PNG_FP_OK         1  /* The number is valid */
1919
1920
/* Tests on the sticky non-zero and negative flags.  To pass these checks
1921
 * the state must also indicate that the whole number is valid - this is
1922
 * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this
1923
 * is equivalent to PNG_FP_OK above.)
1924
 */
1925
713
#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO)
1926
   /* NZ_MASK: the string is valid and a non-zero negative value */
1927
713
#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO)
1928
   /* Z MASK: the string is valid and a non-zero value. */
1929
   /* PNG_FP_SAW_DIGIT: the string is valid. */
1930
#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT)
1931
713
#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK)
1932
#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK)
1933
1934
/* The actual parser.  This can be called repeatedly. It updates
1935
 * the index into the string and the state variable (which must
1936
 * be initialized to 0).  It returns a result code, as above.  There
1937
 * is no point calling the parser any more if it fails to advance to
1938
 * the end of the string - it is stuck on an invalid character (or
1939
 * terminated by '\0').
1940
 *
1941
 * Note that the pointer will consume an E or even an E+ and then leave
1942
 * a 'maybe' state even though a preceding integer.fraction is valid.
1943
 * The PNG_FP_WAS_VALID flag indicates that a preceding substring was
1944
 * a valid number.  It's possible to recover from this by calling
1945
 * the parser again (from the start, with state 0) but with a string
1946
 * that omits the last character (i.e. set the size to the index of
1947
 * the problem character.)  This has not been tested within libpng.
1948
 */
1949
PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
1950
   size_t size, int *statep, size_t *whereami),PNG_EMPTY);
1951
1952
/* This is the same but it checks a complete string and returns true
1953
 * only if it just contains a floating point number.  As of 1.5.4 this
1954
 * function also returns the state at the end of parsing the number if
1955
 * it was valid (otherwise it returns 0.)  This can be used for testing
1956
 * for negative or zero values using the sticky flag.
1957
 */
1958
PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
1959
   size_t size),PNG_EMPTY);
1960
#endif /* pCAL || sCAL */
1961
1962
#if defined(PNG_READ_GAMMA_SUPPORTED) ||\
1963
    defined(PNG_COLORSPACE_SUPPORTED) ||\
1964
    defined(PNG_INCH_CONVERSIONS_SUPPORTED) ||\
1965
    defined(PNG_READ_pHYs_SUPPORTED)
1966
/* Added at libpng version 1.5.0 */
1967
/* This is a utility to provide a*times/div (rounded) and indicate
1968
 * if there is an overflow.  The result is a boolean - false (0)
1969
 * for overflow, true (1) if no overflow, in which case *res
1970
 * holds the result.
1971
 */
1972
PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
1973
   png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY);
1974
1975
/* Calculate a reciprocal - used for gamma values.  This returns
1976
 * 0 if the argument is 0 in order to maintain an undefined value;
1977
 * there are no warnings.
1978
 */
1979
PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
1980
   PNG_EMPTY);
1981
#endif
1982
1983
#ifdef PNG_READ_GAMMA_SUPPORTED
1984
/* The same but gives a reciprocal of the product of two fixed point
1985
 * values.  Accuracy is suitable for gamma calculations but this is
1986
 * not exact - use png_muldiv for that.  Only required at present on read.
1987
 */
1988
PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a,
1989
   png_fixed_point b),PNG_EMPTY);
1990
1991
/* Return true if the gamma value is significantly different from 1.0 */
1992
PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
1993
   PNG_EMPTY);
1994
1995
/* PNGv3: 'resolve' the file gamma according to the new PNGv3 rules for colour
1996
 * space information.
1997
 *
1998
 * NOTE: this uses precisely those chunks that libpng supports.  For example it
1999
 * doesn't use iCCP and it can only use cICP for known and manageable
2000
 * transforms.  For this reason a gamma specified by png_set_gamma always takes
2001
 * precedence.
2002
 */
2003
PNG_INTERNAL_FUNCTION(png_fixed_point,png_resolve_file_gamma,
2004
   (png_const_structrp png_ptr),PNG_EMPTY);
2005
2006
/* Internal fixed point gamma correction.  These APIs are called as
2007
 * required to convert single values - they don't need to be fast,
2008
 * they are not used when processing image pixel values.
2009
 *
2010
 * While the input is an 'unsigned' value it must actually be the
2011
 * correct bit value - 0..255 or 0..65535 as required.
2012
 */
2013
PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr,
2014
   unsigned int value, png_fixed_point gamma_value),PNG_EMPTY);
2015
PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value,
2016
   png_fixed_point gamma_value),PNG_EMPTY);
2017
PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value,
2018
   png_fixed_point gamma_value),PNG_EMPTY);
2019
PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
2020
   PNG_EMPTY);
2021
PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr,
2022
   int bit_depth),PNG_EMPTY);
2023
#endif /* READ_GAMMA */
2024
2025
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2026
/* Set the RGB coefficients if not already set by png_set_rgb_to_gray */
2027
PNG_INTERNAL_FUNCTION(void,png_set_rgb_coefficients,(png_structrp png_ptr),
2028
   PNG_EMPTY);
2029
#endif
2030
2031
#if defined(PNG_cHRM_SUPPORTED) || defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2032
PNG_INTERNAL_FUNCTION(int,png_XYZ_from_xy,(png_XYZ *XYZ, const png_xy *xy),
2033
   PNG_EMPTY);
2034
#endif /* cHRM || READ_RGB_TO_GRAY */
2035
2036
#ifdef PNG_COLORSPACE_SUPPORTED
2037
PNG_INTERNAL_FUNCTION(int,png_xy_from_XYZ,(png_xy *xy, const png_XYZ *XYZ),
2038
   PNG_EMPTY);
2039
#endif
2040
2041
/* SIMPLIFIED READ/WRITE SUPPORT */
2042
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
2043
   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
2044
/* The internal structure that png_image::opaque points to. */
2045
typedef struct png_control
2046
{
2047
   png_structp png_ptr;
2048
   png_infop   info_ptr;
2049
   png_voidp   error_buf;           /* Always a jmp_buf at present. */
2050
2051
   png_const_bytep memory;          /* Memory buffer. */
2052
   size_t          size;            /* Size of the memory buffer. */
2053
2054
   unsigned int for_write       :1; /* Otherwise it is a read structure */
2055
   unsigned int owned_file      :1; /* We own the file in io_ptr */
2056
} png_control;
2057
2058
/* Return the pointer to the jmp_buf from a png_control: necessary because C
2059
 * does not reveal the type of the elements of jmp_buf.
2060
 */
2061
#ifdef __cplusplus
2062
#  define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0])
2063
#else
2064
111
#  define png_control_jmp_buf(pc) ((pc)->error_buf)
2065
#endif
2066
2067
/* Utility to safely execute a piece of libpng code catching and logging any
2068
 * errors that might occur.  Returns true on success, false on failure (either
2069
 * of the function or as a result of a png_error.)
2070
 */
2071
PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr,
2072
   png_const_charp error_message),PNG_NORETURN);
2073
2074
#ifdef PNG_WARNINGS_SUPPORTED
2075
PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr,
2076
   png_const_charp warning_message),PNG_EMPTY);
2077
#else
2078
#  define png_safe_warning 0/*dummy argument*/
2079
#endif
2080
2081
PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image,
2082
   int (*function)(png_voidp), png_voidp arg),PNG_EMPTY);
2083
2084
/* Utility to log an error; this also cleans up the png_image; the function
2085
 * always returns 0 (false).
2086
 */
2087
PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image,
2088
   png_const_charp error_message),PNG_EMPTY);
2089
2090
#ifndef PNG_SIMPLIFIED_READ_SUPPORTED
2091
/* png_image_free is used by the write code but not exported */
2092
PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY);
2093
#endif /* !SIMPLIFIED_READ */
2094
2095
#endif /* SIMPLIFIED READ/WRITE */
2096
2097
/* These are initialization functions for hardware specific PNG filter
2098
 * optimizations; list these here then select the appropriate one at compile
2099
 * time using the macro PNG_FILTER_OPTIMIZATIONS.  If the macro is not defined
2100
 * the generic code is used.
2101
 */
2102
#ifdef PNG_FILTER_OPTIMIZATIONS
2103
PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
2104
   unsigned int bpp), PNG_EMPTY);
2105
   /* Just declare the optimization that will be used */
2106
#else
2107
   /* List *all* the possible optimizations here - this branch is required if
2108
    * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
2109
    * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
2110
    */
2111
#  if PNG_ARM_NEON_OPT > 0
2112
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
2113
   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
2114
#endif
2115
2116
#if PNG_MIPS_MSA_IMPLEMENTATION == 1
2117
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
2118
   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
2119
#endif
2120
2121
#  if PNG_MIPS_MMI_IMPLEMENTATION > 0
2122
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
2123
   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
2124
#  endif
2125
2126
#  if PNG_INTEL_SSE_IMPLEMENTATION > 0
2127
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
2128
   (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
2129
#  endif
2130
#endif
2131
2132
#if PNG_LOONGARCH_LSX_OPT > 0
2133
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx,
2134
    (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
2135
#endif
2136
2137
PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
2138
   png_const_charp key, png_bytep new_key), PNG_EMPTY);
2139
2140
#if PNG_ARM_NEON_IMPLEMENTATION == 1
2141
PNG_INTERNAL_FUNCTION(void,
2142
                      png_riffle_palette_neon,
2143
                      (png_structrp),
2144
                      PNG_EMPTY);
2145
PNG_INTERNAL_FUNCTION(int,
2146
                      png_do_expand_palette_rgba8_neon,
2147
                      (png_structrp,
2148
                       png_row_infop,
2149
                       png_const_bytep,
2150
                       const png_bytepp,
2151
                       const png_bytepp),
2152
                      PNG_EMPTY);
2153
PNG_INTERNAL_FUNCTION(int,
2154
                      png_do_expand_palette_rgb8_neon,
2155
                      (png_structrp,
2156
                       png_row_infop,
2157
                       png_const_bytep,
2158
                       const png_bytepp,
2159
                       const png_bytepp),
2160
                      PNG_EMPTY);
2161
#endif
2162
2163
/* Maintainer: Put new private prototypes here ^ */
2164
2165
#include "pngdebug.h"
2166
2167
#ifdef __cplusplus
2168
}
2169
#endif
2170
2171
#endif /* PNG_VERSION_INFO_ONLY */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngread.c.html b/part1/report/w_corpus/src/libpng/pngread.c.html new file mode 100644 index 0000000..157e2c0 --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngread.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngread.c
Line
Count
Source (jump to first uncovered line)
1
/* pngread.c - read a PNG file
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 * This file contains routines that an application calls directly to
13
 * read a PNG file or stream.
14
 */
15
16
#include "pngpriv.h"
17
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
18
#  include <errno.h>
19
#endif
20
21
#ifdef PNG_READ_SUPPORTED
22
23
/* Create a PNG structure for reading, and allocate any memory needed. */
24
PNG_FUNCTION(png_structp,PNGAPI
25
png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
26
    png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
27
2.22k
{
28
#ifndef PNG_USER_MEM_SUPPORTED
29
   png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
30
        error_fn, warn_fn, NULL, NULL, NULL);
31
#else
32
2.22k
   return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
33
2.22k
        warn_fn, NULL, NULL, NULL);
34
2.22k
}
35
36
/* Alternate create PNG structure for reading, and allocate any memory
37
 * needed.
38
 */
39
PNG_FUNCTION(png_structp,PNGAPI
40
png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
41
    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
42
    png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
43
2.22k
{
44
2.22k
   png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
45
2.22k
       error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
46
2.22k
#endif /* USER_MEM */
47
48
2.22k
   if (png_ptr != NULL)
49
2.22k
   {
50
2.22k
      png_ptr->mode = PNG_IS_READ_STRUCT;
51
52
      /* Added in libpng-1.6.0; this can be used to detect a read structure if
53
       * required (it will be zero in a write structure.)
54
       */
55
2.22k
#     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
56
2.22k
         png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE;
57
2.22k
#     endif
58
59
2.22k
#     ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED
60
2.22k
         png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
61
62
         /* In stable builds only warn if an application error can be completely
63
          * handled.
64
          */
65
2.22k
#        if PNG_RELEASE_BUILD
66
2.22k
            png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
67
2.22k
#        endif
68
2.22k
#     endif
69
70
      /* TODO: delay this, it can be done in png_init_io (if the app doesn't
71
       * do it itself) avoiding setting the default function if it is not
72
       * required.
73
       */
74
2.22k
      png_set_read_fn(png_ptr, NULL, NULL);
75
2.22k
   }
76
77
2.22k
   return png_ptr;
78
2.22k
}
79
80
81
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
82
/* Read the information before the actual image data.  This has been
83
 * changed in v0.90 to allow reading a file that already has the magic
84
 * bytes read from the stream.  You can tell libpng how many bytes have
85
 * been read from the beginning of the stream (up to the maximum of 8)
86
 * via png_set_sig_bytes(), and we will only check the remaining bytes
87
 * here.  The application can then have access to the signature bytes we
88
 * read if it is determined that this isn't a valid PNG file.
89
 */
90
void PNGAPI
91
png_read_info(png_structrp png_ptr, png_inforp info_ptr)
92
2.22k
{
93
2.22k
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
94
2.22k
   int keep;
95
2.22k
#endif
96
97
2.22k
   png_debug(1, "in png_read_info");
98
99
2.22k
   if (png_ptr == NULL || info_ptr == NULL)
100
0
      return;
101
102
   /* Read and check the PNG file signature. */
103
2.22k
   png_read_sig(png_ptr, info_ptr);
104
105
2.22k
   for (;;)
106
33.5k
   {
107
33.5k
      png_uint_32 length = png_read_chunk_header(png_ptr);
108
33.5k
      png_uint_32 chunk_name = png_ptr->chunk_name;
109
110
      /* IDAT logic needs to happen here to simplify getting the two flags
111
       * right.
112
       */
113
33.5k
      if (chunk_name == png_IDAT)
114
1.39k
      {
115
1.39k
         if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
116
1
            png_chunk_error(png_ptr, "Missing IHDR before IDAT");
117
118
1.39k
         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
119
1.39k
             (png_ptr->mode & PNG_HAVE_PLTE) == 0)
120
1
            png_chunk_error(png_ptr, "Missing PLTE before IDAT");
121
122
1.38k
         else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
123
0
            png_chunk_benign_error(png_ptr, "Too many IDATs found");
124
125
1.38k
         png_ptr->mode |= PNG_HAVE_IDAT;
126
1.38k
      }
127
128
32.1k
      else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
129
0
      {
130
0
         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
131
0
         png_ptr->mode |= PNG_AFTER_IDAT;
132
0
      }
133
134
33.5k
      if (chunk_name == png_IHDR)
135
2.20k
         png_handle_chunk(png_ptr, info_ptr, length);
136
137
31.3k
      else if (chunk_name == png_IEND)
138
1
         png_handle_chunk(png_ptr, info_ptr, length);
139
140
31.3k
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
141
31.3k
      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
142
0
      {
143
0
         png_handle_unknown(png_ptr, info_ptr, length, keep);
144
145
0
         if (chunk_name == png_PLTE)
146
0
            png_ptr->mode |= PNG_HAVE_PLTE;
147
148
0
         else if (chunk_name == png_IDAT)
149
0
         {
150
0
            png_ptr->idat_size = 0; /* It has been consumed */
151
0
            break;
152
0
         }
153
0
      }
154
31.3k
#endif
155
156
31.3k
      else if (chunk_name == png_IDAT)
157
1.38k
      {
158
1.38k
         png_ptr->idat_size = length;
159
1.38k
         break;
160
1.38k
      }
161
162
29.9k
      else
163
29.9k
         png_handle_chunk(png_ptr, info_ptr, length);
164
33.5k
   }
165
2.22k
}
166
#endif /* SEQUENTIAL_READ */
167
168
/* Optional call to update the users info_ptr structure */
169
void PNGAPI
170
png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
171
1.38k
{
172
1.38k
   png_debug(1, "in png_read_update_info");
173
174
1.38k
   if (png_ptr != NULL)
175
1.38k
   {
176
1.38k
      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
177
1.38k
      {
178
1.38k
         png_read_start_row(png_ptr);
179
180
1.38k
#        ifdef PNG_READ_TRANSFORMS_SUPPORTED
181
1.38k
            png_read_transform_info(png_ptr, info_ptr);
182
#        else
183
            PNG_UNUSED(info_ptr)
184
#        endif
185
1.38k
      }
186
187
      /* New in 1.6.0 this avoids the bug of doing the initializations twice */
188
0
      else
189
0
         png_app_error(png_ptr,
190
0
             "png_read_update_info/png_start_read_image: duplicate call");
191
1.38k
   }
192
1.38k
}
193
194
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
195
/* Initialize palette, background, etc, after transformations
196
 * are set, but before any reading takes place.  This allows
197
 * the user to obtain a gamma-corrected palette, for example.
198
 * If the user doesn't call this, we will do it ourselves.
199
 */
200
void PNGAPI
201
png_start_read_image(png_structrp png_ptr)
202
0
{
203
0
   png_debug(1, "in png_start_read_image");
204
205
0
   if (png_ptr != NULL)
206
0
   {
207
0
      if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
208
0
         png_read_start_row(png_ptr);
209
210
      /* New in 1.6.0 this avoids the bug of doing the initializations twice */
211
0
      else
212
0
         png_app_error(png_ptr,
213
0
             "png_start_read_image/png_read_update_info: duplicate call");
214
0
   }
215
0
}
216
#endif /* SEQUENTIAL_READ */
217
218
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
219
#ifdef PNG_MNG_FEATURES_SUPPORTED
220
/* Undoes intrapixel differencing,
221
 * NOTE: this is apparently only supported in the 'sequential' reader.
222
 */
223
static void
224
png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
225
0
{
226
0
   png_debug(1, "in png_do_read_intrapixel");
227
228
0
   if (
229
0
       (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
230
0
   {
231
0
      int bytes_per_pixel;
232
0
      png_uint_32 row_width = row_info->width;
233
234
0
      if (row_info->bit_depth == 8)
235
0
      {
236
0
         png_bytep rp;
237
0
         png_uint_32 i;
238
239
0
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
240
0
            bytes_per_pixel = 3;
241
242
0
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
243
0
            bytes_per_pixel = 4;
244
245
0
         else
246
0
            return;
247
248
0
         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
249
0
         {
250
0
            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
251
0
            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
252
0
         }
253
0
      }
254
0
      else if (row_info->bit_depth == 16)
255
0
      {
256
0
         png_bytep rp;
257
0
         png_uint_32 i;
258
259
0
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
260
0
            bytes_per_pixel = 6;
261
262
0
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
263
0
            bytes_per_pixel = 8;
264
265
0
         else
266
0
            return;
267
268
0
         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
269
0
         {
270
0
            png_uint_32 s0   = (png_uint_32)(*(rp    ) << 8) | *(rp + 1);
271
0
            png_uint_32 s1   = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
272
0
            png_uint_32 s2   = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
273
0
            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
274
0
            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
275
0
            *(rp    ) = (png_byte)((red >> 8) & 0xff);
276
0
            *(rp + 1) = (png_byte)(red & 0xff);
277
0
            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
278
0
            *(rp + 5) = (png_byte)(blue & 0xff);
279
0
         }
280
0
      }
281
0
   }
282
0
}
283
#endif /* MNG_FEATURES */
284
285
void PNGAPI
286
png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
287
495k
{
288
495k
   png_row_info row_info;
289
290
495k
   if (png_ptr == NULL)
291
0
      return;
292
293
495k
   png_debug2(1, "in png_read_row (row %lu, pass %d)",
294
495k
       (unsigned long)png_ptr->row_number, png_ptr->pass);
295
296
   /* png_read_start_row sets the information (in particular iwidth) for this
297
    * interlace pass.
298
    */
299
495k
   if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
300
0
      png_read_start_row(png_ptr);
301
302
   /* 1.5.6: row_info moved out of png_struct to a local here. */
303
495k
   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
304
495k
   row_info.color_type = png_ptr->color_type;
305
495k
   row_info.bit_depth = png_ptr->bit_depth;
306
495k
   row_info.channels = png_ptr->channels;
307
495k
   row_info.pixel_depth = png_ptr->pixel_depth;
308
495k
   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
309
310
495k
#ifdef PNG_WARNINGS_SUPPORTED
311
495k
   if (png_ptr->row_number == 0 && png_ptr->pass == 0)
312
1.38k
   {
313
   /* Check for transforms that have been set but were defined out */
314
#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
315
   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
316
      png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
317
#endif
318
319
#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
320
   if ((png_ptr->transformations & PNG_FILLER) != 0)
321
      png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
322
#endif
323
324
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
325
    !defined(PNG_READ_PACKSWAP_SUPPORTED)
326
   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
327
      png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
328
#endif
329
330
#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
331
   if ((png_ptr->transformations & PNG_PACK) != 0)
332
      png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
333
#endif
334
335
#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
336
   if ((png_ptr->transformations & PNG_SHIFT) != 0)
337
      png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
338
#endif
339
340
#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
341
   if ((png_ptr->transformations & PNG_BGR) != 0)
342
      png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
343
#endif
344
345
#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
346
   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
347
      png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
348
#endif
349
1.38k
   }
350
495k
#endif /* WARNINGS */
351
352
495k
#ifdef PNG_READ_INTERLACING_SUPPORTED
353
   /* If interlaced and we do not need a new row, combine row and return.
354
    * Notice that the pixels we have from previous rows have been transformed
355
    * already; we can only combine like with like (transformed or
356
    * untransformed) and, because of the libpng API for interlaced images, this
357
    * means we must transform before de-interlacing.
358
    */
359
495k
   if (png_ptr->interlaced != 0 &&
360
495k
       (png_ptr->transformations & PNG_INTERLACE) != 0)
361
429k
   {
362
429k
      switch (png_ptr->pass)
363
429k
      {
364
112k
         case 0:
365
112k
            if (png_ptr->row_number & 0x07)
366
98.2k
            {
367
98.2k
               if (dsp_row != NULL)
368
0
                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
369
98.2k
               png_read_finish_row(png_ptr);
370
98.2k
               return;
371
98.2k
            }
372
14.1k
            break;
373
374
105k
         case 1:
375
105k
            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
376
102k
            {
377
102k
               if (dsp_row != NULL)
378
0
                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
379
380
102k
               png_read_finish_row(png_ptr);
381
102k
               return;
382
102k
            }
383
2.35k
            break;
384
385
100k
         case 2:
386
100k
            if ((png_ptr->row_number & 0x07) != 4)
387
88.3k
            {
388
88.3k
               if (dsp_row != NULL && (png_ptr->row_number & 4))
389
0
                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
390
391
88.3k
               png_read_finish_row(png_ptr);
392
88.3k
               return;
393
88.3k
            }
394
12.6k
            break;
395
396
63.7k
         case 3:
397
63.7k
            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
398
58.3k
            {
399
58.3k
               if (dsp_row != NULL)
400
0
                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
401
402
58.3k
               png_read_finish_row(png_ptr);
403
58.3k
               return;
404
58.3k
            }
405
5.44k
            break;
406
407
20.9k
         case 4:
408
20.9k
            if ((png_ptr->row_number & 3) != 2)
409
15.7k
            {
410
15.7k
               if (dsp_row != NULL && (png_ptr->row_number & 2))
411
0
                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
412
413
15.7k
               png_read_finish_row(png_ptr);
414
15.7k
               return;
415
15.7k
            }
416
5.21k
            break;
417
418
13.8k
         case 5:
419
13.8k
            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
420
7.15k
            {
421
7.15k
               if (dsp_row != NULL)
422
0
                  png_combine_row(png_ptr, dsp_row, 1/*display*/);
423
424
7.15k
               png_read_finish_row(png_ptr);
425
7.15k
               return;
426
7.15k
            }
427
6.73k
            break;
428
429
6.73k
         default:
430
11.8k
         case 6:
431
11.8k
            if ((png_ptr->row_number & 1) == 0)
432
6.00k
            {
433
6.00k
               png_read_finish_row(png_ptr);
434
6.00k
               return;
435
6.00k
            }
436
5.88k
            break;
437
429k
      }
438
429k
   }
439
118k
#endif
440
441
118k
   if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
442
0
      png_error(png_ptr, "Invalid attempt to read row data");
443
444
   /* Fill the row with IDAT data: */
445
118k
   png_ptr->row_buf[0]=255; /* to force error if no data was found */
446
118k
   png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
447
448
118k
   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
449
66.7k
   {
450
66.7k
      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
451
66.4k
         png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
452
66.4k
             png_ptr->prev_row + 1, png_ptr->row_buf[0]);
453
265
      else
454
265
         png_error(png_ptr, "bad adaptive filter value");
455
66.7k
   }
456
457
   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
458
    * 1.5.6, while the buffer really is this big in current versions of libpng
459
    * it may not be in the future, so this was changed just to copy the
460
    * interlaced count:
461
    */
462
118k
   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
463
464
118k
#ifdef PNG_MNG_FEATURES_SUPPORTED
465
118k
   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
466
118k
       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
467
0
   {
468
      /* Intrapixel differencing */
469
0
      png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
470
0
   }
471
118k
#endif
472
473
118k
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
474
118k
   if (png_ptr->transformations
475
118k
#     ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
476
118k
         || png_ptr->num_palette_max >= 0
477
118k
#     endif
478
118k
      )
479
118k
      png_do_read_transformations(png_ptr, &row_info);
480
118k
#endif
481
482
   /* The transformed pixel depth should match the depth now in row_info. */
483
118k
   if (png_ptr->transformed_pixel_depth == 0)
484
1.36k
   {
485
1.36k
      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
486
1.36k
      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
487
0
         png_error(png_ptr, "sequential row overflow");
488
1.36k
   }
489
490
117k
   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
491
0
      png_error(png_ptr, "internal sequential row size calculation error");
492
493
118k
#ifdef PNG_READ_INTERLACING_SUPPORTED
494
   /* Expand interlaced rows to full size */
495
118k
   if (png_ptr->interlaced != 0 &&
496
118k
      (png_ptr->transformations & PNG_INTERLACE) != 0)
497
52.2k
   {
498
52.2k
      if (png_ptr->pass < 6)
499
46.4k
         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
500
46.4k
             png_ptr->transformations);
501
502
52.2k
      if (dsp_row != NULL)
503
0
         png_combine_row(png_ptr, dsp_row, 1/*display*/);
504
505
52.2k
      if (row != NULL)
506
52.2k
         png_combine_row(png_ptr, row, 0/*row*/);
507
52.2k
   }
508
509
66.1k
   else
510
66.1k
#endif
511
66.1k
   {
512
66.1k
      if (row != NULL)
513
65.9k
         png_combine_row(png_ptr, row, -1/*ignored*/);
514
515
66.1k
      if (dsp_row != NULL)
516
0
         png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
517
66.1k
   }
518
118k
   png_read_finish_row(png_ptr);
519
520
118k
   if (png_ptr->read_row_fn != NULL)
521
0
      (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
522
523
118k
}
524
#endif /* SEQUENTIAL_READ */
525
526
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
527
/* Read one or more rows of image data.  If the image is interlaced,
528
 * and png_set_interlace_handling() has been called, the rows need to
529
 * contain the contents of the rows from the previous pass.  If the
530
 * image has alpha or transparency, and png_handle_alpha()[*] has been
531
 * called, the rows contents must be initialized to the contents of the
532
 * screen.
533
 *
534
 * "row" holds the actual image, and pixels are placed in it
535
 * as they arrive.  If the image is displayed after each pass, it will
536
 * appear to "sparkle" in.  "display_row" can be used to display a
537
 * "chunky" progressive image, with finer detail added as it becomes
538
 * available.  If you do not want this "chunky" display, you may pass
539
 * NULL for display_row.  If you do not want the sparkle display, and
540
 * you have not called png_handle_alpha(), you may pass NULL for rows.
541
 * If you have called png_handle_alpha(), and the image has either an
542
 * alpha channel or a transparency chunk, you must provide a buffer for
543
 * rows.  In this case, you do not have to provide a display_row buffer
544
 * also, but you may.  If the image is not interlaced, or if you have
545
 * not called png_set_interlace_handling(), the display_row buffer will
546
 * be ignored, so pass NULL to it.
547
 *
548
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
549
 */
550
551
void PNGAPI
552
png_read_rows(png_structrp png_ptr, png_bytepp row,
553
    png_bytepp display_row, png_uint_32 num_rows)
554
0
{
555
0
   png_uint_32 i;
556
0
   png_bytepp rp;
557
0
   png_bytepp dp;
558
559
0
   png_debug(1, "in png_read_rows");
560
561
0
   if (png_ptr == NULL)
562
0
      return;
563
564
0
   rp = row;
565
0
   dp = display_row;
566
0
   if (rp != NULL && dp != NULL)
567
0
      for (i = 0; i < num_rows; i++)
568
0
      {
569
0
         png_bytep rptr = *rp++;
570
0
         png_bytep dptr = *dp++;
571
572
0
         png_read_row(png_ptr, rptr, dptr);
573
0
      }
574
575
0
   else if (rp != NULL)
576
0
      for (i = 0; i < num_rows; i++)
577
0
      {
578
0
         png_bytep rptr = *rp;
579
0
         png_read_row(png_ptr, rptr, NULL);
580
0
         rp++;
581
0
      }
582
583
0
   else if (dp != NULL)
584
0
      for (i = 0; i < num_rows; i++)
585
0
      {
586
0
         png_bytep dptr = *dp;
587
0
         png_read_row(png_ptr, NULL, dptr);
588
0
         dp++;
589
0
      }
590
0
}
591
#endif /* SEQUENTIAL_READ */
592
593
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
594
/* Read the entire image.  If the image has an alpha channel or a tRNS
595
 * chunk, and you have called png_handle_alpha()[*], you will need to
596
 * initialize the image to the current image that PNG will be overlaying.
597
 * We set the num_rows again here, in case it was incorrectly set in
598
 * png_read_start_row() by a call to png_read_update_info() or
599
 * png_start_read_image() if png_set_interlace_handling() wasn't called
600
 * prior to either of these functions like it should have been.  You can
601
 * only call this function once.  If you desire to have an image for
602
 * each pass of a interlaced image, use png_read_rows() instead.
603
 *
604
 * [*] png_handle_alpha() does not exist yet, as of this version of libpng
605
 */
606
void PNGAPI
607
png_read_image(png_structrp png_ptr, png_bytepp image)
608
0
{
609
0
   png_uint_32 i, image_height;
610
0
   int pass, j;
611
0
   png_bytepp rp;
612
613
0
   png_debug(1, "in png_read_image");
614
615
0
   if (png_ptr == NULL)
616
0
      return;
617
618
0
#ifdef PNG_READ_INTERLACING_SUPPORTED
619
0
   if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
620
0
   {
621
0
      pass = png_set_interlace_handling(png_ptr);
622
      /* And make sure transforms are initialized. */
623
0
      png_start_read_image(png_ptr);
624
0
   }
625
0
   else
626
0
   {
627
0
      if (png_ptr->interlaced != 0 &&
628
0
          (png_ptr->transformations & PNG_INTERLACE) == 0)
629
0
      {
630
         /* Caller called png_start_read_image or png_read_update_info without
631
          * first turning on the PNG_INTERLACE transform.  We can fix this here,
632
          * but the caller should do it!
633
          */
634
0
         png_warning(png_ptr, "Interlace handling should be turned on when "
635
0
             "using png_read_image");
636
         /* Make sure this is set correctly */
637
0
         png_ptr->num_rows = png_ptr->height;
638
0
      }
639
640
      /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
641
       * the above error case.
642
       */
643
0
      pass = png_set_interlace_handling(png_ptr);
644
0
   }
645
#else
646
   if (png_ptr->interlaced)
647
      png_error(png_ptr,
648
          "Cannot read interlaced image -- interlace handler disabled");
649
650
   pass = 1;
651
#endif
652
653
0
   image_height=png_ptr->height;
654
655
0
   for (j = 0; j < pass; j++)
656
0
   {
657
0
      rp = image;
658
0
      for (i = 0; i < image_height; i++)
659
0
      {
660
0
         png_read_row(png_ptr, *rp, NULL);
661
0
         rp++;
662
0
      }
663
0
   }
664
0
}
665
#endif /* SEQUENTIAL_READ */
666
667
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
668
/* Read the end of the PNG file.  Will not read past the end of the
669
 * file, will verify the end is accurate, and will read any comments
670
 * or time information at the end of the file, if info is not NULL.
671
 */
672
void PNGAPI
673
png_read_end(png_structrp png_ptr, png_inforp info_ptr)
674
503
{
675
503
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
676
503
   int keep;
677
503
#endif
678
679
503
   png_debug(1, "in png_read_end");
680
681
503
   if (png_ptr == NULL)
682
0
      return;
683
684
   /* If png_read_end is called in the middle of reading the rows there may
685
    * still be pending IDAT data and an owned zstream.  Deal with this here.
686
    */
687
503
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
688
503
   if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0)
689
503
#endif
690
503
      png_read_finish_IDAT(png_ptr);
691
692
503
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
693
   /* Report invalid palette index; added at libng-1.5.10 */
694
503
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
695
503
       png_ptr->num_palette_max >= png_ptr->num_palette)
696
0
      png_benign_error(png_ptr, "Read palette index exceeding num_palette");
697
503
#endif
698
699
503
   do
700
4.60k
   {
701
4.60k
      png_uint_32 length = png_read_chunk_header(png_ptr);
702
4.60k
      png_uint_32 chunk_name = png_ptr->chunk_name;
703
704
4.60k
      if (chunk_name != png_IDAT)
705
4.23k
         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
706
707
4.60k
      if (chunk_name == png_IEND)
708
426
         png_handle_chunk(png_ptr, info_ptr, length);
709
710
4.17k
      else if (chunk_name == png_IHDR)
711
1
         png_handle_chunk(png_ptr, info_ptr, length);
712
713
4.17k
      else if (info_ptr == NULL)
714
0
         png_crc_finish(png_ptr, length);
715
716
4.17k
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
717
4.17k
      else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
718
0
      {
719
0
         if (chunk_name == png_IDAT)
720
0
         {
721
0
            if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
722
0
                || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
723
0
               png_benign_error(png_ptr, ".Too many IDATs found");
724
0
         }
725
0
         png_handle_unknown(png_ptr, info_ptr, length, keep);
726
0
         if (chunk_name == png_PLTE)
727
0
            png_ptr->mode |= PNG_HAVE_PLTE;
728
0
      }
729
4.17k
#endif
730
731
4.17k
      else if (chunk_name == png_IDAT)
732
305
      {
733
         /* Zero length IDATs are legal after the last IDAT has been
734
          * read, but not after other chunks have been read.  1.6 does not
735
          * always read all the deflate data; specifically it cannot be relied
736
          * upon to read the Adler32 at the end.  If it doesn't ignore IDAT
737
          * chunks which are longer than zero as well:
738
          */
739
305
         if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
740
305
             || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
741
303
            png_benign_error(png_ptr, "..Too many IDATs found");
742
743
305
         png_crc_finish(png_ptr, length);
744
305
      }
745
746
3.86k
      else
747
3.86k
         png_handle_chunk(png_ptr, info_ptr, length);
748
4.60k
   } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
749
503
}
750
#endif /* SEQUENTIAL_READ */
751
752
/* Free all memory used in the read struct */
753
static void
754
png_read_destroy(png_structrp png_ptr)
755
2.22k
{
756
2.22k
   png_debug(1, "in png_read_destroy");
757
758
2.22k
#ifdef PNG_READ_GAMMA_SUPPORTED
759
2.22k
   png_destroy_gamma_table(png_ptr);
760
2.22k
#endif
761
762
2.22k
   png_free(png_ptr, png_ptr->big_row_buf);
763
2.22k
   png_ptr->big_row_buf = NULL;
764
2.22k
   png_free(png_ptr, png_ptr->big_prev_row);
765
2.22k
   png_ptr->big_prev_row = NULL;
766
2.22k
   png_free(png_ptr, png_ptr->read_buffer);
767
2.22k
   png_ptr->read_buffer = NULL;
768
769
2.22k
#ifdef PNG_READ_QUANTIZE_SUPPORTED
770
2.22k
   png_free(png_ptr, png_ptr->palette_lookup);
771
2.22k
   png_ptr->palette_lookup = NULL;
772
2.22k
   png_free(png_ptr, png_ptr->quantize_index);
773
2.22k
   png_ptr->quantize_index = NULL;
774
2.22k
#endif
775
776
2.22k
   if ((png_ptr->free_me & PNG_FREE_PLTE) != 0)
777
0
   {
778
0
      png_zfree(png_ptr, png_ptr->palette);
779
0
      png_ptr->palette = NULL;
780
0
   }
781
2.22k
   png_ptr->free_me &= ~PNG_FREE_PLTE;
782
783
2.22k
#if defined(PNG_tRNS_SUPPORTED) || \
784
2.22k
    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
785
2.22k
   if ((png_ptr->free_me & PNG_FREE_TRNS) != 0)
786
0
   {
787
0
      png_free(png_ptr, png_ptr->trans_alpha);
788
0
      png_ptr->trans_alpha = NULL;
789
0
   }
790
2.22k
   png_ptr->free_me &= ~PNG_FREE_TRNS;
791
2.22k
#endif
792
793
2.22k
   inflateEnd(&png_ptr->zstream);
794
795
2.22k
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
796
2.22k
   png_free(png_ptr, png_ptr->save_buffer);
797
2.22k
   png_ptr->save_buffer = NULL;
798
2.22k
#endif
799
800
2.22k
#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \
801
2.22k
   defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
802
2.22k
   png_free(png_ptr, png_ptr->unknown_chunk.data);
803
2.22k
   png_ptr->unknown_chunk.data = NULL;
804
2.22k
#endif
805
806
2.22k
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
807
2.22k
   png_free(png_ptr, png_ptr->chunk_list);
808
2.22k
   png_ptr->chunk_list = NULL;
809
2.22k
#endif
810
811
2.22k
#if defined(PNG_READ_EXPAND_SUPPORTED) && \
812
2.22k
    defined(PNG_ARM_NEON_IMPLEMENTATION)
813
2.22k
   png_free(png_ptr, png_ptr->riffled_palette);
814
2.22k
   png_ptr->riffled_palette = NULL;
815
2.22k
#endif
816
817
   /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error
818
    * callbacks are still set at this point.  They are required to complete the
819
    * destruction of the png_struct itself.
820
    */
821
2.22k
}
822
823
/* Free all memory used by the read */
824
void PNGAPI
825
png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
826
    png_infopp end_info_ptr_ptr)
827
4.02k
{
828
4.02k
   png_structrp png_ptr = NULL;
829
830
4.02k
   png_debug(1, "in png_destroy_read_struct");
831
832
4.02k
   if (png_ptr_ptr != NULL)
833
4.02k
      png_ptr = *png_ptr_ptr;
834
835
4.02k
   if (png_ptr == NULL)
836
1.80k
      return;
837
838
   /* libpng 1.6.0: use the API to destroy info structs to ensure consistent
839
    * behavior.  Prior to 1.6.0 libpng did extra 'info' destruction in this API.
840
    * The extra was, apparently, unnecessary yet this hides memory leak bugs.
841
    */
842
2.22k
   png_destroy_info_struct(png_ptr, end_info_ptr_ptr);
843
2.22k
   png_destroy_info_struct(png_ptr, info_ptr_ptr);
844
845
2.22k
   *png_ptr_ptr = NULL;
846
2.22k
   png_read_destroy(png_ptr);
847
2.22k
   png_destroy_png_struct(png_ptr);
848
2.22k
}
849
850
void PNGAPI
851
png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
852
0
{
853
0
   if (png_ptr == NULL)
854
0
      return;
855
856
0
   png_ptr->read_row_fn = read_row_fn;
857
0
}
858
859
860
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
861
#ifdef PNG_INFO_IMAGE_SUPPORTED
862
void PNGAPI
863
png_read_png(png_structrp png_ptr, png_inforp info_ptr,
864
    int transforms, voidp params)
865
0
{
866
0
   png_debug(1, "in png_read_png");
867
868
0
   if (png_ptr == NULL || info_ptr == NULL)
869
0
      return;
870
871
   /* png_read_info() gives us all of the information from the
872
    * PNG file before the first IDAT (image data chunk).
873
    */
874
0
   png_read_info(png_ptr, info_ptr);
875
0
   if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
876
0
      png_error(png_ptr, "Image is too high to process with png_read_png()");
877
878
   /* -------------- image transformations start here ------------------- */
879
   /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM
880
    * is not implemented.  This will only happen in de-configured (non-default)
881
    * libpng builds.  The results can be unexpected - png_read_png may return
882
    * short or mal-formed rows because the transform is skipped.
883
    */
884
885
   /* Tell libpng to strip 16-bit/color files down to 8 bits per color.
886
    */
887
0
   if ((transforms & PNG_TRANSFORM_SCALE_16) != 0)
888
      /* Added at libpng-1.5.4. "strip_16" produces the same result that it
889
       * did in earlier versions, while "scale_16" is now more accurate.
890
       */
891
0
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
892
0
      png_set_scale_16(png_ptr);
893
#else
894
      png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported");
895
#endif
896
897
   /* If both SCALE and STRIP are required pngrtran will effectively cancel the
898
    * latter by doing SCALE first.  This is ok and allows apps not to check for
899
    * which is supported to get the right answer.
900
    */
901
0
   if ((transforms & PNG_TRANSFORM_STRIP_16) != 0)
902
0
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
903
0
      png_set_strip_16(png_ptr);
904
#else
905
      png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported");
906
#endif
907
908
   /* Strip alpha bytes from the input data without combining with
909
    * the background (not recommended).
910
    */
911
0
   if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0)
912
0
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
913
0
      png_set_strip_alpha(png_ptr);
914
#else
915
      png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported");
916
#endif
917
918
   /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
919
    * byte into separate bytes (useful for paletted and grayscale images).
920
    */
921
0
   if ((transforms & PNG_TRANSFORM_PACKING) != 0)
922
0
#ifdef PNG_READ_PACK_SUPPORTED
923
0
      png_set_packing(png_ptr);
924
#else
925
      png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
926
#endif
927
928
   /* Change the order of packed pixels to least significant bit first
929
    * (not useful if you are using png_set_packing).
930
    */
931
0
   if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
932
0
#ifdef PNG_READ_PACKSWAP_SUPPORTED
933
0
      png_set_packswap(png_ptr);
934
#else
935
      png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
936
#endif
937
938
   /* Expand paletted colors into true RGB triplets
939
    * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
940
    * Expand paletted or RGB images with transparency to full alpha
941
    * channels so the data will be available as RGBA quartets.
942
    */
943
0
   if ((transforms & PNG_TRANSFORM_EXPAND) != 0)
944
0
#ifdef PNG_READ_EXPAND_SUPPORTED
945
0
      png_set_expand(png_ptr);
946
#else
947
      png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported");
948
#endif
949
950
   /* We don't handle background color or gamma transformation or quantizing.
951
    */
952
953
   /* Invert monochrome files to have 0 as white and 1 as black
954
    */
955
0
   if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
956
0
#ifdef PNG_READ_INVERT_SUPPORTED
957
0
      png_set_invert_mono(png_ptr);
958
#else
959
      png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
960
#endif
961
962
   /* If you want to shift the pixel values from the range [0,255] or
963
    * [0,65535] to the original [0,7] or [0,31], or whatever range the
964
    * colors were originally in:
965
    */
966
0
   if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
967
0
#ifdef PNG_READ_SHIFT_SUPPORTED
968
0
      if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
969
0
         png_set_shift(png_ptr, &info_ptr->sig_bit);
970
#else
971
      png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
972
#endif
973
974
   /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
975
0
   if ((transforms & PNG_TRANSFORM_BGR) != 0)
976
0
#ifdef PNG_READ_BGR_SUPPORTED
977
0
      png_set_bgr(png_ptr);
978
#else
979
      png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
980
#endif
981
982
   /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
983
0
   if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
984
0
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
985
0
      png_set_swap_alpha(png_ptr);
986
#else
987
      png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
988
#endif
989
990
   /* Swap bytes of 16-bit files to least significant byte first */
991
0
   if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
992
0
#ifdef PNG_READ_SWAP_SUPPORTED
993
0
      png_set_swap(png_ptr);
994
#else
995
      png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
996
#endif
997
998
/* Added at libpng-1.2.41 */
999
   /* Invert the alpha channel from opacity to transparency */
1000
0
   if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
1001
0
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1002
0
      png_set_invert_alpha(png_ptr);
1003
#else
1004
      png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
1005
#endif
1006
1007
/* Added at libpng-1.2.41 */
1008
   /* Expand grayscale image to RGB */
1009
0
   if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0)
1010
0
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1011
0
      png_set_gray_to_rgb(png_ptr);
1012
#else
1013
      png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported");
1014
#endif
1015
1016
/* Added at libpng-1.5.4 */
1017
0
   if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0)
1018
0
#ifdef PNG_READ_EXPAND_16_SUPPORTED
1019
0
      png_set_expand_16(png_ptr);
1020
#else
1021
      png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported");
1022
#endif
1023
1024
   /* We don't handle adding filler bytes */
1025
1026
   /* We use png_read_image and rely on that for interlace handling, but we also
1027
    * call png_read_update_info therefore must turn on interlace handling now:
1028
    */
1029
0
   (void)png_set_interlace_handling(png_ptr);
1030
1031
   /* Optional call to gamma correct and add the background to the palette
1032
    * and update info structure.  REQUIRED if you are expecting libpng to
1033
    * update the palette for you (i.e., you selected such a transform above).
1034
    */
1035
0
   png_read_update_info(png_ptr, info_ptr);
1036
1037
   /* -------------- image transformations end here ------------------- */
1038
1039
0
   png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1040
0
   if (info_ptr->row_pointers == NULL)
1041
0
   {
1042
0
      png_uint_32 iptr;
1043
1044
0
      info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,
1045
0
          info_ptr->height * (sizeof (png_bytep))));
1046
1047
0
      for (iptr=0; iptr<info_ptr->height; iptr++)
1048
0
         info_ptr->row_pointers[iptr] = NULL;
1049
1050
0
      info_ptr->free_me |= PNG_FREE_ROWS;
1051
1052
0
      for (iptr = 0; iptr < info_ptr->height; iptr++)
1053
0
         info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,
1054
0
             png_malloc(png_ptr, info_ptr->rowbytes));
1055
0
   }
1056
1057
0
   png_read_image(png_ptr, info_ptr->row_pointers);
1058
0
   info_ptr->valid |= PNG_INFO_IDAT;
1059
1060
   /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
1061
0
   png_read_end(png_ptr, info_ptr);
1062
1063
0
   PNG_UNUSED(params)
1064
0
}
1065
#endif /* INFO_IMAGE */
1066
#endif /* SEQUENTIAL_READ */
1067
1068
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
1069
/* SIMPLIFIED READ
1070
 *
1071
 * This code currently relies on the sequential reader, though it could easily
1072
 * be made to work with the progressive one.
1073
 */
1074
/* Arguments to png_image_finish_read: */
1075
1076
/* Encoding of PNG data (used by the color-map code) */
1077
0
#  define P_NOTSET  0 /* File encoding not yet known */
1078
0
#  define P_sRGB    1 /* 8-bit encoded to sRGB gamma */
1079
0
#  define P_LINEAR  2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
1080
0
#  define P_FILE    3 /* 8-bit encoded to file gamma, not sRGB or linear */
1081
0
#  define P_LINEAR8 4 /* 8-bit linear: only from a file value */
1082
1083
/* Color-map processing: after libpng has run on the PNG image further
1084
 * processing may be needed to convert the data to color-map indices.
1085
 */
1086
0
#define PNG_CMAP_NONE      0
1087
0
#define PNG_CMAP_GA        1 /* Process GA data to a color-map with alpha */
1088
0
#define PNG_CMAP_TRANS     2 /* Process GA data to a background index */
1089
0
#define PNG_CMAP_RGB       3 /* Process RGB data */
1090
0
#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */
1091
1092
/* The following document where the background is for each processing case. */
1093
0
#define PNG_CMAP_NONE_BACKGROUND      256
1094
0
#define PNG_CMAP_GA_BACKGROUND        231
1095
0
#define PNG_CMAP_TRANS_BACKGROUND     254
1096
0
#define PNG_CMAP_RGB_BACKGROUND       256
1097
0
#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216
1098
1099
typedef struct
1100
{
1101
   /* Arguments: */
1102
   png_imagep image;
1103
   png_voidp  buffer;
1104
   png_int_32 row_stride;
1105
   png_voidp  colormap;
1106
   png_const_colorp background;
1107
   /* Local variables: */
1108
   png_voidp       local_row;
1109
   png_voidp       first_row;
1110
   ptrdiff_t       row_bytes;           /* step between rows */
1111
   int             file_encoding;       /* E_ values above */
1112
   png_fixed_point gamma_to_linear;     /* For P_FILE, reciprocal of gamma */
1113
   int             colormap_processing; /* PNG_CMAP_ values above */
1114
} png_image_read_control;
1115
1116
/* Do all the *safe* initialization - 'safe' means that png_error won't be
1117
 * called, so setting up the jmp_buf is not required.  This means that anything
1118
 * called from here must *not* call png_malloc - it has to call png_malloc_warn
1119
 * instead so that control is returned safely back to this routine.
1120
 */
1121
static int
1122
png_image_read_init(png_imagep image)
1123
425
{
1124
425
   if (image->opaque == NULL)
1125
425
   {
1126
425
      png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image,
1127
425
          png_safe_error, png_safe_warning);
1128
1129
      /* And set the rest of the structure to NULL to ensure that the various
1130
       * fields are consistent.
1131
       */
1132
425
      memset(image, 0, (sizeof *image));
1133
425
      image->version = PNG_IMAGE_VERSION;
1134
1135
425
      if (png_ptr != NULL)
1136
425
      {
1137
425
         png_infop info_ptr = png_create_info_struct(png_ptr);
1138
1139
425
         if (info_ptr != NULL)
1140
425
         {
1141
425
            png_controlp control = png_voidcast(png_controlp,
1142
425
                png_malloc_warn(png_ptr, (sizeof *control)));
1143
1144
425
            if (control != NULL)
1145
425
            {
1146
425
               memset(control, 0, (sizeof *control));
1147
1148
425
               control->png_ptr = png_ptr;
1149
425
               control->info_ptr = info_ptr;
1150
425
               control->for_write = 0;
1151
1152
425
               image->opaque = control;
1153
425
               return 1;
1154
425
            }
1155
1156
            /* Error clean up */
1157
0
            png_destroy_info_struct(png_ptr, &info_ptr);
1158
0
         }
1159
1160
0
         png_destroy_read_struct(&png_ptr, NULL, NULL);
1161
0
      }
1162
1163
0
      return png_image_error(image, "png_image_read: out of memory");
1164
425
   }
1165
1166
0
   return png_image_error(image, "png_image_read: opaque pointer not NULL");
1167
425
}
1168
1169
/* Utility to find the base format of a PNG file from a png_struct. */
1170
static png_uint_32
1171
png_image_format(png_structrp png_ptr)
1172
838
{
1173
838
   png_uint_32 format = 0;
1174
1175
838
   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
1176
418
      format |= PNG_FORMAT_FLAG_COLOR;
1177
1178
838
   if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
1179
170
      format |= PNG_FORMAT_FLAG_ALPHA;
1180
1181
   /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS
1182
    * sets the png_struct fields; that's all we are interested in here.  The
1183
    * precise interaction with an app call to png_set_tRNS and PNG file reading
1184
    * is unclear.
1185
    */
1186
668
   else if (png_ptr->num_trans > 0)
1187
310
      format |= PNG_FORMAT_FLAG_ALPHA;
1188
1189
838
   if (png_ptr->bit_depth == 16)
1190
90
      format |= PNG_FORMAT_FLAG_LINEAR;
1191
1192
838
   if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0)
1193
202
      format |= PNG_FORMAT_FLAG_COLORMAP;
1194
1195
838
   return format;
1196
838
}
1197
1198
static int
1199
chromaticities_match_sRGB(const png_xy *xy)
1200
77
{
1201
77
#  define sRGB_TOLERANCE 1000
1202
77
   static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
1203
77
   {
1204
      /* color      x       y */
1205
77
      /* red   */ 64000, 33000,
1206
77
      /* green */ 30000, 60000,
1207
77
      /* blue  */ 15000,  6000,
1208
77
      /* white */ 31270, 32900
1209
77
   };
1210
1211
77
   if (PNG_OUT_OF_RANGE(xy->whitex, sRGB_xy.whitex,sRGB_TOLERANCE) ||
1212
77
       PNG_OUT_OF_RANGE(xy->whitey, sRGB_xy.whitey,sRGB_TOLERANCE) ||
1213
77
       PNG_OUT_OF_RANGE(xy->redx,   sRGB_xy.redx,  sRGB_TOLERANCE) ||
1214
77
       PNG_OUT_OF_RANGE(xy->redy,   sRGB_xy.redy,  sRGB_TOLERANCE) ||
1215
77
       PNG_OUT_OF_RANGE(xy->greenx, sRGB_xy.greenx,sRGB_TOLERANCE) ||
1216
77
       PNG_OUT_OF_RANGE(xy->greeny, sRGB_xy.greeny,sRGB_TOLERANCE) ||
1217
77
       PNG_OUT_OF_RANGE(xy->bluex,  sRGB_xy.bluex, sRGB_TOLERANCE) ||
1218
77
       PNG_OUT_OF_RANGE(xy->bluey,  sRGB_xy.bluey, sRGB_TOLERANCE))
1219
40
      return 0;
1220
37
   return 1;
1221
77
}
1222
1223
/* Is the given gamma significantly different from sRGB?  The test is the same
1224
 * one used in pngrtran.c when deciding whether to do gamma correction.  The
1225
 * arithmetic optimizes the division by using the fact that the inverse of the
1226
 * file sRGB gamma is 2.2
1227
 */
1228
static int
1229
png_gamma_not_sRGB(png_fixed_point g)
1230
0
{
1231
   /* 1.6.47: use the same sanity checks as used in pngrtran.c */
1232
0
   if (g < PNG_LIB_GAMMA_MIN || g > PNG_LIB_GAMMA_MAX)
1233
0
      return 0; /* Includes the uninitialized value 0 */
1234
1235
0
   return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
1236
0
}
1237
1238
/* Do the main body of a 'png_image_begin_read' function; read the PNG file
1239
 * header and fill in all the information.  This is executed in a safe context,
1240
 * unlike the init routine above.
1241
 */
1242
static int
1243
png_image_is_not_sRGB(png_const_structrp png_ptr)
1244
209
{
1245
   /* Does the colorspace **not** match sRGB?  The flag is only set if the
1246
    * answer can be determined reliably.
1247
    *
1248
    * png_struct::chromaticities always exists since the simplified API
1249
    * requires rgb-to-gray.  The mDCV, cICP and cHRM chunks may all set it to
1250
    * a non-sRGB value, so it needs to be checked but **only** if one of
1251
    * those chunks occured in the file.
1252
    */
1253
   /* Highest priority: check to be safe. */
1254
209
   if (png_has_chunk(png_ptr, cICP) || png_has_chunk(png_ptr, mDCV))
1255
46
      return !chromaticities_match_sRGB(&png_ptr->chromaticities);
1256
1257
   /* If the image is marked as sRGB then it is... */
1258
163
   if (png_has_chunk(png_ptr, sRGB))
1259
20
      return 0;
1260
1261
   /* Last stop: cHRM, must check: */
1262
143
   if (png_has_chunk(png_ptr, cHRM))
1263
31
      return !chromaticities_match_sRGB(&png_ptr->chromaticities);
1264
1265
   /* Else default to sRGB */
1266
112
   return 0;
1267
143
}
1268
1269
static int
1270
png_image_read_header(png_voidp argument)
1271
425
{
1272
425
   png_imagep image = png_voidcast(png_imagep, argument);
1273
425
   png_structrp png_ptr = image->opaque->png_ptr;
1274
425
   png_inforp info_ptr = image->opaque->info_ptr;
1275
1276
425
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1277
425
   png_set_benign_errors(png_ptr, 1/*warn*/);
1278
425
#endif
1279
425
   png_read_info(png_ptr, info_ptr);
1280
1281
   /* Do this the fast way; just read directly out of png_struct. */
1282
425
   image->width = png_ptr->width;
1283
425
   image->height = png_ptr->height;
1284
1285
425
   {
1286
425
      png_uint_32 format = png_image_format(png_ptr);
1287
1288
425
      image->format = format;
1289
1290
      /* Greyscale images don't (typically) have colour space information and
1291
       * using it is pretty much impossible, so use sRGB for grayscale (it
1292
       * doesn't matter r==g==b so the transform is irrelevant.)
1293
       */
1294
425
      if ((format & PNG_FORMAT_FLAG_COLOR) != 0 &&
1295
425
          png_image_is_not_sRGB(png_ptr))
1296
40
         image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
1297
425
   }
1298
1299
   /* We need the maximum number of entries regardless of the format the
1300
    * application sets here.
1301
    */
1302
425
   {
1303
425
      png_uint_32 cmap_entries;
1304
1305
425
      switch (png_ptr->color_type)
1306
425
      {
1307
197
         case PNG_COLOR_TYPE_GRAY:
1308
197
            cmap_entries = 1U << png_ptr->bit_depth;
1309
197
            break;
1310
1311
101
         case PNG_COLOR_TYPE_PALETTE:
1312
101
            cmap_entries = (png_uint_32)png_ptr->num_palette;
1313
101
            break;
1314
1315
121
         default:
1316
121
            cmap_entries = 256;
1317
121
            break;
1318
425
      }
1319
1320
419
      if (cmap_entries > 256)
1321
15
         cmap_entries = 256;
1322
1323
419
      image->colormap_entries = cmap_entries;
1324
419
   }
1325
1326
0
   return 1;
1327
425
}
1328
1329
#ifdef PNG_STDIO_SUPPORTED
1330
int PNGAPI
1331
png_image_begin_read_from_stdio(png_imagep image, FILE *file)
1332
{
1333
   if (image != NULL && image->version == PNG_IMAGE_VERSION)
1334
   {
1335
      if (file != NULL)
1336
      {
1337
         if (png_image_read_init(image) != 0)
1338
         {
1339
            /* This is slightly evil, but png_init_io doesn't do anything other
1340
             * than this and we haven't changed the standard IO functions so
1341
             * this saves a 'safe' function.
1342
             */
1343
            image->opaque->png_ptr->io_ptr = file;
1344
            return png_safe_execute(image, png_image_read_header, image);
1345
         }
1346
      }
1347
1348
      else
1349
         return png_image_error(image,
1350
             "png_image_begin_read_from_stdio: invalid argument");
1351
   }
1352
1353
   else if (image != NULL)
1354
      return png_image_error(image,
1355
          "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
1356
1357
   return 0;
1358
}
1359
1360
int PNGAPI
1361
png_image_begin_read_from_file(png_imagep image, const char *file_name)
1362
{
1363
   if (image != NULL && image->version == PNG_IMAGE_VERSION)
1364
   {
1365
      if (file_name != NULL)
1366
      {
1367
         FILE *fp = fopen(file_name, "rb");
1368
1369
         if (fp != NULL)
1370
         {
1371
            if (png_image_read_init(image) != 0)
1372
            {
1373
               image->opaque->png_ptr->io_ptr = fp;
1374
               image->opaque->owned_file = 1;
1375
               return png_safe_execute(image, png_image_read_header, image);
1376
            }
1377
1378
            /* Clean up: just the opened file. */
1379
            (void)fclose(fp);
1380
         }
1381
1382
         else
1383
            return png_image_error(image, strerror(errno));
1384
      }
1385
1386
      else
1387
         return png_image_error(image,
1388
             "png_image_begin_read_from_file: invalid argument");
1389
   }
1390
1391
   else if (image != NULL)
1392
      return png_image_error(image,
1393
          "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
1394
1395
   return 0;
1396
}
1397
#endif /* STDIO */
1398
1399
static void PNGCBAPI
1400
png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need)
1401
21.7k
{
1402
21.7k
   if (png_ptr != NULL)
1403
21.7k
   {
1404
21.7k
      png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);
1405
21.7k
      if (image != NULL)
1406
21.7k
      {
1407
21.7k
         png_controlp cp = image->opaque;
1408
21.7k
         if (cp != NULL)
1409
21.7k
         {
1410
21.7k
            png_const_bytep memory = cp->memory;
1411
21.7k
            size_t size = cp->size;
1412
1413
21.7k
            if (memory != NULL && size >= need)
1414
21.7k
            {
1415
21.7k
               memcpy(out, memory, need);
1416
21.7k
               cp->memory = memory + need;
1417
21.7k
               cp->size = size - need;
1418
21.7k
               return;
1419
21.7k
            }
1420
1421
0
            png_error(png_ptr, "read beyond end of data");
1422
21.7k
         }
1423
21.7k
      }
1424
1425
0
      png_error(png_ptr, "invalid memory read");
1426
21.7k
   }
1427
21.7k
}
1428
1429
int PNGAPI png_image_begin_read_from_memory(png_imagep image,
1430
    png_const_voidp memory, size_t size)
1431
425
{
1432
425
   if (image != NULL && image->version == PNG_IMAGE_VERSION)
1433
425
   {
1434
425
      if (memory != NULL && size > 0)
1435
425
      {
1436
425
         if (png_image_read_init(image) != 0)
1437
425
         {
1438
            /* Now set the IO functions to read from the memory buffer and
1439
             * store it into io_ptr.  Again do this in-place to avoid calling a
1440
             * libpng function that requires error handling.
1441
             */
1442
425
            image->opaque->memory = png_voidcast(png_const_bytep, memory);
1443
425
            image->opaque->size = size;
1444
425
            image->opaque->png_ptr->io_ptr = image;
1445
425
            image->opaque->png_ptr->read_data_fn = png_image_memory_read;
1446
1447
425
            return png_safe_execute(image, png_image_read_header, image);
1448
425
         }
1449
425
      }
1450
1451
0
      else
1452
0
         return png_image_error(image,
1453
0
             "png_image_begin_read_from_memory: invalid argument");
1454
425
   }
1455
1456
0
   else if (image != NULL)
1457
0
      return png_image_error(image,
1458
0
          "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
1459
1460
0
   return 0;
1461
425
}
1462
1463
/* Utility function to skip chunks that are not used by the simplified image
1464
 * read functions and an appropriate macro to call it.
1465
 */
1466
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1467
static void
1468
png_image_skip_unused_chunks(png_structrp png_ptr)
1469
419
{
1470
   /* Prepare the reader to ignore all recognized chunks whose data will not
1471
    * be used, i.e., all chunks recognized by libpng except for those
1472
    * involved in basic image reading:
1473
    *
1474
    *    IHDR, PLTE, IDAT, IEND
1475
    *
1476
    * Or image data handling:
1477
    *
1478
    *    tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.
1479
    *
1480
    * This provides a small performance improvement and eliminates any
1481
    * potential vulnerability to security problems in the unused chunks.
1482
    *
1483
    * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored
1484
    * too.  This allows the simplified API to be compiled without iCCP support.
1485
    */
1486
419
   {
1487
419
         static const png_byte chunks_to_process[] = {
1488
419
            98,  75,  71,  68, '\0',  /* bKGD */
1489
419
            99,  72,  82,  77, '\0',  /* cHRM */
1490
419
            99,  73,  67,  80, '\0',  /* cICP */
1491
419
           103,  65,  77,  65, '\0',  /* gAMA */
1492
419
           109,  68,  67,  86, '\0',  /* mDCV */
1493
419
           115,  66,  73,  84, '\0',  /* sBIT */
1494
419
           115,  82,  71,  66, '\0',  /* sRGB */
1495
419
         };
1496
1497
       /* Ignore unknown chunks and all other chunks except for the
1498
        * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
1499
        */
1500
419
       png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
1501
419
           NULL, -1);
1502
1503
       /* But do not ignore image data handling chunks */
1504
419
       png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
1505
419
           chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
1506
419
   }
1507
419
}
1508
1509
419
#  define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
1510
#else
1511
#  define PNG_SKIP_CHUNKS(p) ((void)0)
1512
#endif /* HANDLE_AS_UNKNOWN */
1513
1514
/* The following macro gives the exact rounded answer for all values in the
1515
 * range 0..255 (it actually divides by 51.2, but the rounding still generates
1516
 * the correct numbers 0..5
1517
 */
1518
0
#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8)
1519
1520
/* Utility functions to make particular color-maps */
1521
static void
1522
set_file_encoding(png_image_read_control *display)
1523
0
{
1524
0
   png_structrp png_ptr = display->image->opaque->png_ptr;
1525
0
   png_fixed_point g = png_resolve_file_gamma(png_ptr);
1526
1527
   /* PNGv3: the result may be 0 however the 'default_gamma' should have been
1528
    * set before this is called so zero is an error:
1529
    */
1530
0
   if (g == 0)
1531
0
      png_error(png_ptr, "internal: default gamma not set");
1532
1533
0
   if (png_gamma_significant(g) != 0)
1534
0
   {
1535
0
      if (png_gamma_not_sRGB(g) != 0)
1536
0
      {
1537
0
         display->file_encoding = P_FILE;
1538
0
         display->gamma_to_linear = png_reciprocal(g);
1539
0
      }
1540
1541
0
      else
1542
0
         display->file_encoding = P_sRGB;
1543
0
   }
1544
1545
0
   else
1546
0
      display->file_encoding = P_LINEAR8;
1547
0
}
1548
1549
static unsigned int
1550
decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
1551
0
{
1552
0
   if (encoding == P_FILE) /* double check */
1553
0
      encoding = display->file_encoding;
1554
1555
0
   if (encoding == P_NOTSET) /* must be the file encoding */
1556
0
   {
1557
0
      set_file_encoding(display);
1558
0
      encoding = display->file_encoding;
1559
0
   }
1560
1561
0
   switch (encoding)
1562
0
   {
1563
0
      case P_FILE:
1564
0
         value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
1565
0
         break;
1566
1567
0
      case P_sRGB:
1568
0
         value = png_sRGB_table[value];
1569
0
         break;
1570
1571
0
      case P_LINEAR:
1572
0
         break;
1573
1574
0
      case P_LINEAR8:
1575
0
         value *= 257;
1576
0
         break;
1577
1578
0
#ifdef __GNUC__
1579
0
      default:
1580
0
         png_error(display->image->opaque->png_ptr,
1581
0
             "unexpected encoding (internal error)");
1582
0
#endif
1583
0
   }
1584
1585
0
   return value;
1586
0
}
1587
1588
static png_uint_32
1589
png_colormap_compose(png_image_read_control *display,
1590
    png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
1591
    png_uint_32 background, int encoding)
1592
0
{
1593
   /* The file value is composed on the background, the background has the given
1594
    * encoding and so does the result, the file is encoded with P_FILE and the
1595
    * file and alpha are 8-bit values.  The (output) encoding will always be
1596
    * P_LINEAR or P_sRGB.
1597
    */
1598
0
   png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
1599
0
   png_uint_32 b = decode_gamma(display, background, encoding);
1600
1601
   /* The alpha is always an 8-bit value (it comes from the palette), the value
1602
    * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.
1603
    */
1604
0
   f = f * alpha + b * (255-alpha);
1605
1606
0
   if (encoding == P_LINEAR)
1607
0
   {
1608
      /* Scale to 65535; divide by 255, approximately (in fact this is extremely
1609
       * accurate, it divides by 255.00000005937181414556, with no overflow.)
1610
       */
1611
0
      f *= 257; /* Now scaled by 65535 */
1612
0
      f += f >> 16;
1613
0
      f = (f+32768) >> 16;
1614
0
   }
1615
1616
0
   else /* P_sRGB */
1617
0
      f = PNG_sRGB_FROM_LINEAR(f);
1618
1619
0
   return f;
1620
0
}
1621
1622
/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must
1623
 * be 8-bit.
1624
 */
1625
static void
1626
png_create_colormap_entry(png_image_read_control *display,
1627
    png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
1628
    png_uint_32 alpha, int encoding)
1629
0
{
1630
0
   png_imagep image = display->image;
1631
0
   int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
1632
0
       P_LINEAR : P_sRGB;
1633
0
   int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
1634
0
       (red != green || green != blue);
1635
1636
0
   if (ip > 255)
1637
0
      png_error(image->opaque->png_ptr, "color-map index out of range");
1638
1639
   /* Update the cache with whether the file gamma is significantly different
1640
    * from sRGB.
1641
    */
1642
0
   if (encoding == P_FILE)
1643
0
   {
1644
0
      if (display->file_encoding == P_NOTSET)
1645
0
         set_file_encoding(display);
1646
1647
      /* Note that the cached value may be P_FILE too, but if it is then the
1648
       * gamma_to_linear member has been set.
1649
       */
1650
0
      encoding = display->file_encoding;
1651
0
   }
1652
1653
0
   if (encoding == P_FILE)
1654
0
   {
1655
0
      png_fixed_point g = display->gamma_to_linear;
1656
1657
0
      red = png_gamma_16bit_correct(red*257, g);
1658
0
      green = png_gamma_16bit_correct(green*257, g);
1659
0
      blue = png_gamma_16bit_correct(blue*257, g);
1660
1661
0
      if (convert_to_Y != 0 || output_encoding == P_LINEAR)
1662
0
      {
1663
0
         alpha *= 257;
1664
0
         encoding = P_LINEAR;
1665
0
      }
1666
1667
0
      else
1668
0
      {
1669
0
         red = PNG_sRGB_FROM_LINEAR(red * 255);
1670
0
         green = PNG_sRGB_FROM_LINEAR(green * 255);
1671
0
         blue = PNG_sRGB_FROM_LINEAR(blue * 255);
1672
0
         encoding = P_sRGB;
1673
0
      }
1674
0
   }
1675
1676
0
   else if (encoding == P_LINEAR8)
1677
0
   {
1678
      /* This encoding occurs quite frequently in test cases because PngSuite
1679
       * includes a gAMA 1.0 chunk with most images.
1680
       */
1681
0
      red *= 257;
1682
0
      green *= 257;
1683
0
      blue *= 257;
1684
0
      alpha *= 257;
1685
0
      encoding = P_LINEAR;
1686
0
   }
1687
1688
0
   else if (encoding == P_sRGB &&
1689
0
       (convert_to_Y  != 0 || output_encoding == P_LINEAR))
1690
0
   {
1691
      /* The values are 8-bit sRGB values, but must be converted to 16-bit
1692
       * linear.
1693
       */
1694
0
      red = png_sRGB_table[red];
1695
0
      green = png_sRGB_table[green];
1696
0
      blue = png_sRGB_table[blue];
1697
0
      alpha *= 257;
1698
0
      encoding = P_LINEAR;
1699
0
   }
1700
1701
   /* This is set if the color isn't gray but the output is. */
1702
0
   if (encoding == P_LINEAR)
1703
0
   {
1704
0
      if (convert_to_Y != 0)
1705
0
      {
1706
         /* NOTE: these values are copied from png_do_rgb_to_gray */
1707
0
         png_uint_32 y = (png_uint_32)6968 * red  + (png_uint_32)23434 * green +
1708
0
            (png_uint_32)2366 * blue;
1709
1710
0
         if (output_encoding == P_LINEAR)
1711
0
            y = (y + 16384) >> 15;
1712
1713
0
         else
1714
0
         {
1715
            /* y is scaled by 32768, we need it scaled by 255: */
1716
0
            y = (y + 128) >> 8;
1717
0
            y *= 255;
1718
0
            y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
1719
0
            alpha = PNG_DIV257(alpha);
1720
0
            encoding = P_sRGB;
1721
0
         }
1722
1723
0
         blue = red = green = y;
1724
0
      }
1725
1726
0
      else if (output_encoding == P_sRGB)
1727
0
      {
1728
0
         red = PNG_sRGB_FROM_LINEAR(red * 255);
1729
0
         green = PNG_sRGB_FROM_LINEAR(green * 255);
1730
0
         blue = PNG_sRGB_FROM_LINEAR(blue * 255);
1731
0
         alpha = PNG_DIV257(alpha);
1732
0
         encoding = P_sRGB;
1733
0
      }
1734
0
   }
1735
1736
0
   if (encoding != output_encoding)
1737
0
      png_error(image->opaque->png_ptr, "bad encoding (internal error)");
1738
1739
   /* Store the value. */
1740
0
   {
1741
0
#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
1742
0
         int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
1743
0
            (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
1744
#     else
1745
#        define afirst 0
1746
#     endif
1747
0
#     ifdef PNG_FORMAT_BGR_SUPPORTED
1748
0
         int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
1749
#     else
1750
#        define bgr 0
1751
#     endif
1752
1753
0
      if (output_encoding == P_LINEAR)
1754
0
      {
1755
0
         png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);
1756
1757
0
         entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
1758
1759
         /* The linear 16-bit values must be pre-multiplied by the alpha channel
1760
          * value, if less than 65535 (this is, effectively, composite on black
1761
          * if the alpha channel is removed.)
1762
          */
1763
0
         switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
1764
0
         {
1765
0
            case 4:
1766
0
               entry[afirst ? 0 : 3] = (png_uint_16)alpha;
1767
               /* FALLTHROUGH */
1768
1769
0
            case 3:
1770
0
               if (alpha < 65535)
1771
0
               {
1772
0
                  if (alpha > 0)
1773
0
                  {
1774
0
                     blue = (blue * alpha + 32767U)/65535U;
1775
0
                     green = (green * alpha + 32767U)/65535U;
1776
0
                     red = (red * alpha + 32767U)/65535U;
1777
0
                  }
1778
1779
0
                  else
1780
0
                     red = green = blue = 0;
1781
0
               }
1782
0
               entry[afirst + (2 ^ bgr)] = (png_uint_16)blue;
1783
0
               entry[afirst + 1] = (png_uint_16)green;
1784
0
               entry[afirst + bgr] = (png_uint_16)red;
1785
0
               break;
1786
1787
0
            case 2:
1788
0
               entry[1 ^ afirst] = (png_uint_16)alpha;
1789
               /* FALLTHROUGH */
1790
1791
0
            case 1:
1792
0
               if (alpha < 65535)
1793
0
               {
1794
0
                  if (alpha > 0)
1795
0
                     green = (green * alpha + 32767U)/65535U;
1796
1797
0
                  else
1798
0
                     green = 0;
1799
0
               }
1800
0
               entry[afirst] = (png_uint_16)green;
1801
0
               break;
1802
1803
0
            default:
1804
0
               break;
1805
0
         }
1806
0
      }
1807
1808
0
      else /* output encoding is P_sRGB */
1809
0
      {
1810
0
         png_bytep entry = png_voidcast(png_bytep, display->colormap);
1811
1812
0
         entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
1813
1814
0
         switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
1815
0
         {
1816
0
            case 4:
1817
0
               entry[afirst ? 0 : 3] = (png_byte)alpha;
1818
               /* FALLTHROUGH */
1819
0
            case 3:
1820
0
               entry[afirst + (2 ^ bgr)] = (png_byte)blue;
1821
0
               entry[afirst + 1] = (png_byte)green;
1822
0
               entry[afirst + bgr] = (png_byte)red;
1823
0
               break;
1824
1825
0
            case 2:
1826
0
               entry[1 ^ afirst] = (png_byte)alpha;
1827
               /* FALLTHROUGH */
1828
0
            case 1:
1829
0
               entry[afirst] = (png_byte)green;
1830
0
               break;
1831
1832
0
            default:
1833
0
               break;
1834
0
         }
1835
0
      }
1836
1837
#     ifdef afirst
1838
#        undef afirst
1839
#     endif
1840
#     ifdef bgr
1841
#        undef bgr
1842
#     endif
1843
0
   }
1844
0
}
1845
1846
static int
1847
make_gray_file_colormap(png_image_read_control *display)
1848
0
{
1849
0
   unsigned int i;
1850
1851
0
   for (i=0; i<256; ++i)
1852
0
      png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
1853
1854
0
   return (int)i;
1855
0
}
1856
1857
static int
1858
make_gray_colormap(png_image_read_control *display)
1859
0
{
1860
0
   unsigned int i;
1861
1862
0
   for (i=0; i<256; ++i)
1863
0
      png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
1864
1865
0
   return (int)i;
1866
0
}
1867
0
#define PNG_GRAY_COLORMAP_ENTRIES 256
1868
1869
static int
1870
make_ga_colormap(png_image_read_control *display)
1871
0
{
1872
0
   unsigned int i, a;
1873
1874
   /* Alpha is retained, the output will be a color-map with entries
1875
    * selected by six levels of alpha.  One transparent entry, 6 gray
1876
    * levels for all the intermediate alpha values, leaving 230 entries
1877
    * for the opaque grays.  The color-map entries are the six values
1878
    * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the
1879
    * relevant entry.
1880
    *
1881
    * if (alpha > 229) // opaque
1882
    * {
1883
    *    // The 231 entries are selected to make the math below work:
1884
    *    base = 0;
1885
    *    entry = (231 * gray + 128) >> 8;
1886
    * }
1887
    * else if (alpha < 26) // transparent
1888
    * {
1889
    *    base = 231;
1890
    *    entry = 0;
1891
    * }
1892
    * else // partially opaque
1893
    * {
1894
    *    base = 226 + 6 * PNG_DIV51(alpha);
1895
    *    entry = PNG_DIV51(gray);
1896
    * }
1897
    */
1898
0
   i = 0;
1899
0
   while (i < 231)
1900
0
   {
1901
0
      unsigned int gray = (i * 256 + 115) / 231;
1902
0
      png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);
1903
0
   }
1904
1905
   /* 255 is used here for the component values for consistency with the code
1906
    * that undoes premultiplication in pngwrite.c.
1907
    */
1908
0
   png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);
1909
1910
0
   for (a=1; a<5; ++a)
1911
0
   {
1912
0
      unsigned int g;
1913
1914
0
      for (g=0; g<6; ++g)
1915
0
         png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
1916
0
             P_sRGB);
1917
0
   }
1918
1919
0
   return (int)i;
1920
0
}
1921
1922
0
#define PNG_GA_COLORMAP_ENTRIES 256
1923
1924
static int
1925
make_rgb_colormap(png_image_read_control *display)
1926
0
{
1927
0
   unsigned int i, r;
1928
1929
   /* Build a 6x6x6 opaque RGB cube */
1930
0
   for (i=r=0; r<6; ++r)
1931
0
   {
1932
0
      unsigned int g;
1933
1934
0
      for (g=0; g<6; ++g)
1935
0
      {
1936
0
         unsigned int b;
1937
1938
0
         for (b=0; b<6; ++b)
1939
0
            png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
1940
0
                P_sRGB);
1941
0
      }
1942
0
   }
1943
1944
0
   return (int)i;
1945
0
}
1946
1947
0
#define PNG_RGB_COLORMAP_ENTRIES 216
1948
1949
/* Return a palette index to the above palette given three 8-bit sRGB values. */
1950
#define PNG_RGB_INDEX(r,g,b) \
1951
0
   ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))
1952
1953
static int
1954
png_image_read_colormap(png_voidp argument)
1955
0
{
1956
0
   png_image_read_control *display =
1957
0
      png_voidcast(png_image_read_control*, argument);
1958
0
   png_imagep image = display->image;
1959
1960
0
   png_structrp png_ptr = image->opaque->png_ptr;
1961
0
   png_uint_32 output_format = image->format;
1962
0
   int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
1963
0
      P_LINEAR : P_sRGB;
1964
1965
0
   unsigned int cmap_entries;
1966
0
   unsigned int output_processing;        /* Output processing option */
1967
0
   unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */
1968
1969
   /* Background information; the background color and the index of this color
1970
    * in the color-map if it exists (else 256).
1971
    */
1972
0
   unsigned int background_index = 256;
1973
0
   png_uint_32 back_r, back_g, back_b;
1974
1975
   /* Flags to accumulate things that need to be done to the input. */
1976
0
   int expand_tRNS = 0;
1977
1978
   /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is
1979
    * very difficult to do, the results look awful, and it is difficult to see
1980
    * what possible use it is because the application can't control the
1981
    * color-map.
1982
    */
1983
0
   if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||
1984
0
         png_ptr->num_trans > 0) /* alpha in input */ &&
1985
0
      ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)
1986
0
   {
1987
0
      if (output_encoding == P_LINEAR) /* compose on black */
1988
0
         back_b = back_g = back_r = 0;
1989
1990
0
      else if (display->background == NULL /* no way to remove it */)
1991
0
         png_error(png_ptr,
1992
0
             "background color must be supplied to remove alpha/transparency");
1993
1994
      /* Get a copy of the background color (this avoids repeating the checks
1995
       * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the
1996
       * output format.
1997
       */
1998
0
      else
1999
0
      {
2000
0
         back_g = display->background->green;
2001
0
         if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0)
2002
0
         {
2003
0
            back_r = display->background->red;
2004
0
            back_b = display->background->blue;
2005
0
         }
2006
0
         else
2007
0
            back_b = back_r = back_g;
2008
0
      }
2009
0
   }
2010
2011
0
   else if (output_encoding == P_LINEAR)
2012
0
      back_b = back_r = back_g = 65535;
2013
2014
0
   else
2015
0
      back_b = back_r = back_g = 255;
2016
2017
   /* Default the input file gamma if required - this is necessary because
2018
    * libpng assumes that if no gamma information is present the data is in the
2019
    * output format, but the simplified API deduces the gamma from the input
2020
    * format.  The 'default' gamma value is also set by png_set_alpha_mode, but
2021
    * this is happening before any such call, so:
2022
    *
2023
    * TODO: should be an internal API and all this code should be copied into a
2024
    * single common gamma+colorspace file.
2025
    */
2026
0
   if (png_ptr->bit_depth == 16 &&
2027
0
      (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
2028
0
      png_ptr->default_gamma = PNG_GAMMA_LINEAR;
2029
2030
0
   else
2031
0
      png_ptr->default_gamma = PNG_GAMMA_sRGB_INVERSE;
2032
2033
   /* Decide what to do based on the PNG color type of the input data.  The
2034
    * utility function png_create_colormap_entry deals with most aspects of the
2035
    * output transformations; this code works out how to produce bytes of
2036
    * color-map entries from the original format.
2037
    */
2038
0
   switch (png_ptr->color_type)
2039
0
   {
2040
0
      case PNG_COLOR_TYPE_GRAY:
2041
0
         if (png_ptr->bit_depth <= 8)
2042
0
         {
2043
            /* There at most 256 colors in the output, regardless of
2044
             * transparency.
2045
             */
2046
0
            unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;
2047
2048
0
            cmap_entries = 1U << png_ptr->bit_depth;
2049
0
            if (cmap_entries > image->colormap_entries)
2050
0
               png_error(png_ptr, "gray[8] color-map: too few entries");
2051
2052
0
            step = 255 / (cmap_entries - 1);
2053
0
            output_processing = PNG_CMAP_NONE;
2054
2055
            /* If there is a tRNS chunk then this either selects a transparent
2056
             * value or, if the output has no alpha, the background color.
2057
             */
2058
0
            if (png_ptr->num_trans > 0)
2059
0
            {
2060
0
               trans = png_ptr->trans_color.gray;
2061
2062
0
               if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
2063
0
                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
2064
0
            }
2065
2066
            /* png_create_colormap_entry just takes an RGBA and writes the
2067
             * corresponding color-map entry using the format from 'image',
2068
             * including the required conversion to sRGB or linear as
2069
             * appropriate.  The input values are always either sRGB (if the
2070
             * gamma correction flag is 0) or 0..255 scaled file encoded values
2071
             * (if the function must gamma correct them).
2072
             */
2073
0
            for (i=val=0; i<cmap_entries; ++i, val += step)
2074
0
            {
2075
               /* 'i' is a file value.  While this will result in duplicated
2076
                * entries for 8-bit non-sRGB encoded files it is necessary to
2077
                * have non-gamma corrected values to do tRNS handling.
2078
                */
2079
0
               if (i != trans)
2080
0
                  png_create_colormap_entry(display, i, val, val, val, 255,
2081
0
                      P_FILE/*8-bit with file gamma*/);
2082
2083
               /* Else this entry is transparent.  The colors don't matter if
2084
                * there is an alpha channel (back_alpha == 0), but it does no
2085
                * harm to pass them in; the values are not set above so this
2086
                * passes in white.
2087
                *
2088
                * NOTE: this preserves the full precision of the application
2089
                * supplied background color when it is used.
2090
                */
2091
0
               else
2092
0
                  png_create_colormap_entry(display, i, back_r, back_g, back_b,
2093
0
                      back_alpha, output_encoding);
2094
0
            }
2095
2096
            /* We need libpng to preserve the original encoding. */
2097
0
            data_encoding = P_FILE;
2098
2099
            /* The rows from libpng, while technically gray values, are now also
2100
             * color-map indices; however, they may need to be expanded to 1
2101
             * byte per pixel.  This is what png_set_packing does (i.e., it
2102
             * unpacks the bit values into bytes.)
2103
             */
2104
0
            if (png_ptr->bit_depth < 8)
2105
0
               png_set_packing(png_ptr);
2106
0
         }
2107
2108
0
         else /* bit depth is 16 */
2109
0
         {
2110
            /* The 16-bit input values can be converted directly to 8-bit gamma
2111
             * encoded values; however, if a tRNS chunk is present 257 color-map
2112
             * entries are required.  This means that the extra entry requires
2113
             * special processing; add an alpha channel, sacrifice gray level
2114
             * 254 and convert transparent (alpha==0) entries to that.
2115
             *
2116
             * Use libpng to chop the data to 8 bits.  Convert it to sRGB at the
2117
             * same time to minimize quality loss.  If a tRNS chunk is present
2118
             * this means libpng must handle it too; otherwise it is impossible
2119
             * to do the exact match on the 16-bit value.
2120
             *
2121
             * If the output has no alpha channel *and* the background color is
2122
             * gray then it is possible to let libpng handle the substitution by
2123
             * ensuring that the corresponding gray level matches the background
2124
             * color exactly.
2125
             */
2126
0
            data_encoding = P_sRGB;
2127
2128
0
            if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2129
0
               png_error(png_ptr, "gray[16] color-map: too few entries");
2130
2131
0
            cmap_entries = (unsigned int)make_gray_colormap(display);
2132
2133
0
            if (png_ptr->num_trans > 0)
2134
0
            {
2135
0
               unsigned int back_alpha;
2136
2137
0
               if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2138
0
                  back_alpha = 0;
2139
2140
0
               else
2141
0
               {
2142
0
                  if (back_r == back_g && back_g == back_b)
2143
0
                  {
2144
                     /* Background is gray; no special processing will be
2145
                      * required.
2146
                      */
2147
0
                     png_color_16 c;
2148
0
                     png_uint_32 gray = back_g;
2149
2150
0
                     if (output_encoding == P_LINEAR)
2151
0
                     {
2152
0
                        gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2153
2154
                        /* And make sure the corresponding palette entry
2155
                         * matches.
2156
                         */
2157
0
                        png_create_colormap_entry(display, gray, back_g, back_g,
2158
0
                            back_g, 65535, P_LINEAR);
2159
0
                     }
2160
2161
                     /* The background passed to libpng, however, must be the
2162
                      * sRGB value.
2163
                      */
2164
0
                     c.index = 0; /*unused*/
2165
0
                     c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2166
2167
                     /* NOTE: does this work without expanding tRNS to alpha?
2168
                      * It should be the color->gray case below apparently
2169
                      * doesn't.
2170
                      */
2171
0
                     png_set_background_fixed(png_ptr, &c,
2172
0
                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2173
0
                         0/*gamma: not used*/);
2174
2175
0
                     output_processing = PNG_CMAP_NONE;
2176
0
                     break;
2177
0
                  }
2178
#ifdef __COVERITY__
2179
                 /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
2180
                  * here.
2181
                  */
2182
                  back_alpha = 255;
2183
#else
2184
0
                  back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
2185
0
#endif
2186
0
               }
2187
2188
               /* output_processing means that the libpng-processed row will be
2189
                * 8-bit GA and it has to be processing to single byte color-map
2190
                * values.  Entry 254 is replaced by either a completely
2191
                * transparent entry or by the background color at full
2192
                * precision (and the background color is not a simple gray
2193
                * level in this case.)
2194
                */
2195
0
               expand_tRNS = 1;
2196
0
               output_processing = PNG_CMAP_TRANS;
2197
0
               background_index = 254;
2198
2199
               /* And set (overwrite) color-map entry 254 to the actual
2200
                * background color at full precision.
2201
                */
2202
0
               png_create_colormap_entry(display, 254, back_r, back_g, back_b,
2203
0
                   back_alpha, output_encoding);
2204
0
            }
2205
2206
0
            else
2207
0
               output_processing = PNG_CMAP_NONE;
2208
0
         }
2209
0
         break;
2210
2211
0
      case PNG_COLOR_TYPE_GRAY_ALPHA:
2212
         /* 8-bit or 16-bit PNG with two channels - gray and alpha.  A minimum
2213
          * of 65536 combinations.  If, however, the alpha channel is to be
2214
          * removed there are only 256 possibilities if the background is gray.
2215
          * (Otherwise there is a subset of the 65536 possibilities defined by
2216
          * the triangle between black, white and the background color.)
2217
          *
2218
          * Reduce 16-bit files to 8-bit and sRGB encode the result.  No need to
2219
          * worry about tRNS matching - tRNS is ignored if there is an alpha
2220
          * channel.
2221
          */
2222
0
         data_encoding = P_sRGB;
2223
2224
0
         if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2225
0
         {
2226
0
            if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2227
0
               png_error(png_ptr, "gray+alpha color-map: too few entries");
2228
2229
0
            cmap_entries = (unsigned int)make_ga_colormap(display);
2230
2231
0
            background_index = PNG_CMAP_GA_BACKGROUND;
2232
0
            output_processing = PNG_CMAP_GA;
2233
0
         }
2234
2235
0
         else /* alpha is removed */
2236
0
         {
2237
            /* Alpha must be removed as the PNG data is processed when the
2238
             * background is a color because the G and A channels are
2239
             * independent and the vector addition (non-parallel vectors) is a
2240
             * 2-D problem.
2241
             *
2242
             * This can be reduced to the same algorithm as above by making a
2243
             * colormap containing gray levels (for the opaque grays), a
2244
             * background entry (for a transparent pixel) and a set of four six
2245
             * level color values, one set for each intermediate alpha value.
2246
             * See the comments in make_ga_colormap for how this works in the
2247
             * per-pixel processing.
2248
             *
2249
             * If the background is gray, however, we only need a 256 entry gray
2250
             * level color map.  It is sufficient to make the entry generated
2251
             * for the background color be exactly the color specified.
2252
             */
2253
0
            if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||
2254
0
               (back_r == back_g && back_g == back_b))
2255
0
            {
2256
               /* Background is gray; no special processing will be required. */
2257
0
               png_color_16 c;
2258
0
               png_uint_32 gray = back_g;
2259
2260
0
               if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2261
0
                  png_error(png_ptr, "gray-alpha color-map: too few entries");
2262
2263
0
               cmap_entries = (unsigned int)make_gray_colormap(display);
2264
2265
0
               if (output_encoding == P_LINEAR)
2266
0
               {
2267
0
                  gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2268
2269
                  /* And make sure the corresponding palette entry matches. */
2270
0
                  png_create_colormap_entry(display, gray, back_g, back_g,
2271
0
                      back_g, 65535, P_LINEAR);
2272
0
               }
2273
2274
               /* The background passed to libpng, however, must be the sRGB
2275
                * value.
2276
                */
2277
0
               c.index = 0; /*unused*/
2278
0
               c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2279
2280
0
               png_set_background_fixed(png_ptr, &c,
2281
0
                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2282
0
                   0/*gamma: not used*/);
2283
2284
0
               output_processing = PNG_CMAP_NONE;
2285
0
            }
2286
2287
0
            else
2288
0
            {
2289
0
               png_uint_32 i, a;
2290
2291
               /* This is the same as png_make_ga_colormap, above, except that
2292
                * the entries are all opaque.
2293
                */
2294
0
               if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2295
0
                  png_error(png_ptr, "ga-alpha color-map: too few entries");
2296
2297
0
               i = 0;
2298
0
               while (i < 231)
2299
0
               {
2300
0
                  png_uint_32 gray = (i * 256 + 115) / 231;
2301
0
                  png_create_colormap_entry(display, i++, gray, gray, gray,
2302
0
                      255, P_sRGB);
2303
0
               }
2304
2305
               /* NOTE: this preserves the full precision of the application
2306
                * background color.
2307
                */
2308
0
               background_index = i;
2309
0
               png_create_colormap_entry(display, i++, back_r, back_g, back_b,
2310
#ifdef __COVERITY__
2311
                   /* Coverity claims that output_encoding
2312
                    * cannot be 2 (P_LINEAR) here.
2313
                    */ 255U,
2314
#else
2315
0
                    output_encoding == P_LINEAR ? 65535U : 255U,
2316
0
#endif
2317
0
                    output_encoding);
2318
2319
               /* For non-opaque input composite on the sRGB background - this
2320
                * requires inverting the encoding for each component.  The input
2321
                * is still converted to the sRGB encoding because this is a
2322
                * reasonable approximate to the logarithmic curve of human
2323
                * visual sensitivity, at least over the narrow range which PNG
2324
                * represents.  Consequently 'G' is always sRGB encoded, while
2325
                * 'A' is linear.  We need the linear background colors.
2326
                */
2327
0
               if (output_encoding == P_sRGB) /* else already linear */
2328
0
               {
2329
                  /* This may produce a value not exactly matching the
2330
                   * background, but that's ok because these numbers are only
2331
                   * used when alpha != 0
2332
                   */
2333
0
                  back_r = png_sRGB_table[back_r];
2334
0
                  back_g = png_sRGB_table[back_g];
2335
0
                  back_b = png_sRGB_table[back_b];
2336
0
               }
2337
2338
0
               for (a=1; a<5; ++a)
2339
0
               {
2340
0
                  unsigned int g;
2341
2342
                  /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled
2343
                   * by an 8-bit alpha value (0..255).
2344
                   */
2345
0
                  png_uint_32 alpha = 51 * a;
2346
0
                  png_uint_32 back_rx = (255-alpha) * back_r;
2347
0
                  png_uint_32 back_gx = (255-alpha) * back_g;
2348
0
                  png_uint_32 back_bx = (255-alpha) * back_b;
2349
2350
0
                  for (g=0; g<6; ++g)
2351
0
                  {
2352
0
                     png_uint_32 gray = png_sRGB_table[g*51] * alpha;
2353
2354
0
                     png_create_colormap_entry(display, i++,
2355
0
                         PNG_sRGB_FROM_LINEAR(gray + back_rx),
2356
0
                         PNG_sRGB_FROM_LINEAR(gray + back_gx),
2357
0
                         PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
2358
0
                  }
2359
0
               }
2360
2361
0
               cmap_entries = i;
2362
0
               output_processing = PNG_CMAP_GA;
2363
0
            }
2364
0
         }
2365
0
         break;
2366
2367
0
      case PNG_COLOR_TYPE_RGB:
2368
0
      case PNG_COLOR_TYPE_RGB_ALPHA:
2369
         /* Exclude the case where the output is gray; we can always handle this
2370
          * with the cases above.
2371
          */
2372
0
         if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)
2373
0
         {
2374
            /* The color-map will be grayscale, so we may as well convert the
2375
             * input RGB values to a simple grayscale and use the grayscale
2376
             * code above.
2377
             *
2378
             * NOTE: calling this apparently damages the recognition of the
2379
             * transparent color in background color handling; call
2380
             * png_set_tRNS_to_alpha before png_set_background_fixed.
2381
             */
2382
0
            png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
2383
0
                -1);
2384
0
            data_encoding = P_sRGB;
2385
2386
            /* The output will now be one or two 8-bit gray or gray+alpha
2387
             * channels.  The more complex case arises when the input has alpha.
2388
             */
2389
0
            if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2390
0
               png_ptr->num_trans > 0) &&
2391
0
               (output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2392
0
            {
2393
               /* Both input and output have an alpha channel, so no background
2394
                * processing is required; just map the GA bytes to the right
2395
                * color-map entry.
2396
                */
2397
0
               expand_tRNS = 1;
2398
2399
0
               if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2400
0
                  png_error(png_ptr, "rgb[ga] color-map: too few entries");
2401
2402
0
               cmap_entries = (unsigned int)make_ga_colormap(display);
2403
0
               background_index = PNG_CMAP_GA_BACKGROUND;
2404
0
               output_processing = PNG_CMAP_GA;
2405
0
            }
2406
2407
0
            else
2408
0
            {
2409
0
               const png_fixed_point gamma = png_resolve_file_gamma(png_ptr);
2410
2411
               /* Either the input or the output has no alpha channel, so there
2412
                * will be no non-opaque pixels in the color-map; it will just be
2413
                * grayscale.
2414
                */
2415
0
               if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2416
0
                  png_error(png_ptr, "rgb[gray] color-map: too few entries");
2417
2418
               /* Ideally this code would use libpng to do the gamma correction,
2419
                * but if an input alpha channel is to be removed we will hit the
2420
                * libpng bug in gamma+compose+rgb-to-gray (the double gamma
2421
                * correction bug).  Fix this by dropping the gamma correction in
2422
                * this case and doing it in the palette; this will result in
2423
                * duplicate palette entries, but that's better than the
2424
                * alternative of double gamma correction.
2425
                *
2426
                * NOTE: PNGv3: check the resolved result of all the potentially
2427
                * different colour space chunks.
2428
                */
2429
0
               if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2430
0
                  png_ptr->num_trans > 0) &&
2431
0
                  png_gamma_not_sRGB(gamma) != 0)
2432
0
               {
2433
0
                  cmap_entries = (unsigned int)make_gray_file_colormap(display);
2434
0
                  data_encoding = P_FILE;
2435
0
               }
2436
2437
0
               else
2438
0
                  cmap_entries = (unsigned int)make_gray_colormap(display);
2439
2440
               /* But if the input has alpha or transparency it must be removed
2441
                */
2442
0
               if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2443
0
                  png_ptr->num_trans > 0)
2444
0
               {
2445
0
                  png_color_16 c;
2446
0
                  png_uint_32 gray = back_g;
2447
2448
                  /* We need to ensure that the application background exists in
2449
                   * the colormap and that completely transparent pixels map to
2450
                   * it.  Achieve this simply by ensuring that the entry
2451
                   * selected for the background really is the background color.
2452
                   */
2453
0
                  if (data_encoding == P_FILE) /* from the fixup above */
2454
0
                  {
2455
                     /* The app supplied a gray which is in output_encoding, we
2456
                      * need to convert it to a value of the input (P_FILE)
2457
                      * encoding then set this palette entry to the required
2458
                      * output encoding.
2459
                      */
2460
0
                     if (output_encoding == P_sRGB)
2461
0
                        gray = png_sRGB_table[gray]; /* now P_LINEAR */
2462
2463
0
                     gray = PNG_DIV257(png_gamma_16bit_correct(gray, gamma));
2464
                        /* now P_FILE */
2465
2466
                     /* And make sure the corresponding palette entry contains
2467
                      * exactly the required sRGB value.
2468
                      */
2469
0
                     png_create_colormap_entry(display, gray, back_g, back_g,
2470
0
                         back_g, 0/*unused*/, output_encoding);
2471
0
                  }
2472
2473
0
                  else if (output_encoding == P_LINEAR)
2474
0
                  {
2475
0
                     gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2476
2477
                     /* And make sure the corresponding palette entry matches.
2478
                      */
2479
0
                     png_create_colormap_entry(display, gray, back_g, back_g,
2480
0
                        back_g, 0/*unused*/, P_LINEAR);
2481
0
                  }
2482
2483
                  /* The background passed to libpng, however, must be the
2484
                   * output (normally sRGB) value.
2485
                   */
2486
0
                  c.index = 0; /*unused*/
2487
0
                  c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2488
2489
                  /* NOTE: the following is apparently a bug in libpng. Without
2490
                   * it the transparent color recognition in
2491
                   * png_set_background_fixed seems to go wrong.
2492
                   */
2493
0
                  expand_tRNS = 1;
2494
0
                  png_set_background_fixed(png_ptr, &c,
2495
0
                      PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2496
0
                      0/*gamma: not used*/);
2497
0
               }
2498
2499
0
               output_processing = PNG_CMAP_NONE;
2500
0
            }
2501
0
         }
2502
2503
0
         else /* output is color */
2504
0
         {
2505
            /* We could use png_quantize here so long as there is no transparent
2506
             * color or alpha; png_quantize ignores alpha.  Easier overall just
2507
             * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
2508
             * Consequently we always want libpng to produce sRGB data.
2509
             */
2510
0
            data_encoding = P_sRGB;
2511
2512
            /* Is there any transparency or alpha? */
2513
0
            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2514
0
               png_ptr->num_trans > 0)
2515
0
            {
2516
               /* Is there alpha in the output too?  If so all four channels are
2517
                * processed into a special RGB cube with alpha support.
2518
                */
2519
0
               if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2520
0
               {
2521
0
                  png_uint_32 r;
2522
2523
0
                  if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
2524
0
                     png_error(png_ptr, "rgb+alpha color-map: too few entries");
2525
2526
0
                  cmap_entries = (unsigned int)make_rgb_colormap(display);
2527
2528
                  /* Add a transparent entry. */
2529
0
                  png_create_colormap_entry(display, cmap_entries, 255, 255,
2530
0
                      255, 0, P_sRGB);
2531
2532
                  /* This is stored as the background index for the processing
2533
                   * algorithm.
2534
                   */
2535
0
                  background_index = cmap_entries++;
2536
2537
                  /* Add 27 r,g,b entries each with alpha 0.5. */
2538
0
                  for (r=0; r<256; r = (r << 1) | 0x7f)
2539
0
                  {
2540
0
                     png_uint_32 g;
2541
2542
0
                     for (g=0; g<256; g = (g << 1) | 0x7f)
2543
0
                     {
2544
0
                        png_uint_32 b;
2545
2546
                        /* This generates components with the values 0, 127 and
2547
                         * 255
2548
                         */
2549
0
                        for (b=0; b<256; b = (b << 1) | 0x7f)
2550
0
                           png_create_colormap_entry(display, cmap_entries++,
2551
0
                               r, g, b, 128, P_sRGB);
2552
0
                     }
2553
0
                  }
2554
2555
0
                  expand_tRNS = 1;
2556
0
                  output_processing = PNG_CMAP_RGB_ALPHA;
2557
0
               }
2558
2559
0
               else
2560
0
               {
2561
                  /* Alpha/transparency must be removed.  The background must
2562
                   * exist in the color map (achieved by setting adding it after
2563
                   * the 666 color-map).  If the standard processing code will
2564
                   * pick up this entry automatically that's all that is
2565
                   * required; libpng can be called to do the background
2566
                   * processing.
2567
                   */
2568
0
                  unsigned int sample_size =
2569
0
                     PNG_IMAGE_SAMPLE_SIZE(output_format);
2570
0
                  png_uint_32 r, g, b; /* sRGB background */
2571
2572
0
                  if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
2573
0
                     png_error(png_ptr, "rgb-alpha color-map: too few entries");
2574
2575
0
                  cmap_entries = (unsigned int)make_rgb_colormap(display);
2576
2577
0
                  png_create_colormap_entry(display, cmap_entries, back_r,
2578
0
                      back_g, back_b, 0/*unused*/, output_encoding);
2579
2580
0
                  if (output_encoding == P_LINEAR)
2581
0
                  {
2582
0
                     r = PNG_sRGB_FROM_LINEAR(back_r * 255);
2583
0
                     g = PNG_sRGB_FROM_LINEAR(back_g * 255);
2584
0
                     b = PNG_sRGB_FROM_LINEAR(back_b * 255);
2585
0
                  }
2586
2587
0
                  else
2588
0
                  {
2589
0
                     r = back_r;
2590
0
                     g = back_g;
2591
0
                     b = back_g;
2592
0
                  }
2593
2594
                  /* Compare the newly-created color-map entry with the one the
2595
                   * PNG_CMAP_RGB algorithm will use.  If the two entries don't
2596
                   * match, add the new one and set this as the background
2597
                   * index.
2598
                   */
2599
0
                  if (memcmp((png_const_bytep)display->colormap +
2600
0
                      sample_size * cmap_entries,
2601
0
                      (png_const_bytep)display->colormap +
2602
0
                          sample_size * PNG_RGB_INDEX(r,g,b),
2603
0
                     sample_size) != 0)
2604
0
                  {
2605
                     /* The background color must be added. */
2606
0
                     background_index = cmap_entries++;
2607
2608
                     /* Add 27 r,g,b entries each with created by composing with
2609
                      * the background at alpha 0.5.
2610
                      */
2611
0
                     for (r=0; r<256; r = (r << 1) | 0x7f)
2612
0
                     {
2613
0
                        for (g=0; g<256; g = (g << 1) | 0x7f)
2614
0
                        {
2615
                           /* This generates components with the values 0, 127
2616
                            * and 255
2617
                            */
2618
0
                           for (b=0; b<256; b = (b << 1) | 0x7f)
2619
0
                              png_create_colormap_entry(display, cmap_entries++,
2620
0
                                  png_colormap_compose(display, r, P_sRGB, 128,
2621
0
                                      back_r, output_encoding),
2622
0
                                  png_colormap_compose(display, g, P_sRGB, 128,
2623
0
                                      back_g, output_encoding),
2624
0
                                  png_colormap_compose(display, b, P_sRGB, 128,
2625
0
                                      back_b, output_encoding),
2626
0
                                  0/*unused*/, output_encoding);
2627
0
                        }
2628
0
                     }
2629
2630
0
                     expand_tRNS = 1;
2631
0
                     output_processing = PNG_CMAP_RGB_ALPHA;
2632
0
                  }
2633
2634
0
                  else /* background color is in the standard color-map */
2635
0
                  {
2636
0
                     png_color_16 c;
2637
2638
0
                     c.index = 0; /*unused*/
2639
0
                     c.red = (png_uint_16)back_r;
2640
0
                     c.gray = c.green = (png_uint_16)back_g;
2641
0
                     c.blue = (png_uint_16)back_b;
2642
2643
0
                     png_set_background_fixed(png_ptr, &c,
2644
0
                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2645
0
                         0/*gamma: not used*/);
2646
2647
0
                     output_processing = PNG_CMAP_RGB;
2648
0
                  }
2649
0
               }
2650
0
            }
2651
2652
0
            else /* no alpha or transparency in the input */
2653
0
            {
2654
               /* Alpha in the output is irrelevant, simply map the opaque input
2655
                * pixels to the 6x6x6 color-map.
2656
                */
2657
0
               if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
2658
0
                  png_error(png_ptr, "rgb color-map: too few entries");
2659
2660
0
               cmap_entries = (unsigned int)make_rgb_colormap(display);
2661
0
               output_processing = PNG_CMAP_RGB;
2662
0
            }
2663
0
         }
2664
0
         break;
2665
2666
0
      case PNG_COLOR_TYPE_PALETTE:
2667
         /* It's already got a color-map.  It may be necessary to eliminate the
2668
          * tRNS entries though.
2669
          */
2670
0
         {
2671
0
            unsigned int num_trans = png_ptr->num_trans;
2672
0
            png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;
2673
0
            png_const_colorp colormap = png_ptr->palette;
2674
0
            int do_background = trans != NULL &&
2675
0
               (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
2676
0
            unsigned int i;
2677
2678
            /* Just in case: */
2679
0
            if (trans == NULL)
2680
0
               num_trans = 0;
2681
2682
0
            output_processing = PNG_CMAP_NONE;
2683
0
            data_encoding = P_FILE; /* Don't change from color-map indices */
2684
0
            cmap_entries = (unsigned int)png_ptr->num_palette;
2685
0
            if (cmap_entries > 256)
2686
0
               cmap_entries = 256;
2687
2688
0
            if (cmap_entries > (unsigned int)image->colormap_entries)
2689
0
               png_error(png_ptr, "palette color-map: too few entries");
2690
2691
0
            for (i=0; i < cmap_entries; ++i)
2692
0
            {
2693
0
               if (do_background != 0 && i < num_trans && trans[i] < 255)
2694
0
               {
2695
0
                  if (trans[i] == 0)
2696
0
                     png_create_colormap_entry(display, i, back_r, back_g,
2697
0
                         back_b, 0, output_encoding);
2698
2699
0
                  else
2700
0
                  {
2701
                     /* Must compose the PNG file color in the color-map entry
2702
                      * on the sRGB color in 'back'.
2703
                      */
2704
0
                     png_create_colormap_entry(display, i,
2705
0
                         png_colormap_compose(display, colormap[i].red,
2706
0
                             P_FILE, trans[i], back_r, output_encoding),
2707
0
                         png_colormap_compose(display, colormap[i].green,
2708
0
                             P_FILE, trans[i], back_g, output_encoding),
2709
0
                         png_colormap_compose(display, colormap[i].blue,
2710
0
                             P_FILE, trans[i], back_b, output_encoding),
2711
0
                         output_encoding == P_LINEAR ? trans[i] * 257U :
2712
0
                             trans[i],
2713
0
                         output_encoding);
2714
0
                  }
2715
0
               }
2716
2717
0
               else
2718
0
                  png_create_colormap_entry(display, i, colormap[i].red,
2719
0
                      colormap[i].green, colormap[i].blue,
2720
0
                      i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
2721
0
            }
2722
2723
            /* The PNG data may have indices packed in fewer than 8 bits, it
2724
             * must be expanded if so.
2725
             */
2726
0
            if (png_ptr->bit_depth < 8)
2727
0
               png_set_packing(png_ptr);
2728
0
         }
2729
0
         break;
2730
2731
0
      default:
2732
0
         png_error(png_ptr, "invalid PNG color type");
2733
         /*NOT REACHED*/
2734
0
   }
2735
2736
   /* Now deal with the output processing */
2737
0
   if (expand_tRNS != 0 && png_ptr->num_trans > 0 &&
2738
0
       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)
2739
0
      png_set_tRNS_to_alpha(png_ptr);
2740
2741
0
   switch (data_encoding)
2742
0
   {
2743
0
      case P_sRGB:
2744
         /* Change to 8-bit sRGB */
2745
0
         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
2746
         /* FALLTHROUGH */
2747
2748
0
      case P_FILE:
2749
0
         if (png_ptr->bit_depth > 8)
2750
0
            png_set_scale_16(png_ptr);
2751
0
         break;
2752
2753
0
#ifdef __GNUC__
2754
0
      default:
2755
0
         png_error(png_ptr, "bad data option (internal error)");
2756
0
#endif
2757
0
   }
2758
2759
0
   if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
2760
0
      png_error(png_ptr, "color map overflow (BAD internal error)");
2761
2762
0
   image->colormap_entries = cmap_entries;
2763
2764
   /* Double check using the recorded background index */
2765
0
   switch (output_processing)
2766
0
   {
2767
0
      case PNG_CMAP_NONE:
2768
0
         if (background_index != PNG_CMAP_NONE_BACKGROUND)
2769
0
            goto bad_background;
2770
0
         break;
2771
2772
0
      case PNG_CMAP_GA:
2773
0
         if (background_index != PNG_CMAP_GA_BACKGROUND)
2774
0
            goto bad_background;
2775
0
         break;
2776
2777
0
      case PNG_CMAP_TRANS:
2778
0
         if (background_index >= cmap_entries ||
2779
0
            background_index != PNG_CMAP_TRANS_BACKGROUND)
2780
0
            goto bad_background;
2781
0
         break;
2782
2783
0
      case PNG_CMAP_RGB:
2784
0
         if (background_index != PNG_CMAP_RGB_BACKGROUND)
2785
0
            goto bad_background;
2786
0
         break;
2787
2788
0
      case PNG_CMAP_RGB_ALPHA:
2789
0
         if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND)
2790
0
            goto bad_background;
2791
0
         break;
2792
2793
0
      default:
2794
0
         png_error(png_ptr, "bad processing option (internal error)");
2795
2796
0
      bad_background:
2797
0
         png_error(png_ptr, "bad background index (internal error)");
2798
0
   }
2799
2800
0
   display->colormap_processing = (int)output_processing;
2801
2802
0
   return 1/*ok*/;
2803
0
}
2804
2805
/* The final part of the color-map read called from png_image_finish_read. */
2806
static int
2807
png_image_read_and_map(png_voidp argument)
2808
0
{
2809
0
   png_image_read_control *display = png_voidcast(png_image_read_control*,
2810
0
       argument);
2811
0
   png_imagep image = display->image;
2812
0
   png_structrp png_ptr = image->opaque->png_ptr;
2813
0
   int passes;
2814
2815
   /* Called when the libpng data must be transformed into the color-mapped
2816
    * form.  There is a local row buffer in display->local and this routine must
2817
    * do the interlace handling.
2818
    */
2819
0
   switch (png_ptr->interlaced)
2820
0
   {
2821
0
      case PNG_INTERLACE_NONE:
2822
0
         passes = 1;
2823
0
         break;
2824
2825
0
      case PNG_INTERLACE_ADAM7:
2826
0
         passes = PNG_INTERLACE_ADAM7_PASSES;
2827
0
         break;
2828
2829
0
      default:
2830
0
         png_error(png_ptr, "unknown interlace type");
2831
0
   }
2832
2833
0
   {
2834
0
      png_uint_32  height = image->height;
2835
0
      png_uint_32  width = image->width;
2836
0
      int          proc = display->colormap_processing;
2837
0
      png_bytep    first_row = png_voidcast(png_bytep, display->first_row);
2838
0
      ptrdiff_t    step_row = display->row_bytes;
2839
0
      int pass;
2840
2841
0
      for (pass = 0; pass < passes; ++pass)
2842
0
      {
2843
0
         unsigned int     startx, stepx, stepy;
2844
0
         png_uint_32      y;
2845
2846
0
         if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
2847
0
         {
2848
            /* The row may be empty for a short image: */
2849
0
            if (PNG_PASS_COLS(width, pass) == 0)
2850
0
               continue;
2851
2852
0
            startx = PNG_PASS_START_COL(pass);
2853
0
            stepx = PNG_PASS_COL_OFFSET(pass);
2854
0
            y = PNG_PASS_START_ROW(pass);
2855
0
            stepy = PNG_PASS_ROW_OFFSET(pass);
2856
0
         }
2857
2858
0
         else
2859
0
         {
2860
0
            y = 0;
2861
0
            startx = 0;
2862
0
            stepx = stepy = 1;
2863
0
         }
2864
2865
0
         for (; y<height; y += stepy)
2866
0
         {
2867
0
            png_bytep inrow = png_voidcast(png_bytep, display->local_row);
2868
0
            png_bytep outrow = first_row + y * step_row;
2869
0
            png_const_bytep end_row = outrow + width;
2870
2871
            /* Read read the libpng data into the temporary buffer. */
2872
0
            png_read_row(png_ptr, inrow, NULL);
2873
2874
            /* Now process the row according to the processing option, note
2875
             * that the caller verifies that the format of the libpng output
2876
             * data is as required.
2877
             */
2878
0
            outrow += startx;
2879
0
            switch (proc)
2880
0
            {
2881
0
               case PNG_CMAP_GA:
2882
0
                  for (; outrow < end_row; outrow += stepx)
2883
0
                  {
2884
                     /* The data is always in the PNG order */
2885
0
                     unsigned int gray = *inrow++;
2886
0
                     unsigned int alpha = *inrow++;
2887
0
                     unsigned int entry;
2888
2889
                     /* NOTE: this code is copied as a comment in
2890
                      * make_ga_colormap above.  Please update the
2891
                      * comment if you change this code!
2892
                      */
2893
0
                     if (alpha > 229) /* opaque */
2894
0
                     {
2895
0
                        entry = (231 * gray + 128) >> 8;
2896
0
                     }
2897
0
                     else if (alpha < 26) /* transparent */
2898
0
                     {
2899
0
                        entry = 231;
2900
0
                     }
2901
0
                     else /* partially opaque */
2902
0
                     {
2903
0
                        entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);
2904
0
                     }
2905
2906
0
                     *outrow = (png_byte)entry;
2907
0
                  }
2908
0
                  break;
2909
2910
0
               case PNG_CMAP_TRANS:
2911
0
                  for (; outrow < end_row; outrow += stepx)
2912
0
                  {
2913
0
                     png_byte gray = *inrow++;
2914
0
                     png_byte alpha = *inrow++;
2915
2916
0
                     if (alpha == 0)
2917
0
                        *outrow = PNG_CMAP_TRANS_BACKGROUND;
2918
2919
0
                     else if (gray != PNG_CMAP_TRANS_BACKGROUND)
2920
0
                        *outrow = gray;
2921
2922
0
                     else
2923
0
                        *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1);
2924
0
                  }
2925
0
                  break;
2926
2927
0
               case PNG_CMAP_RGB:
2928
0
                  for (; outrow < end_row; outrow += stepx)
2929
0
                  {
2930
0
                     *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]);
2931
0
                     inrow += 3;
2932
0
                  }
2933
0
                  break;
2934
2935
0
               case PNG_CMAP_RGB_ALPHA:
2936
0
                  for (; outrow < end_row; outrow += stepx)
2937
0
                  {
2938
0
                     unsigned int alpha = inrow[3];
2939
2940
                     /* Because the alpha entries only hold alpha==0.5 values
2941
                      * split the processing at alpha==0.25 (64) and 0.75
2942
                      * (196).
2943
                      */
2944
2945
0
                     if (alpha >= 196)
2946
0
                        *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
2947
0
                            inrow[2]);
2948
2949
0
                     else if (alpha < 64)
2950
0
                        *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
2951
2952
0
                     else
2953
0
                     {
2954
                        /* Likewise there are three entries for each of r, g
2955
                         * and b.  We could select the entry by popcount on
2956
                         * the top two bits on those architectures that
2957
                         * support it, this is what the code below does,
2958
                         * crudely.
2959
                         */
2960
0
                        unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1;
2961
2962
                        /* Here are how the values map:
2963
                         *
2964
                         * 0x00 .. 0x3f -> 0
2965
                         * 0x40 .. 0xbf -> 1
2966
                         * 0xc0 .. 0xff -> 2
2967
                         *
2968
                         * So, as above with the explicit alpha checks, the
2969
                         * breakpoints are at 64 and 196.
2970
                         */
2971
0
                        if (inrow[0] & 0x80) back_i += 9; /* red */
2972
0
                        if (inrow[0] & 0x40) back_i += 9;
2973
0
                        if (inrow[0] & 0x80) back_i += 3; /* green */
2974
0
                        if (inrow[0] & 0x40) back_i += 3;
2975
0
                        if (inrow[0] & 0x80) back_i += 1; /* blue */
2976
0
                        if (inrow[0] & 0x40) back_i += 1;
2977
2978
0
                        *outrow = (png_byte)back_i;
2979
0
                     }
2980
2981
0
                     inrow += 4;
2982
0
                  }
2983
0
                  break;
2984
2985
0
               default:
2986
0
                  break;
2987
0
            }
2988
0
         }
2989
0
      }
2990
0
   }
2991
2992
0
   return 1;
2993
0
}
2994
2995
static int
2996
png_image_read_colormapped(png_voidp argument)
2997
0
{
2998
0
   png_image_read_control *display = png_voidcast(png_image_read_control*,
2999
0
       argument);
3000
0
   png_imagep image = display->image;
3001
0
   png_controlp control = image->opaque;
3002
0
   png_structrp png_ptr = control->png_ptr;
3003
0
   png_inforp info_ptr = control->info_ptr;
3004
3005
0
   int passes = 0; /* As a flag */
3006
3007
0
   PNG_SKIP_CHUNKS(png_ptr);
3008
3009
   /* Update the 'info' structure and make sure the result is as required; first
3010
    * make sure to turn on the interlace handling if it will be required
3011
    * (because it can't be turned on *after* the call to png_read_update_info!)
3012
    */
3013
0
   if (display->colormap_processing == PNG_CMAP_NONE)
3014
0
      passes = png_set_interlace_handling(png_ptr);
3015
3016
0
   png_read_update_info(png_ptr, info_ptr);
3017
3018
   /* The expected output can be deduced from the colormap_processing option. */
3019
0
   switch (display->colormap_processing)
3020
0
   {
3021
0
      case PNG_CMAP_NONE:
3022
         /* Output must be one channel and one byte per pixel, the output
3023
          * encoding can be anything.
3024
          */
3025
0
         if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
3026
0
            info_ptr->color_type == PNG_COLOR_TYPE_GRAY) &&
3027
0
            info_ptr->bit_depth == 8)
3028
0
            break;
3029
3030
0
         goto bad_output;
3031
3032
0
      case PNG_CMAP_TRANS:
3033
0
      case PNG_CMAP_GA:
3034
         /* Output must be two channels and the 'G' one must be sRGB, the latter
3035
          * can be checked with an exact number because it should have been set
3036
          * to this number above!
3037
          */
3038
0
         if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
3039
0
            info_ptr->bit_depth == 8 &&
3040
0
            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3041
0
            image->colormap_entries == 256)
3042
0
            break;
3043
3044
0
         goto bad_output;
3045
3046
0
      case PNG_CMAP_RGB:
3047
         /* Output must be 8-bit sRGB encoded RGB */
3048
0
         if (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
3049
0
            info_ptr->bit_depth == 8 &&
3050
0
            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3051
0
            image->colormap_entries == 216)
3052
0
            break;
3053
3054
0
         goto bad_output;
3055
3056
0
      case PNG_CMAP_RGB_ALPHA:
3057
         /* Output must be 8-bit sRGB encoded RGBA */
3058
0
         if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
3059
0
            info_ptr->bit_depth == 8 &&
3060
0
            png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3061
0
            image->colormap_entries == 244 /* 216 + 1 + 27 */)
3062
0
            break;
3063
3064
0
         goto bad_output;
3065
3066
0
      default:
3067
0
      bad_output:
3068
0
         png_error(png_ptr, "bad color-map processing (internal error)");
3069
0
   }
3070
3071
   /* Now read the rows.  Do this here if it is possible to read directly into
3072
    * the output buffer, otherwise allocate a local row buffer of the maximum
3073
    * size libpng requires and call the relevant processing routine safely.
3074
    */
3075
0
   {
3076
0
      png_voidp first_row = display->buffer;
3077
0
      ptrdiff_t row_bytes = display->row_stride;
3078
3079
      /* The following expression is designed to work correctly whether it gives
3080
       * a signed or an unsigned result.
3081
       */
3082
0
      if (row_bytes < 0)
3083
0
      {
3084
0
         char *ptr = png_voidcast(char*, first_row);
3085
0
         ptr += (image->height-1) * (-row_bytes);
3086
0
         first_row = png_voidcast(png_voidp, ptr);
3087
0
      }
3088
3089
0
      display->first_row = first_row;
3090
0
      display->row_bytes = row_bytes;
3091
0
   }
3092
3093
0
   if (passes == 0)
3094
0
   {
3095
0
      int result;
3096
0
      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
3097
3098
0
      display->local_row = row;
3099
0
      result = png_safe_execute(image, png_image_read_and_map, display);
3100
0
      display->local_row = NULL;
3101
0
      png_free(png_ptr, row);
3102
3103
0
      return result;
3104
0
   }
3105
3106
0
   else
3107
0
   {
3108
0
      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
3109
3110
0
      while (--passes >= 0)
3111
0
      {
3112
0
         png_uint_32      y = image->height;
3113
0
         png_bytep        row = png_voidcast(png_bytep, display->first_row);
3114
3115
0
         for (; y > 0; --y)
3116
0
         {
3117
0
            png_read_row(png_ptr, row, NULL);
3118
0
            row += row_bytes;
3119
0
         }
3120
0
      }
3121
3122
0
      return 1;
3123
0
   }
3124
0
}
3125
3126
/* Just the row reading part of png_image_read. */
3127
static int
3128
png_image_read_composite(png_voidp argument)
3129
0
{
3130
0
   png_image_read_control *display = png_voidcast(png_image_read_control*,
3131
0
       argument);
3132
0
   png_imagep image = display->image;
3133
0
   png_structrp png_ptr = image->opaque->png_ptr;
3134
0
   int passes;
3135
3136
0
   switch (png_ptr->interlaced)
3137
0
   {
3138
0
      case PNG_INTERLACE_NONE:
3139
0
         passes = 1;
3140
0
         break;
3141
3142
0
      case PNG_INTERLACE_ADAM7:
3143
0
         passes = PNG_INTERLACE_ADAM7_PASSES;
3144
0
         break;
3145
3146
0
      default:
3147
0
         png_error(png_ptr, "unknown interlace type");
3148
0
   }
3149
3150
0
   {
3151
0
      png_uint_32  height = image->height;
3152
0
      png_uint_32  width = image->width;
3153
0
      ptrdiff_t    step_row = display->row_bytes;
3154
0
      unsigned int channels =
3155
0
          (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
3156
0
      int pass;
3157
3158
0
      for (pass = 0; pass < passes; ++pass)
3159
0
      {
3160
0
         unsigned int     startx, stepx, stepy;
3161
0
         png_uint_32      y;
3162
3163
0
         if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3164
0
         {
3165
            /* The row may be empty for a short image: */
3166
0
            if (PNG_PASS_COLS(width, pass) == 0)
3167
0
               continue;
3168
3169
0
            startx = PNG_PASS_START_COL(pass) * channels;
3170
0
            stepx = PNG_PASS_COL_OFFSET(pass) * channels;
3171
0
            y = PNG_PASS_START_ROW(pass);
3172
0
            stepy = PNG_PASS_ROW_OFFSET(pass);
3173
0
         }
3174
3175
0
         else
3176
0
         {
3177
0
            y = 0;
3178
0
            startx = 0;
3179
0
            stepx = channels;
3180
0
            stepy = 1;
3181
0
         }
3182
3183
0
         for (; y<height; y += stepy)
3184
0
         {
3185
0
            png_bytep inrow = png_voidcast(png_bytep, display->local_row);
3186
0
            png_bytep outrow;
3187
0
            png_const_bytep end_row;
3188
3189
            /* Read the row, which is packed: */
3190
0
            png_read_row(png_ptr, inrow, NULL);
3191
3192
0
            outrow = png_voidcast(png_bytep, display->first_row);
3193
0
            outrow += y * step_row;
3194
0
            end_row = outrow + width * channels;
3195
3196
            /* Now do the composition on each pixel in this row. */
3197
0
            outrow += startx;
3198
0
            for (; outrow < end_row; outrow += stepx)
3199
0
            {
3200
0
               png_byte alpha = inrow[channels];
3201
3202
0
               if (alpha > 0) /* else no change to the output */
3203
0
               {
3204
0
                  unsigned int c;
3205
3206
0
                  for (c=0; c<channels; ++c)
3207
0
                  {
3208
0
                     png_uint_32 component = inrow[c];
3209
3210
0
                     if (alpha < 255) /* else just use component */
3211
0
                     {
3212
                        /* This is PNG_OPTIMIZED_ALPHA, the component value
3213
                         * is a linear 8-bit value.  Combine this with the
3214
                         * current outrow[c] value which is sRGB encoded.
3215
                         * Arithmetic here is 16-bits to preserve the output
3216
                         * values correctly.
3217
                         */
3218
0
                        component *= 257*255; /* =65535 */
3219
0
                        component += (255-alpha)*png_sRGB_table[outrow[c]];
3220
3221
                        /* So 'component' is scaled by 255*65535 and is
3222
                         * therefore appropriate for the sRGB to linear
3223
                         * conversion table.
3224
                         */
3225
0
                        component = PNG_sRGB_FROM_LINEAR(component);
3226
0
                     }
3227
3228
0
                     outrow[c] = (png_byte)component;
3229
0
                  }
3230
0
               }
3231
3232
0
               inrow += channels+1; /* components and alpha channel */
3233
0
            }
3234
0
         }
3235
0
      }
3236
0
   }
3237
3238
0
   return 1;
3239
0
}
3240
3241
/* The do_local_background case; called when all the following transforms are to
3242
 * be done:
3243
 *
3244
 * PNG_RGB_TO_GRAY
3245
 * PNG_COMPOSITE
3246
 * PNG_GAMMA
3247
 *
3248
 * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and
3249
 * PNG_COMPOSITE code performs gamma correction, so we get double gamma
3250
 * correction.  The fix-up is to prevent the PNG_COMPOSITE operation from
3251
 * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha
3252
 * row and handles the removal or pre-multiplication of the alpha channel.
3253
 */
3254
static int
3255
png_image_read_background(png_voidp argument)
3256
0
{
3257
0
   png_image_read_control *display = png_voidcast(png_image_read_control*,
3258
0
       argument);
3259
0
   png_imagep image = display->image;
3260
0
   png_structrp png_ptr = image->opaque->png_ptr;
3261
0
   png_inforp info_ptr = image->opaque->info_ptr;
3262
0
   png_uint_32 height = image->height;
3263
0
   png_uint_32 width = image->width;
3264
0
   int pass, passes;
3265
3266
   /* Double check the convoluted logic below.  We expect to get here with
3267
    * libpng doing rgb to gray and gamma correction but background processing
3268
    * left to the png_image_read_background function.  The rows libpng produce
3269
    * might be 8 or 16-bit but should always have two channels; gray plus alpha.
3270
    */
3271
0
   if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
3272
0
      png_error(png_ptr, "lost rgb to gray");
3273
3274
0
   if ((png_ptr->transformations & PNG_COMPOSE) != 0)
3275
0
      png_error(png_ptr, "unexpected compose");
3276
3277
0
   if (png_get_channels(png_ptr, info_ptr) != 2)
3278
0
      png_error(png_ptr, "lost/gained channels");
3279
3280
   /* Expect the 8-bit case to always remove the alpha channel */
3281
0
   if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 &&
3282
0
      (image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
3283
0
      png_error(png_ptr, "unexpected 8-bit transformation");
3284
3285
0
   switch (png_ptr->interlaced)
3286
0
   {
3287
0
      case PNG_INTERLACE_NONE:
3288
0
         passes = 1;
3289
0
         break;
3290
3291
0
      case PNG_INTERLACE_ADAM7:
3292
0
         passes = PNG_INTERLACE_ADAM7_PASSES;
3293
0
         break;
3294
3295
0
      default:
3296
0
         png_error(png_ptr, "unknown interlace type");
3297
0
   }
3298
3299
   /* Use direct access to info_ptr here because otherwise the simplified API
3300
    * would require PNG_EASY_ACCESS_SUPPORTED (just for this.)  Note this is
3301
    * checking the value after libpng expansions, not the original value in the
3302
    * PNG.
3303
    */
3304
0
   switch (info_ptr->bit_depth)
3305
0
   {
3306
0
      case 8:
3307
         /* 8-bit sRGB gray values with an alpha channel; the alpha channel is
3308
          * to be removed by composing on a background: either the row if
3309
          * display->background is NULL or display->background->green if not.
3310
          * Unlike the code above ALPHA_OPTIMIZED has *not* been done.
3311
          */
3312
0
         {
3313
0
            png_bytep first_row = png_voidcast(png_bytep, display->first_row);
3314
0
            ptrdiff_t step_row = display->row_bytes;
3315
3316
0
            for (pass = 0; pass < passes; ++pass)
3317
0
            {
3318
0
               unsigned int     startx, stepx, stepy;
3319
0
               png_uint_32      y;
3320
3321
0
               if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3322
0
               {
3323
                  /* The row may be empty for a short image: */
3324
0
                  if (PNG_PASS_COLS(width, pass) == 0)
3325
0
                     continue;
3326
3327
0
                  startx = PNG_PASS_START_COL(pass);
3328
0
                  stepx = PNG_PASS_COL_OFFSET(pass);
3329
0
                  y = PNG_PASS_START_ROW(pass);
3330
0
                  stepy = PNG_PASS_ROW_OFFSET(pass);
3331
0
               }
3332
3333
0
               else
3334
0
               {
3335
0
                  y = 0;
3336
0
                  startx = 0;
3337
0
                  stepx = stepy = 1;
3338
0
               }
3339
3340
0
               if (display->background == NULL)
3341
0
               {
3342
0
                  for (; y<height; y += stepy)
3343
0
                  {
3344
0
                     png_bytep inrow = png_voidcast(png_bytep,
3345
0
                         display->local_row);
3346
0
                     png_bytep outrow = first_row + y * step_row;
3347
0
                     png_const_bytep end_row = outrow + width;
3348
3349
                     /* Read the row, which is packed: */
3350
0
                     png_read_row(png_ptr, inrow, NULL);
3351
3352
                     /* Now do the composition on each pixel in this row. */
3353
0
                     outrow += startx;
3354
0
                     for (; outrow < end_row; outrow += stepx)
3355
0
                     {
3356
0
                        png_byte alpha = inrow[1];
3357
3358
0
                        if (alpha > 0) /* else no change to the output */
3359
0
                        {
3360
0
                           png_uint_32 component = inrow[0];
3361
3362
0
                           if (alpha < 255) /* else just use component */
3363
0
                           {
3364
                              /* Since PNG_OPTIMIZED_ALPHA was not set it is
3365
                               * necessary to invert the sRGB transfer
3366
                               * function and multiply the alpha out.
3367
                               */
3368
0
                              component = png_sRGB_table[component] * alpha;
3369
0
                              component += png_sRGB_table[outrow[0]] *
3370
0
                                 (255-alpha);
3371
0
                              component = PNG_sRGB_FROM_LINEAR(component);
3372
0
                           }
3373
3374
0
                           outrow[0] = (png_byte)component;
3375
0
                        }
3376
3377
0
                        inrow += 2; /* gray and alpha channel */
3378
0
                     }
3379
0
                  }
3380
0
               }
3381
3382
0
               else /* constant background value */
3383
0
               {
3384
0
                  png_byte background8 = display->background->green;
3385
0
                  png_uint_16 background = png_sRGB_table[background8];
3386
3387
0
                  for (; y<height; y += stepy)
3388
0
                  {
3389
0
                     png_bytep inrow = png_voidcast(png_bytep,
3390
0
                         display->local_row);
3391
0
                     png_bytep outrow = first_row + y * step_row;
3392
0
                     png_const_bytep end_row = outrow + width;
3393
3394
                     /* Read the row, which is packed: */
3395
0
                     png_read_row(png_ptr, inrow, NULL);
3396
3397
                     /* Now do the composition on each pixel in this row. */
3398
0
                     outrow += startx;
3399
0
                     for (; outrow < end_row; outrow += stepx)
3400
0
                     {
3401
0
                        png_byte alpha = inrow[1];
3402
3403
0
                        if (alpha > 0) /* else use background */
3404
0
                        {
3405
0
                           png_uint_32 component = inrow[0];
3406
3407
0
                           if (alpha < 255) /* else just use component */
3408
0
                           {
3409
0
                              component = png_sRGB_table[component] * alpha;
3410
0
                              component += background * (255-alpha);
3411
0
                              component = PNG_sRGB_FROM_LINEAR(component);
3412
0
                           }
3413
3414
0
                           outrow[0] = (png_byte)component;
3415
0
                        }
3416
3417
0
                        else
3418
0
                           outrow[0] = background8;
3419
3420
0
                        inrow += 2; /* gray and alpha channel */
3421
0
                     }
3422
0
                  }
3423
0
               }
3424
0
            }
3425
0
         }
3426
0
         break;
3427
3428
0
      case 16:
3429
         /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must
3430
          * still be done and, maybe, the alpha channel removed.  This code also
3431
          * handles the alpha-first option.
3432
          */
3433
0
         {
3434
0
            png_uint_16p first_row = png_voidcast(png_uint_16p,
3435
0
                display->first_row);
3436
            /* The division by two is safe because the caller passed in a
3437
             * stride which was multiplied by 2 (below) to get row_bytes.
3438
             */
3439
0
            ptrdiff_t    step_row = display->row_bytes / 2;
3440
0
            unsigned int preserve_alpha = (image->format &
3441
0
                PNG_FORMAT_FLAG_ALPHA) != 0;
3442
0
            unsigned int outchannels = 1U+preserve_alpha;
3443
0
            int swap_alpha = 0;
3444
3445
0
#           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
3446
0
               if (preserve_alpha != 0 &&
3447
0
                   (image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
3448
0
                  swap_alpha = 1;
3449
0
#           endif
3450
3451
0
            for (pass = 0; pass < passes; ++pass)
3452
0
            {
3453
0
               unsigned int     startx, stepx, stepy;
3454
0
               png_uint_32      y;
3455
3456
               /* The 'x' start and step are adjusted to output components here.
3457
                */
3458
0
               if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3459
0
               {
3460
                  /* The row may be empty for a short image: */
3461
0
                  if (PNG_PASS_COLS(width, pass) == 0)
3462
0
                     continue;
3463
3464
0
                  startx = PNG_PASS_START_COL(pass) * outchannels;
3465
0
                  stepx = PNG_PASS_COL_OFFSET(pass) * outchannels;
3466
0
                  y = PNG_PASS_START_ROW(pass);
3467
0
                  stepy = PNG_PASS_ROW_OFFSET(pass);
3468
0
               }
3469
3470
0
               else
3471
0
               {
3472
0
                  y = 0;
3473
0
                  startx = 0;
3474
0
                  stepx = outchannels;
3475
0
                  stepy = 1;
3476
0
               }
3477
3478
0
               for (; y<height; y += stepy)
3479
0
               {
3480
0
                  png_const_uint_16p inrow;
3481
0
                  png_uint_16p outrow = first_row + y*step_row;
3482
0
                  png_uint_16p end_row = outrow + width * outchannels;
3483
3484
                  /* Read the row, which is packed: */
3485
0
                  png_read_row(png_ptr, png_voidcast(png_bytep,
3486
0
                      display->local_row), NULL);
3487
0
                  inrow = png_voidcast(png_const_uint_16p, display->local_row);
3488
3489
                  /* Now do the pre-multiplication on each pixel in this row.
3490
                   */
3491
0
                  outrow += startx;
3492
0
                  for (; outrow < end_row; outrow += stepx)
3493
0
                  {
3494
0
                     png_uint_32 component = inrow[0];
3495
0
                     png_uint_16 alpha = inrow[1];
3496
3497
0
                     if (alpha > 0) /* else 0 */
3498
0
                     {
3499
0
                        if (alpha < 65535) /* else just use component */
3500
0
                        {
3501
0
                           component *= alpha;
3502
0
                           component += 32767;
3503
0
                           component /= 65535;
3504
0
                        }
3505
0
                     }
3506
3507
0
                     else
3508
0
                        component = 0;
3509
3510
0
                     outrow[swap_alpha] = (png_uint_16)component;
3511
0
                     if (preserve_alpha != 0)
3512
0
                        outrow[1 ^ swap_alpha] = alpha;
3513
3514
0
                     inrow += 2; /* components and alpha channel */
3515
0
                  }
3516
0
               }
3517
0
            }
3518
0
         }
3519
0
         break;
3520
3521
0
#ifdef __GNUC__
3522
0
      default:
3523
0
         png_error(png_ptr, "unexpected bit depth");
3524
0
#endif
3525
0
   }
3526
3527
0
   return 1;
3528
0
}
3529
3530
/* The guts of png_image_finish_read as a png_safe_execute callback. */
3531
static int
3532
png_image_read_direct(png_voidp argument)
3533
419
{
3534
419
   png_image_read_control *display = png_voidcast(png_image_read_control*,
3535
419
       argument);
3536
419
   png_imagep image = display->image;
3537
419
   png_structrp png_ptr = image->opaque->png_ptr;
3538
419
   png_inforp info_ptr = image->opaque->info_ptr;
3539
3540
419
   png_uint_32 format = image->format;
3541
419
   int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;
3542
419
   int do_local_compose = 0;
3543
419
   int do_local_background = 0; /* to avoid double gamma correction bug */
3544
419
   int passes = 0;
3545
3546
   /* Add transforms to ensure the correct output format is produced then check
3547
    * that the required implementation support is there.  Always expand; always
3548
    * need 8 bits minimum, no palette and expanded tRNS.
3549
    */
3550
419
   png_set_expand(png_ptr);
3551
3552
   /* Now check the format to see if it was modified. */
3553
419
   {
3554
419
      png_uint_32 base_format = png_image_format(png_ptr) &
3555
419
         ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */;
3556
419
      png_uint_32 change = format ^ base_format;
3557
419
      png_fixed_point output_gamma;
3558
419
      int mode; /* alpha mode */
3559
3560
      /* Do this first so that we have a record if rgb to gray is happening. */
3561
419
      if ((change & PNG_FORMAT_FLAG_COLOR) != 0)
3562
210
      {
3563
         /* gray<->color transformation required. */
3564
210
         if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
3565
210
            png_set_gray_to_rgb(png_ptr);
3566
3567
0
         else
3568
0
         {
3569
            /* libpng can't do both rgb to gray and
3570
             * background/pre-multiplication if there is also significant gamma
3571
             * correction, because both operations require linear colors and
3572
             * the code only supports one transform doing the gamma correction.
3573
             * Handle this by doing the pre-multiplication or background
3574
             * operation in this code, if necessary.
3575
             *
3576
             * TODO: fix this by rewriting pngrtran.c (!)
3577
             *
3578
             * For the moment (given that fixing this in pngrtran.c is an
3579
             * enormous change) 'do_local_background' is used to indicate that
3580
             * the problem exists.
3581
             */
3582
0
            if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
3583
0
               do_local_background = 1/*maybe*/;
3584
3585
0
            png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
3586
0
                PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
3587
0
         }
3588
3589
210
         change &= ~PNG_FORMAT_FLAG_COLOR;
3590
210
      }
3591
3592
      /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.
3593
       */
3594
419
      {
3595
         /* This is safe but should no longer be necessary as
3596
          * png_ptr->default_gamma should have been set after the
3597
          * info-before-IDAT was read in png_image_read_header.
3598
          *
3599
          * TODO: 1.8: remove this and see what happens.
3600
          */
3601
419
         png_fixed_point input_gamma_default;
3602
3603
419
         if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 &&
3604
419
             (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
3605
45
            input_gamma_default = PNG_GAMMA_LINEAR;
3606
374
         else
3607
374
            input_gamma_default = PNG_DEFAULT_sRGB;
3608
3609
         /* Call png_set_alpha_mode to set the default for the input gamma; the
3610
          * output gamma is set by a second call below.
3611
          */
3612
419
         png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);
3613
419
      }
3614
3615
419
      if (linear != 0)
3616
0
      {
3617
         /* If there *is* an alpha channel in the input it must be multiplied
3618
          * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.
3619
          */
3620
0
         if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
3621
0
            mode = PNG_ALPHA_STANDARD; /* associated alpha */
3622
3623
0
         else
3624
0
            mode = PNG_ALPHA_PNG;
3625
3626
0
         output_gamma = PNG_GAMMA_LINEAR;
3627
0
      }
3628
3629
419
      else
3630
419
      {
3631
419
         mode = PNG_ALPHA_PNG;
3632
419
         output_gamma = PNG_DEFAULT_sRGB;
3633
419
      }
3634
3635
419
      if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0)
3636
0
      {
3637
0
         mode = PNG_ALPHA_OPTIMIZED;
3638
0
         change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
3639
0
      }
3640
3641
      /* If 'do_local_background' is set check for the presence of gamma
3642
       * correction; this is part of the work-round for the libpng bug
3643
       * described above.
3644
       *
3645
       * TODO: fix libpng and remove this.
3646
       */
3647
419
      if (do_local_background != 0)
3648
0
      {
3649
0
         png_fixed_point gtest;
3650
3651
         /* This is 'png_gamma_threshold' from pngrtran.c; the test used for
3652
          * gamma correction, the screen gamma hasn't been set on png_struct
3653
          * yet; it's set below.  png_struct::gamma, however, is set to the
3654
          * final value.
3655
          */
3656
0
         if (png_muldiv(&gtest, output_gamma,
3657
0
                  png_resolve_file_gamma(png_ptr), PNG_FP_1) != 0 &&
3658
0
             png_gamma_significant(gtest) == 0)
3659
0
            do_local_background = 0;
3660
3661
0
         else if (mode == PNG_ALPHA_STANDARD)
3662
0
         {
3663
0
            do_local_background = 2/*required*/;
3664
0
            mode = PNG_ALPHA_PNG; /* prevent libpng doing it */
3665
0
         }
3666
3667
         /* else leave as 1 for the checks below */
3668
0
      }
3669
3670
      /* If the bit-depth changes then handle that here. */
3671
419
      if ((change & PNG_FORMAT_FLAG_LINEAR) != 0)
3672
45
      {
3673
45
         if (linear != 0 /*16-bit output*/)
3674
0
            png_set_expand_16(png_ptr);
3675
3676
45
         else /* 8-bit output */
3677
45
            png_set_scale_16(png_ptr);
3678
3679
45
         change &= ~PNG_FORMAT_FLAG_LINEAR;
3680
45
      }
3681
3682
      /* Now the background/alpha channel changes. */
3683
419
      if ((change & PNG_FORMAT_FLAG_ALPHA) != 0)
3684
179
      {
3685
         /* Removing an alpha channel requires composition for the 8-bit
3686
          * formats; for the 16-bit it is already done, above, by the
3687
          * pre-multiplication and the channel just needs to be stripped.
3688
          */
3689
179
         if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
3690
0
         {
3691
            /* If RGB->gray is happening the alpha channel must be left and the
3692
             * operation completed locally.
3693
             *
3694
             * TODO: fix libpng and remove this.
3695
             */
3696
0
            if (do_local_background != 0)
3697
0
               do_local_background = 2/*required*/;
3698
3699
            /* 16-bit output: just remove the channel */
3700
0
            else if (linear != 0) /* compose on black (well, pre-multiply) */
3701
0
               png_set_strip_alpha(png_ptr);
3702
3703
            /* 8-bit output: do an appropriate compose */
3704
0
            else if (display->background != NULL)
3705
0
            {
3706
0
               png_color_16 c;
3707
3708
0
               c.index = 0; /*unused*/
3709
0
               c.red = display->background->red;
3710
0
               c.green = display->background->green;
3711
0
               c.blue = display->background->blue;
3712
0
               c.gray = display->background->green;
3713
3714
               /* This is always an 8-bit sRGB value, using the 'green' channel
3715
                * for gray is much better than calculating the luminance here;
3716
                * we can get off-by-one errors in that calculation relative to
3717
                * the app expectations and that will show up in transparent
3718
                * pixels.
3719
                */
3720
0
               png_set_background_fixed(png_ptr, &c,
3721
0
                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
3722
0
                   0/*gamma: not used*/);
3723
0
            }
3724
3725
0
            else /* compose on row: implemented below. */
3726
0
            {
3727
0
               do_local_compose = 1;
3728
               /* This leaves the alpha channel in the output, so it has to be
3729
                * removed by the code below.  Set the encoding to the 'OPTIMIZE'
3730
                * one so the code only has to hack on the pixels that require
3731
                * composition.
3732
                */
3733
0
               mode = PNG_ALPHA_OPTIMIZED;
3734
0
            }
3735
0
         }
3736
3737
179
         else /* output needs an alpha channel */
3738
179
         {
3739
            /* This is tricky because it happens before the swap operation has
3740
             * been accomplished; however, the swap does *not* swap the added
3741
             * alpha channel (weird API), so it must be added in the correct
3742
             * place.
3743
             */
3744
179
            png_uint_32 filler; /* opaque filler */
3745
179
            int where;
3746
3747
179
            if (linear != 0)
3748
0
               filler = 65535;
3749
3750
179
            else
3751
179
               filler = 255;
3752
3753
179
#ifdef PNG_FORMAT_AFIRST_SUPPORTED
3754
179
            if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
3755
0
            {
3756
0
               where = PNG_FILLER_BEFORE;
3757
0
               change &= ~PNG_FORMAT_FLAG_AFIRST;
3758
0
            }
3759
3760
179
            else
3761
179
#endif
3762
179
            where = PNG_FILLER_AFTER;
3763
3764
179
            png_set_add_alpha(png_ptr, filler, where);
3765
179
         }
3766
3767
         /* This stops the (irrelevant) call to swap_alpha below. */
3768
179
         change &= ~PNG_FORMAT_FLAG_ALPHA;
3769
179
      }
3770
3771
      /* Now set the alpha mode correctly; this is always done, even if there is
3772
       * no alpha channel in either the input or the output because it correctly
3773
       * sets the output gamma.
3774
       */
3775
419
      png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);
3776
3777
419
#     ifdef PNG_FORMAT_BGR_SUPPORTED
3778
419
         if ((change & PNG_FORMAT_FLAG_BGR) != 0)
3779
0
         {
3780
            /* Check only the output format; PNG is never BGR; don't do this if
3781
             * the output is gray, but fix up the 'format' value in that case.
3782
             */
3783
0
            if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
3784
0
               png_set_bgr(png_ptr);
3785
3786
0
            else
3787
0
               format &= ~PNG_FORMAT_FLAG_BGR;
3788
3789
0
            change &= ~PNG_FORMAT_FLAG_BGR;
3790
0
         }
3791
419
#     endif
3792
3793
419
#     ifdef PNG_FORMAT_AFIRST_SUPPORTED
3794
419
         if ((change & PNG_FORMAT_FLAG_AFIRST) != 0)
3795
0
         {
3796
            /* Only relevant if there is an alpha channel - it's particularly
3797
             * important to handle this correctly because do_local_compose may
3798
             * be set above and then libpng will keep the alpha channel for this
3799
             * code to remove.
3800
             */
3801
0
            if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)
3802
0
            {
3803
               /* Disable this if doing a local background,
3804
                * TODO: remove this when local background is no longer required.
3805
                */
3806
0
               if (do_local_background != 2)
3807
0
                  png_set_swap_alpha(png_ptr);
3808
0
            }
3809
3810
0
            else
3811
0
               format &= ~PNG_FORMAT_FLAG_AFIRST;
3812
3813
0
            change &= ~PNG_FORMAT_FLAG_AFIRST;
3814
0
         }
3815
419
#     endif
3816
3817
      /* If the *output* is 16-bit then we need to check for a byte-swap on this
3818
       * architecture.
3819
       */
3820
419
      if (linear != 0)
3821
0
      {
3822
0
         png_uint_16 le = 0x0001;
3823
3824
0
         if ((*(png_const_bytep) & le) != 0)
3825
0
            png_set_swap(png_ptr);
3826
0
      }
3827
3828
      /* If change is not now 0 some transformation is missing - error out. */
3829
419
      if (change != 0)
3830
0
         png_error(png_ptr, "png_read_image: unsupported transformation");
3831
419
   }
3832
3833
419
   PNG_SKIP_CHUNKS(png_ptr);
3834
3835
   /* Update the 'info' structure and make sure the result is as required; first
3836
    * make sure to turn on the interlace handling if it will be required
3837
    * (because it can't be turned on *after* the call to png_read_update_info!)
3838
    *
3839
    * TODO: remove the do_local_background fixup below.
3840
    */
3841
419
   if (do_local_compose == 0 && do_local_background != 2)
3842
419
      passes = png_set_interlace_handling(png_ptr);
3843
3844
419
   png_read_update_info(png_ptr, info_ptr);
3845
3846
419
   {
3847
419
      png_uint_32 info_format = 0;
3848
3849
419
      if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
3850
419
         info_format |= PNG_FORMAT_FLAG_COLOR;
3851
3852
419
      if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
3853
419
      {
3854
         /* do_local_compose removes this channel below. */
3855
419
         if (do_local_compose == 0)
3856
419
         {
3857
            /* do_local_background does the same if required. */
3858
419
            if (do_local_background != 2 ||
3859
419
               (format & PNG_FORMAT_FLAG_ALPHA) != 0)
3860
419
               info_format |= PNG_FORMAT_FLAG_ALPHA;
3861
419
         }
3862
419
      }
3863
3864
0
      else if (do_local_compose != 0) /* internal error */
3865
0
         png_error(png_ptr, "png_image_read: alpha channel lost");
3866
3867
419
      if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) {
3868
0
         info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
3869
0
      }
3870
3871
419
      if (info_ptr->bit_depth == 16)
3872
0
         info_format |= PNG_FORMAT_FLAG_LINEAR;
3873
3874
419
#ifdef PNG_FORMAT_BGR_SUPPORTED
3875
419
      if ((png_ptr->transformations & PNG_BGR) != 0)
3876
0
         info_format |= PNG_FORMAT_FLAG_BGR;
3877
419
#endif
3878
3879
419
#ifdef PNG_FORMAT_AFIRST_SUPPORTED
3880
419
         if (do_local_background == 2)
3881
0
         {
3882
0
            if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
3883
0
               info_format |= PNG_FORMAT_FLAG_AFIRST;
3884
0
         }
3885
3886
419
         if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 ||
3887
419
            ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&
3888
419
            (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))
3889
0
         {
3890
0
            if (do_local_background == 2)
3891
0
               png_error(png_ptr, "unexpected alpha swap transformation");
3892
3893
0
            info_format |= PNG_FORMAT_FLAG_AFIRST;
3894
0
         }
3895
419
#     endif
3896
3897
      /* This is actually an internal error. */
3898
419
      if (info_format != format)
3899
0
         png_error(png_ptr, "png_read_image: invalid transformations");
3900
419
   }
3901
3902
   /* Now read the rows.  If do_local_compose is set then it is necessary to use
3903
    * a local row buffer.  The output will be GA, RGBA or BGRA and must be
3904
    * converted to G, RGB or BGR as appropriate.  The 'local_row' member of the
3905
    * display acts as a flag.
3906
    */
3907
419
   {
3908
419
      png_voidp first_row = display->buffer;
3909
419
      ptrdiff_t row_bytes = display->row_stride;
3910
3911
419
      if (linear != 0)
3912
0
         row_bytes *= 2;
3913
3914
      /* The following expression is designed to work correctly whether it gives
3915
       * a signed or an unsigned result.
3916
       */
3917
419
      if (row_bytes < 0)
3918
0
      {
3919
0
         char *ptr = png_voidcast(char*, first_row);
3920
0
         ptr += (image->height-1) * (-row_bytes);
3921
0
         first_row = png_voidcast(png_voidp, ptr);
3922
0
      }
3923
3924
419
      display->first_row = first_row;
3925
419
      display->row_bytes = row_bytes;
3926
419
   }
3927
3928
419
   if (do_local_compose != 0)
3929
0
   {
3930
0
      int result;
3931
0
      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
3932
3933
0
      display->local_row = row;
3934
0
      result = png_safe_execute(image, png_image_read_composite, display);
3935
0
      display->local_row = NULL;
3936
0
      png_free(png_ptr, row);
3937
3938
0
      return result;
3939
0
   }
3940
3941
419
   else if (do_local_background == 2)
3942
0
   {
3943
0
      int result;
3944
0
      png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
3945
3946
0
      display->local_row = row;
3947
0
      result = png_safe_execute(image, png_image_read_background, display);
3948
0
      display->local_row = NULL;
3949
0
      png_free(png_ptr, row);
3950
3951
0
      return result;
3952
0
   }
3953
3954
419
   else
3955
419
   {
3956
419
      png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
3957
3958
1.37k
      while (--passes >= 0)
3959
959
      {
3960
959
         png_uint_32      y = image->height;
3961
959
         png_bytep        row = png_voidcast(png_bytep, display->first_row);
3962
3963
53.7k
         for (; y > 0; --y)
3964
52.7k
         {
3965
52.7k
            png_read_row(png_ptr, row, NULL);
3966
52.7k
            row += row_bytes;
3967
52.7k
         }
3968
959
      }
3969
3970
419
      return 1;
3971
419
   }
3972
419
}
3973
3974
int PNGAPI
3975
png_image_finish_read(png_imagep image, png_const_colorp background,
3976
    void *buffer, png_int_32 row_stride, void *colormap)
3977
419
{
3978
419
   if (image != NULL && image->version == PNG_IMAGE_VERSION)
3979
419
   {
3980
      /* Check for row_stride overflow.  This check is not performed on the
3981
       * original PNG format because it may not occur in the output PNG format
3982
       * and libpng deals with the issues of reading the original.
3983
       */
3984
419
      unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
3985
3986
      /* The following checks just the 'row_stride' calculation to ensure it
3987
       * fits in a signed 32-bit value.  Because channels/components can be
3988
       * either 1 or 2 bytes in size the length of a row can still overflow 32
3989
       * bits; this is just to verify that the 'row_stride' argument can be
3990
       * represented.
3991
       */
3992
419
      if (image->width <= 0x7fffffffU/channels) /* no overflow */
3993
419
      {
3994
419
         png_uint_32 check;
3995
419
         png_uint_32 png_row_stride = image->width * channels;
3996
3997
419
         if (row_stride == 0)
3998
419
            row_stride = (png_int_32)/*SAFE*/png_row_stride;
3999
4000
419
         if (row_stride < 0)
4001
0
            check = (png_uint_32)(-row_stride);
4002
4003
419
         else
4004
419
            check = (png_uint_32)row_stride;
4005
4006
         /* This verifies 'check', the absolute value of the actual stride
4007
          * passed in and detects overflow in the application calculation (i.e.
4008
          * if the app did actually pass in a non-zero 'row_stride'.
4009
          */
4010
419
         if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)
4011
419
         {
4012
            /* Now check for overflow of the image buffer calculation; this
4013
             * limits the whole image size to 32 bits for API compatibility with
4014
             * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
4015
             *
4016
             * The PNG_IMAGE_BUFFER_SIZE macro is:
4017
             *
4018
             *    (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride))
4019
             *
4020
             * And the component size is always 1 or 2, so make sure that the
4021
             * number of *bytes* that the application is saying are available
4022
             * does actually fit into a 32-bit number.
4023
             *
4024
             * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE
4025
             * will be changed to use png_alloc_size_t; bigger images can be
4026
             * accommodated on 64-bit systems.
4027
             */
4028
419
            if (image->height <=
4029
419
                0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check)
4030
419
            {
4031
419
               if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
4032
419
                  (image->colormap_entries > 0 && colormap != NULL))
4033
419
               {
4034
419
                  int result;
4035
419
                  png_image_read_control display;
4036
4037
419
                  memset(&display, 0, (sizeof display));
4038
419
                  display.image = image;
4039
419
                  display.buffer = buffer;
4040
419
                  display.row_stride = row_stride;
4041
419
                  display.colormap = colormap;
4042
419
                  display.background = background;
4043
419
                  display.local_row = NULL;
4044
4045
                  /* Choose the correct 'end' routine; for the color-map case
4046
                   * all the setup has already been done.
4047
                   */
4048
419
                  if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
4049
0
                     result =
4050
0
                         png_safe_execute(image,
4051
0
                             png_image_read_colormap, &display) &&
4052
0
                             png_safe_execute(image,
4053
0
                             png_image_read_colormapped, &display);
4054
4055
419
                  else
4056
419
                     result =
4057
419
                        png_safe_execute(image,
4058
419
                            png_image_read_direct, &display);
4059
4060
419
                  png_image_free(image);
4061
419
                  return result;
4062
419
               }
4063
4064
0
               else
4065
0
                  return png_image_error(image,
4066
0
                      "png_image_finish_read[color-map]: no color-map");
4067
419
            }
4068
4069
0
            else
4070
0
               return png_image_error(image,
4071
0
                   "png_image_finish_read: image too large");
4072
419
         }
4073
4074
0
         else
4075
0
            return png_image_error(image,
4076
0
                "png_image_finish_read: invalid argument");
4077
419
      }
4078
4079
0
      else
4080
0
         return png_image_error(image,
4081
0
             "png_image_finish_read: row_stride too large");
4082
419
   }
4083
4084
0
   else if (image != NULL)
4085
0
      return png_image_error(image,
4086
0
          "png_image_finish_read: damaged PNG_IMAGE_VERSION");
4087
4088
0
   return 0;
4089
419
}
4090
4091
#endif /* SIMPLIFIED_READ */
4092
#endif /* READ */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngrio.c.html b/part1/report/w_corpus/src/libpng/pngrio.c.html new file mode 100644 index 0000000..31c67aa --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngrio.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngrio.c
Line
Count
Source (jump to first uncovered line)
1
/* pngrio.c - functions for data input
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 * This file provides a location for all input.  Users who need
13
 * special handling are expected to write a function that has the same
14
 * arguments as this and performs a similar function, but that possibly
15
 * has a different input method.  Note that you shouldn't change this
16
 * function, but rather write a replacement function and then make
17
 * libpng use it at run time with png_set_read_fn(...).
18
 */
19
20
#include "pngpriv.h"
21
22
#ifdef PNG_READ_SUPPORTED
23
24
/* Read the data from whatever input you are using.  The default routine
25
 * reads from a file pointer.  Note that this routine sometimes gets called
26
 * with very small lengths, so you should implement some kind of simple
27
 * buffering if you are using unbuffered reads.  This should never be asked
28
 * to read more than 64K on a 16-bit machine.
29
 */
30
void /* PRIVATE */
31
png_read_data(png_structrp png_ptr, png_bytep data, size_t length)
32
112k
{
33
112k
   png_debug1(4, "reading %d bytes", (int)length);
34
35
112k
   if (png_ptr->read_data_fn != NULL)
36
112k
      (*(png_ptr->read_data_fn))(png_ptr, data, length);
37
38
0
   else
39
0
      png_error(png_ptr, "Call to NULL read function");
40
112k
}
41
42
#ifdef PNG_STDIO_SUPPORTED
43
/* This is the function that does the actual reading of data.  If you are
44
 * not reading from a standard C stream, you should create a replacement
45
 * read_data function and use it at run time with png_set_read_fn(), rather
46
 * than changing the library.
47
 */
48
void PNGCBAPI
49
png_default_read_data(png_structp png_ptr, png_bytep data, size_t length)
50
{
51
   size_t check;
52
53
   if (png_ptr == NULL)
54
      return;
55
56
   /* fread() returns 0 on error, so it is OK to store this in a size_t
57
    * instead of an int, which is what fread() actually returns.
58
    */
59
   check = fread(data, 1, length, png_voidcast(FILE *, png_ptr->io_ptr));
60
61
   if (check != length)
62
      png_error(png_ptr, "Read Error");
63
}
64
#endif
65
66
/* This function allows the application to supply a new input function
67
 * for libpng if standard C streams aren't being used.
68
 *
69
 * This function takes as its arguments:
70
 *
71
 * png_ptr      - pointer to a png input data structure
72
 *
73
 * io_ptr       - pointer to user supplied structure containing info about
74
 *                the input functions.  May be NULL.
75
 *
76
 * read_data_fn - pointer to a new input function that takes as its
77
 *                arguments a pointer to a png_struct, a pointer to
78
 *                a location where input data can be stored, and a 32-bit
79
 *                unsigned int that is the number of bytes to be read.
80
 *                To exit and output any fatal error messages the new write
81
 *                function should call png_error(png_ptr, "Error msg").
82
 *                May be NULL, in which case libpng's default function will
83
 *                be used.
84
 */
85
void PNGAPI
86
png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
87
    png_rw_ptr read_data_fn)
88
4.02k
{
89
4.02k
   if (png_ptr == NULL)
90
0
      return;
91
92
4.02k
   png_ptr->io_ptr = io_ptr;
93
94
#ifdef PNG_STDIO_SUPPORTED
95
   if (read_data_fn != NULL)
96
      png_ptr->read_data_fn = read_data_fn;
97
98
   else
99
      png_ptr->read_data_fn = png_default_read_data;
100
#else
101
4.02k
   png_ptr->read_data_fn = read_data_fn;
102
4.02k
#endif
103
104
#ifdef PNG_WRITE_SUPPORTED
105
   /* It is an error to write to a read device */
106
   if (png_ptr->write_data_fn != NULL)
107
   {
108
      png_ptr->write_data_fn = NULL;
109
      png_warning(png_ptr,
110
          "Can't set both read_data_fn and write_data_fn in the"
111
          " same structure");
112
   }
113
#endif
114
115
#ifdef PNG_WRITE_FLUSH_SUPPORTED
116
   png_ptr->output_flush_fn = NULL;
117
#endif
118
4.02k
}
119
#endif /* READ */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngrtran.c.html b/part1/report/w_corpus/src/libpng/pngrtran.c.html new file mode 100644 index 0000000..9d296d6 --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngrtran.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

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

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngrutil.c
Line
Count
Source (jump to first uncovered line)
1
/* pngrutil.c - utilities to read a PNG file
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 * This file contains routines that are only called from within
13
 * libpng itself during the course of reading an image.
14
 */
15
16
#include "pngpriv.h"
17
18
#ifdef PNG_READ_SUPPORTED
19
20
/* The minimum 'zlib' stream is assumed to be just the 2 byte header, 5 bytes
21
 * minimum 'deflate' stream, and the 4 byte checksum.
22
 */
23
551
#define LZ77Min  (2U+5U+4U)
24
25
#ifdef PNG_READ_INTERLACING_SUPPORTED
26
/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */
27
28
/* Start of interlace block */
29
static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
30
/* Offset to next interlace block */
31
static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
32
/* Start of interlace block in the y direction */
33
static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
34
/* Offset to next interlace block in the y direction */
35
static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
36
37
/* TODO: Move these arrays to a common utility module to avoid duplication. */
38
#endif
39
40
png_uint_32 PNGAPI
41
png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
42
42.0k
{
43
42.0k
   png_uint_32 uval = png_get_uint_32(buf);
44
45
42.0k
   if (uval > PNG_UINT_31_MAX)
46
41
      png_error(png_ptr, "PNG unsigned integer out of range");
47
48
42.0k
   return uval;
49
42.0k
}
50
51
#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
52
/* NOTE: the read macros will obscure these definitions, so that if
53
 * PNG_USE_READ_MACROS is set the library will not use them internally,
54
 * but the APIs will still be available externally.
55
 *
56
 * The parentheses around "PNGAPI function_name" in the following three
57
 * functions are necessary because they allow the macros to co-exist with
58
 * these (unused but exported) functions.
59
 */
60
61
/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
62
png_uint_32 (PNGAPI
63
png_get_uint_32)(png_const_bytep buf)
64
0
{
65
0
   png_uint_32 uval =
66
0
       ((png_uint_32)(*(buf    )) << 24) +
67
0
       ((png_uint_32)(*(buf + 1)) << 16) +
68
0
       ((png_uint_32)(*(buf + 2)) <<  8) +
69
0
       ((png_uint_32)(*(buf + 3))      ) ;
70
71
0
   return uval;
72
0
}
73
74
/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
75
 * data is stored in the PNG file in two's complement format and there
76
 * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
77
 * the following code does a two's complement to native conversion.
78
 */
79
png_int_32 (PNGAPI
80
png_get_int_32)(png_const_bytep buf)
81
0
{
82
0
   png_uint_32 uval = png_get_uint_32(buf);
83
0
   if ((uval & 0x80000000) == 0) /* non-negative */
84
0
      return (png_int_32)uval;
85
86
0
   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
87
0
   if ((uval & 0x80000000) == 0) /* no overflow */
88
0
      return -(png_int_32)uval;
89
   /* The following has to be safe; this function only gets called on PNG data
90
    * and if we get here that data is invalid.  0 is the most safe value and
91
    * if not then an attacker would surely just generate a PNG with 0 instead.
92
    */
93
0
   return 0;
94
0
}
95
96
/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
97
png_uint_16 (PNGAPI
98
png_get_uint_16)(png_const_bytep buf)
99
0
{
100
   /* ANSI-C requires an int value to accommodate at least 16 bits so this
101
    * works and allows the compiler not to worry about possible narrowing
102
    * on 32-bit systems.  (Pre-ANSI systems did not make integers smaller
103
    * than 16 bits either.)
104
    */
105
0
   unsigned int val =
106
0
       ((unsigned int)(*buf) << 8) +
107
0
       ((unsigned int)(*(buf + 1)));
108
109
0
   return (png_uint_16)val;
110
0
}
111
112
#endif /* READ_INT_FUNCTIONS */
113
114
/* Read and check the PNG file signature */
115
void /* PRIVATE */
116
png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
117
2.22k
{
118
2.22k
   size_t num_checked, num_to_check;
119
120
   /* Exit if the user application does not expect a signature. */
121
2.22k
   if (png_ptr->sig_bytes >= 8)
122
1.80k
      return;
123
124
425
   num_checked = png_ptr->sig_bytes;
125
425
   num_to_check = 8 - num_checked;
126
127
425
#ifdef PNG_IO_STATE_SUPPORTED
128
425
   png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
129
425
#endif
130
131
   /* The signature must be serialized in a single I/O call. */
132
425
   png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
133
425
   png_ptr->sig_bytes = 8;
134
135
425
   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
136
0
   {
137
0
      if (num_checked < 4 &&
138
0
          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0)
139
0
         png_error(png_ptr, "Not a PNG file");
140
0
      else
141
0
         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
142
0
   }
143
425
   if (num_checked < 3)
144
425
      png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
145
425
}
146
147
/* This function is called to verify that a chunk name is valid.
148
 * Do this using the bit-whacking approach from contrib/tools/pngfix.c
149
 *
150
 * Copied from libpng 1.7.
151
 */
152
static int
153
check_chunk_name(png_uint_32 name)
154
37.5k
{
155
37.5k
   png_uint_32 t;
156
157
   /* Remove bit 5 from all but the reserved byte; this means
158
    * every 8-bit unit must be in the range 65-90 to be valid.
159
    * So bit 5 must be zero, bit 6 must be set and bit 7 zero.
160
    */
161
37.5k
   name &= ~PNG_U32(32,32,0,32);
162
37.5k
   t = (name & ~0x1f1f1f1fU) ^ 0x40404040U;
163
164
   /* Subtract 65 for each 8-bit quantity, this must not
165
    * overflow and each byte must then be in the range 0-25.
166
    */
167
37.5k
   name -= PNG_U32(65,65,65,65);
168
37.5k
   t |= name;
169
170
   /* Subtract 26, handling the overflow which should set the
171
    * top three bits of each byte.
172
    */
173
37.5k
   name -= PNG_U32(25,25,25,26);
174
37.5k
   t |= ~name;
175
176
37.5k
   return (t & 0xe0e0e0e0U) == 0U;
177
37.5k
}
178
179
/* Read the chunk header (length + type name).
180
 * Put the type name into png_ptr->chunk_name, and return the length.
181
 */
182
png_uint_32 /* PRIVATE */
183
png_read_chunk_header(png_structrp png_ptr)
184
38.1k
{
185
38.1k
   png_byte buf[8];
186
38.1k
   png_uint_32 chunk_name, length;
187
188
38.1k
#ifdef PNG_IO_STATE_SUPPORTED
189
38.1k
   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
190
38.1k
#endif
191
192
   /* Read the length and the chunk name.  png_struct::chunk_name is immediately
193
    * updated even if they are detectably wrong.  This aids error message
194
    * handling by allowing png_chunk_error to be used.
195
    */
196
38.1k
   png_read_data(png_ptr, buf, 8);
197
38.1k
   length = png_get_uint_31(png_ptr, buf);
198
38.1k
   png_ptr->chunk_name = chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
199
200
   /* Reset the crc and run it over the chunk name. */
201
38.1k
   png_reset_crc(png_ptr);
202
38.1k
   png_calculate_crc(png_ptr, buf + 4, 4);
203
204
38.1k
   png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu",
205
38.1k
       (unsigned long)png_ptr->chunk_name, (unsigned long)length);
206
207
   /* Sanity check the length (first by <= 0x80) and the chunk name.  An error
208
    * here indicates a broken stream and libpng has no recovery from this.
209
    */
210
38.1k
   if (buf[0] >= 0x80U)
211
0
      png_chunk_error(png_ptr, "bad header (invalid length)");
212
213
   /* Check to see if chunk name is valid. */
214
38.1k
   if (!check_chunk_name(chunk_name))
215
155
      png_chunk_error(png_ptr, "bad header (invalid type)");
216
217
37.9k
#ifdef PNG_IO_STATE_SUPPORTED
218
37.9k
   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
219
37.9k
#endif
220
221
37.9k
   return length;
222
38.1k
}
223
224
/* Read data, and (optionally) run it through the CRC. */
225
void /* PRIVATE */
226
png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)
227
37.5k
{
228
37.5k
   if (png_ptr == NULL)
229
0
      return;
230
231
37.5k
   png_read_data(png_ptr, buf, length);
232
37.5k
   png_calculate_crc(png_ptr, buf, length);
233
37.5k
}
234
235
/* Compare the CRC stored in the PNG file with that calculated by libpng from
236
 * the data it has read thus far.
237
 */
238
static int
239
png_crc_error(png_structrp png_ptr, int handle_as_ancillary)
240
36.8k
{
241
36.8k
   png_byte crc_bytes[4];
242
36.8k
   png_uint_32 crc;
243
36.8k
   int need_crc = 1;
244
245
   /* There are four flags two for ancillary and two for critical chunks.  The
246
    * default setting of these flags is all zero.
247
    *
248
    * PNG_FLAG_CRC_ANCILLARY_USE
249
    * PNG_FLAG_CRC_ANCILLARY_NOWARN
250
    *  USE+NOWARN: no CRC calculation (implemented here), else;
251
    *  NOWARN:     png_chunk_error on error (implemented in png_crc_finish)
252
    *  else:       png_chunk_warning on error (implemented in png_crc_finish)
253
    *              This is the default.
254
    *
255
    *    I.e. NOWARN without USE produces png_chunk_error.  The default setting
256
    *    where neither are set does the same thing.
257
    *
258
    * PNG_FLAG_CRC_CRITICAL_USE
259
    * PNG_FLAG_CRC_CRITICAL_IGNORE
260
    *  IGNORE: no CRC calculation (implemented here), else;
261
    *  USE:    png_chunk_warning on error (implemented in png_crc_finish)
262
    *  else:   png_chunk_error on error (implemented in png_crc_finish)
263
    *          This is the default.
264
    *
265
    * This arose because of original mis-implementation and has persisted for
266
    * compatibility reasons.
267
    *
268
    * TODO: the flag names are internal so maybe this can be changed to
269
    * something comprehensible.
270
    */
271
36.8k
   if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
272
31.8k
   {
273
31.8k
      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
274
31.8k
          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
275
25.6k
         need_crc = 0;
276
31.8k
   }
277
278
5.01k
   else /* critical */
279
5.01k
   {
280
5.01k
      if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
281
4.06k
         need_crc = 0;
282
5.01k
   }
283
284
36.8k
#ifdef PNG_IO_STATE_SUPPORTED
285
36.8k
   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
286
36.8k
#endif
287
288
   /* The chunk CRC must be serialized in a single I/O call. */
289
36.8k
   png_read_data(png_ptr, crc_bytes, 4);
290
291
36.8k
   if (need_crc != 0)
292
7.10k
   {
293
7.10k
      crc = png_get_uint_32(crc_bytes);
294
7.10k
      return crc != png_ptr->crc;
295
7.10k
   }
296
297
29.7k
   else
298
29.7k
      return 0;
299
36.8k
}
300
301
/* Optionally skip data and then check the CRC.  Depending on whether we
302
 * are reading an ancillary or critical chunk, and how the program has set
303
 * things up, we may calculate the CRC on the data and print a message.
304
 * Returns '1' if there was a CRC error, '0' otherwise.
305
 *
306
 * There is one public version which is used in most places and another which
307
 * takes the value for the 'critical' flag to check.  This allows PLTE and IEND
308
 * handling code to ignore the CRC error and removes some confusing code
309
 * duplication.
310
 */
311
static int
312
png_crc_finish_critical(png_structrp png_ptr, png_uint_32 skip,
313
      int handle_as_ancillary)
314
36.9k
{
315
   /* The size of the local buffer for inflate is a good guess as to a
316
    * reasonable size to use for buffering reads from the application.
317
    */
318
52.0k
   while (skip > 0)
319
15.1k
   {
320
15.1k
      png_uint_32 len;
321
15.1k
      png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
322
323
15.1k
      len = (sizeof tmpbuf);
324
15.1k
      if (len > skip)
325
15.0k
         len = skip;
326
15.1k
      skip -= len;
327
328
15.1k
      png_crc_read(png_ptr, tmpbuf, len);
329
15.1k
   }
330
331
   /* If 'handle_as_ancillary' has been requested and this is a critical chunk
332
    * but PNG_FLAG_CRC_CRITICAL_IGNORE was set then png_read_crc did not, in
333
    * fact, calculate the CRC so the ANCILLARY settings should not be used
334
    * instead.
335
    */
336
36.9k
   if (handle_as_ancillary &&
337
36.9k
       (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
338
1.16k
      handle_as_ancillary = 0;
339
340
   /* TODO: this might be more comprehensible if png_crc_error was inlined here.
341
    */
342
36.9k
   if (png_crc_error(png_ptr, handle_as_ancillary) != 0)
343
3.71k
   {
344
      /* See above for the explanation of how the flags work. */
345
3.71k
      if (handle_as_ancillary || PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ?
346
3.59k
          (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 :
347
3.71k
          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0)
348
3.59k
         png_chunk_warning(png_ptr, "CRC error");
349
350
111
      else
351
111
         png_chunk_error(png_ptr, "CRC error");
352
353
3.59k
      return 1;
354
3.71k
   }
355
356
33.2k
   return 0;
357
36.9k
}
358
359
int /* PRIVATE */
360
png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
361
35.1k
{
362
35.1k
   return png_crc_finish_critical(png_ptr, skip, 0/*critical handling*/);
363
35.1k
}
364
365
#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
366
    defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\
367
    defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\
368
    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_eXIf_SUPPORTED) ||\
369
    defined(PNG_SEQUENTIAL_READ_SUPPORTED)
370
/* Manage the read buffer; this simply reallocates the buffer if it is not small
371
 * enough (or if it is not allocated).  The routine returns a pointer to the
372
 * buffer; if an error occurs and 'warn' is set the routine returns NULL, else
373
 * it will call png_error on failure.
374
 */
375
static png_bytep
376
png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size)
377
12.6k
{
378
12.6k
   png_bytep buffer = png_ptr->read_buffer;
379
380
12.6k
   if (new_size > png_chunk_max(png_ptr)) return NULL;
381
382
12.5k
   if (buffer != NULL && new_size > png_ptr->read_buffer_size)
383
921
   {
384
921
      png_ptr->read_buffer = NULL;
385
921
      png_ptr->read_buffer_size = 0;
386
921
      png_free(png_ptr, buffer);
387
921
      buffer = NULL;
388
921
   }
389
390
12.5k
   if (buffer == NULL)
391
3.51k
   {
392
3.51k
      buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size));
393
394
3.51k
      if (buffer != NULL)
395
3.51k
      {
396
3.51k
#        ifndef PNG_NO_MEMZERO /* for detecting UIM bugs **only** */
397
3.51k
            memset(buffer, 0, new_size); /* just in case */
398
3.51k
#        endif
399
3.51k
         png_ptr->read_buffer = buffer;
400
3.51k
         png_ptr->read_buffer_size = new_size;
401
3.51k
      }
402
3.51k
   }
403
404
12.5k
   return buffer;
405
12.6k
}
406
#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|eXIf|SEQUENTIAL_READ */
407
408
/* png_inflate_claim: claim the zstream for some nefarious purpose that involves
409
 * decompression.  Returns Z_OK on success, else a zlib error code.  It checks
410
 * the owner but, in final release builds, just issues a warning if some other
411
 * chunk apparently owns the stream.  Prior to release it does a png_error.
412
 */
413
static int
414
png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
415
3.11k
{
416
3.11k
   if (png_ptr->zowner != 0)
417
0
   {
418
0
      char msg[64];
419
420
0
      PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner);
421
      /* So the message that results is "<chunk> using zstream"; this is an
422
       * internal error, but is very useful for debugging.  i18n requirements
423
       * are minimal.
424
       */
425
0
      (void)png_safecat(msg, (sizeof msg), 4, " using zstream");
426
0
#if PNG_RELEASE_BUILD
427
0
      png_chunk_warning(png_ptr, msg);
428
0
      png_ptr->zowner = 0;
429
#else
430
      png_chunk_error(png_ptr, msg);
431
#endif
432
0
   }
433
434
   /* Implementation note: unlike 'png_deflate_claim' this internal function
435
    * does not take the size of the data as an argument.  Some efficiency could
436
    * be gained by using this when it is known *if* the zlib stream itself does
437
    * not record the number; however, this is an illusion: the original writer
438
    * of the PNG may have selected a lower window size, and we really must
439
    * follow that because, for systems with with limited capabilities, we
440
    * would otherwise reject the application's attempts to use a smaller window
441
    * size (zlib doesn't have an interface to say "this or lower"!).
442
    *
443
    * inflateReset2 was added to zlib 1.2.4; before this the window could not be
444
    * reset, therefore it is necessary to always allocate the maximum window
445
    * size with earlier zlibs just in case later compressed chunks need it.
446
    */
447
3.11k
   {
448
3.11k
      int ret; /* zlib return code */
449
3.11k
#if ZLIB_VERNUM >= 0x1240
450
3.11k
      int window_bits = 0;
451
452
3.11k
# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)
453
3.11k
      if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
454
3.11k
          PNG_OPTION_ON)
455
0
      {
456
0
         window_bits = 15;
457
0
         png_ptr->zstream_start = 0; /* fixed window size */
458
0
      }
459
460
3.11k
      else
461
3.11k
      {
462
3.11k
         png_ptr->zstream_start = 1;
463
3.11k
      }
464
3.11k
# endif
465
466
3.11k
#endif /* ZLIB_VERNUM >= 0x1240 */
467
468
      /* Set this for safety, just in case the previous owner left pointers to
469
       * memory allocations.
470
       */
471
3.11k
      png_ptr->zstream.next_in = NULL;
472
3.11k
      png_ptr->zstream.avail_in = 0;
473
3.11k
      png_ptr->zstream.next_out = NULL;
474
3.11k
      png_ptr->zstream.avail_out = 0;
475
476
3.11k
      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
477
1.60k
      {
478
1.60k
#if ZLIB_VERNUM >= 0x1240
479
1.60k
         ret = inflateReset2(&png_ptr->zstream, window_bits);
480
#else
481
         ret = inflateReset(&png_ptr->zstream);
482
#endif
483
1.60k
      }
484
485
1.50k
      else
486
1.50k
      {
487
1.50k
#if ZLIB_VERNUM >= 0x1240
488
1.50k
         ret = inflateInit2(&png_ptr->zstream, window_bits);
489
#else
490
         ret = inflateInit(&png_ptr->zstream);
491
#endif
492
493
1.50k
         if (ret == Z_OK)
494
1.50k
            png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
495
1.50k
      }
496
497
#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
498
      if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
499
         /* Turn off validation of the ADLER32 checksum in IDAT chunks */
500
         ret = inflateValidate(&png_ptr->zstream, 0);
501
#endif
502
503
3.11k
      if (ret == Z_OK)
504
3.11k
         png_ptr->zowner = owner;
505
506
0
      else
507
0
         png_zstream_error(png_ptr, ret);
508
509
3.11k
      return ret;
510
3.11k
   }
511
512
#ifdef window_bits
513
# undef window_bits
514
#endif
515
3.11k
}
516
517
#if ZLIB_VERNUM >= 0x1240
518
/* Handle the start of the inflate stream if we called inflateInit2(strm,0);
519
 * in this case some zlib versions skip validation of the CINFO field and, in
520
 * certain circumstances, libpng may end up displaying an invalid image, in
521
 * contrast to implementations that call zlib in the normal way (e.g. libpng
522
 * 1.5).
523
 */
524
int /* PRIVATE */
525
png_zlib_inflate(png_structrp png_ptr, int flush)
526
137k
{
527
137k
   if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0)
528
3.09k
   {
529
3.09k
      if ((*png_ptr->zstream.next_in >> 4) > 7)
530
24
      {
531
24
         png_ptr->zstream.msg = "invalid window size (libpng)";
532
24
         return Z_DATA_ERROR;
533
24
      }
534
535
3.07k
      png_ptr->zstream_start = 0;
536
3.07k
   }
537
538
137k
   return inflate(&png_ptr->zstream, flush);
539
137k
}
540
#endif /* Zlib >= 1.2.4 */
541
542
#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
543
#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED)
544
/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
545
 * allow the caller to do multiple calls if required.  If the 'finish' flag is
546
 * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
547
 * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and
548
 * Z_OK or Z_STREAM_END will be returned on success.
549
 *
550
 * The input and output sizes are updated to the actual amounts of data consumed
551
 * or written, not the amount available (as in a z_stream).  The data pointers
552
 * are not changed, so the next input is (data+input_size) and the next
553
 * available output is (output+output_size).
554
 */
555
static int
556
png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
557
    /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr,
558
    /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr)
559
1.76k
{
560
1.76k
   if (png_ptr->zowner == owner) /* Else not claimed */
561
1.76k
   {
562
1.76k
      int ret;
563
1.76k
      png_alloc_size_t avail_out = *output_size_ptr;
564
1.76k
      png_uint_32 avail_in = *input_size_ptr;
565
566
      /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it
567
       * can't even necessarily handle 65536 bytes) because the type uInt is
568
       * "16 bits or more".  Consequently it is necessary to chunk the input to
569
       * zlib.  This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the
570
       * maximum value that can be stored in a uInt.)  It is possible to set
571
       * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have
572
       * a performance advantage, because it reduces the amount of data accessed
573
       * at each step and that may give the OS more time to page it in.
574
       */
575
1.76k
      png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
576
      /* avail_in and avail_out are set below from 'size' */
577
1.76k
      png_ptr->zstream.avail_in = 0;
578
1.76k
      png_ptr->zstream.avail_out = 0;
579
580
      /* Read directly into the output if it is available (this is set to
581
       * a local buffer below if output is NULL).
582
       */
583
1.76k
      if (output != NULL)
584
543
         png_ptr->zstream.next_out = output;
585
586
1.76k
      do
587
2.03k
      {
588
2.03k
         uInt avail;
589
2.03k
         Byte local_buffer[PNG_INFLATE_BUF_SIZE];
590
591
         /* zlib INPUT BUFFER */
592
         /* The setting of 'avail_in' used to be outside the loop; by setting it
593
          * inside it is possible to chunk the input to zlib and simply rely on
594
          * zlib to advance the 'next_in' pointer.  This allows arbitrary
595
          * amounts of data to be passed through zlib at the unavoidable cost of
596
          * requiring a window save (memcpy of up to 32768 output bytes)
597
          * every ZLIB_IO_MAX input bytes.
598
          */
599
2.03k
         avail_in += png_ptr->zstream.avail_in; /* not consumed last time */
600
601
2.03k
         avail = ZLIB_IO_MAX;
602
603
2.03k
         if (avail_in < avail)
604
2.03k
            avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */
605
606
2.03k
         avail_in -= avail;
607
2.03k
         png_ptr->zstream.avail_in = avail;
608
609
         /* zlib OUTPUT BUFFER */
610
2.03k
         avail_out += png_ptr->zstream.avail_out; /* not written last time */
611
612
2.03k
         avail = ZLIB_IO_MAX; /* maximum zlib can process */
613
614
2.03k
         if (output == NULL)
615
1.48k
         {
616
            /* Reset the output buffer each time round if output is NULL and
617
             * make available the full buffer, up to 'remaining_space'
618
             */
619
1.48k
            png_ptr->zstream.next_out = local_buffer;
620
1.48k
            if ((sizeof local_buffer) < avail)
621
1.48k
               avail = (sizeof local_buffer);
622
1.48k
         }
623
624
2.03k
         if (avail_out < avail)
625
543
            avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */
626
627
2.03k
         png_ptr->zstream.avail_out = avail;
628
2.03k
         avail_out -= avail;
629
630
         /* zlib inflate call */
631
         /* In fact 'avail_out' may be 0 at this point, that happens at the end
632
          * of the read when the final LZ end code was not passed at the end of
633
          * the previous chunk of input data.  Tell zlib if we have reached the
634
          * end of the output buffer.
635
          */
636
2.03k
         ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH :
637
2.03k
             (finish ? Z_FINISH : Z_SYNC_FLUSH));
638
2.03k
      } while (ret == Z_OK);
639
640
      /* For safety kill the local buffer pointer now */
641
1.76k
      if (output == NULL)
642
1.21k
         png_ptr->zstream.next_out = NULL;
643
644
      /* Claw back the 'size' and 'remaining_space' byte counts. */
645
1.76k
      avail_in += png_ptr->zstream.avail_in;
646
1.76k
      avail_out += png_ptr->zstream.avail_out;
647
648
      /* Update the input and output sizes; the updated values are the amount
649
       * consumed or written, effectively the inverse of what zlib uses.
650
       */
651
1.76k
      if (avail_out > 0)
652
1.21k
         *output_size_ptr -= avail_out;
653
654
1.76k
      if (avail_in > 0)
655
288
         *input_size_ptr -= avail_in;
656
657
      /* Ensure png_ptr->zstream.msg is set (even in the success case!) */
658
1.76k
      png_zstream_error(png_ptr, ret);
659
1.76k
      return ret;
660
1.76k
   }
661
662
0
   else
663
0
   {
664
      /* This is a bad internal error.  The recovery assigns to the zstream msg
665
       * pointer, which is not owned by the caller, but this is safe; it's only
666
       * used on errors!
667
       */
668
0
      png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
669
0
      return Z_STREAM_ERROR;
670
0
   }
671
1.76k
}
672
673
/*
674
 * Decompress trailing data in a chunk.  The assumption is that read_buffer
675
 * points at an allocated area holding the contents of a chunk with a
676
 * trailing compressed part.  What we get back is an allocated area
677
 * holding the original prefix part and an uncompressed version of the
678
 * trailing part (the malloc area passed in is freed).
679
 */
680
static int
681
png_decompress_chunk(png_structrp png_ptr,
682
    png_uint_32 chunklength, png_uint_32 prefix_size,
683
    png_alloc_size_t *newlength /* must be initialized to the maximum! */,
684
    int terminate /*add a '\0' to the end of the uncompressed data*/)
685
1.21k
{
686
   /* TODO: implement different limits for different types of chunk.
687
    *
688
    * The caller supplies *newlength set to the maximum length of the
689
    * uncompressed data, but this routine allocates space for the prefix and
690
    * maybe a '\0' terminator too.  We have to assume that 'prefix_size' is
691
    * limited only by the maximum chunk size.
692
    */
693
1.21k
   png_alloc_size_t limit = png_chunk_max(png_ptr);
694
695
1.21k
   if (limit >= prefix_size + (terminate != 0))
696
1.21k
   {
697
1.21k
      int ret;
698
699
1.21k
      limit -= prefix_size + (terminate != 0);
700
701
1.21k
      if (limit < *newlength)
702
1.21k
         *newlength = limit;
703
704
      /* Now try to claim the stream. */
705
1.21k
      ret = png_inflate_claim(png_ptr, png_ptr->chunk_name);
706
707
1.21k
      if (ret == Z_OK)
708
1.21k
      {
709
1.21k
         png_uint_32 lzsize = chunklength - prefix_size;
710
711
1.21k
         ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
712
1.21k
             /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
713
             /* output: */ NULL, newlength);
714
715
1.21k
         if (ret == Z_STREAM_END)
716
543
         {
717
            /* Use 'inflateReset' here, not 'inflateReset2' because this
718
             * preserves the previously decided window size (otherwise it would
719
             * be necessary to store the previous window size.)  In practice
720
             * this doesn't matter anyway, because png_inflate will call inflate
721
             * with Z_FINISH in almost all cases, so the window will not be
722
             * maintained.
723
             */
724
543
            if (inflateReset(&png_ptr->zstream) == Z_OK)
725
543
            {
726
               /* Because of the limit checks above we know that the new,
727
                * expanded, size will fit in a size_t (let alone an
728
                * png_alloc_size_t).  Use png_malloc_base here to avoid an
729
                * extra OOM message.
730
                */
731
543
               png_alloc_size_t new_size = *newlength;
732
543
               png_alloc_size_t buffer_size = prefix_size + new_size +
733
543
                   (terminate != 0);
734
543
               png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
735
543
                   buffer_size));
736
737
543
               if (text != NULL)
738
543
               {
739
543
                  memset(text, 0, buffer_size);
740
741
543
                  ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
742
543
                      png_ptr->read_buffer + prefix_size, &lzsize,
743
543
                      text + prefix_size, newlength);
744
745
543
                  if (ret == Z_STREAM_END)
746
543
                  {
747
543
                     if (new_size == *newlength)
748
543
                     {
749
543
                        if (terminate != 0)
750
543
                           text[prefix_size + *newlength] = 0;
751
752
543
                        if (prefix_size > 0)
753
543
                           memcpy(text, png_ptr->read_buffer, prefix_size);
754
755
543
                        {
756
543
                           png_bytep old_ptr = png_ptr->read_buffer;
757
758
543
                           png_ptr->read_buffer = text;
759
543
                           png_ptr->read_buffer_size = buffer_size;
760
543
                           text = old_ptr; /* freed below */
761
543
                        }
762
543
                     }
763
764
0
                     else
765
0
                     {
766
                        /* The size changed on the second read, there can be no
767
                         * guarantee that anything is correct at this point.
768
                         * The 'msg' pointer has been set to "unexpected end of
769
                         * LZ stream", which is fine, but return an error code
770
                         * that the caller won't accept.
771
                         */
772
0
                        ret = PNG_UNEXPECTED_ZLIB_RETURN;
773
0
                     }
774
543
                  }
775
776
0
                  else if (ret == Z_OK)
777
0
                     ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */
778
779
                  /* Free the text pointer (this is the old read_buffer on
780
                   * success)
781
                   */
782
543
                  png_free(png_ptr, text);
783
784
                  /* This really is very benign, but it's still an error because
785
                   * the extra space may otherwise be used as a Trojan Horse.
786
                   */
787
543
                  if (ret == Z_STREAM_END &&
788
543
                      chunklength - prefix_size != lzsize)
789
1
                     png_chunk_benign_error(png_ptr, "extra compressed data");
790
543
               }
791
792
0
               else
793
0
               {
794
                  /* Out of memory allocating the buffer */
795
0
                  ret = Z_MEM_ERROR;
796
0
                  png_zstream_error(png_ptr, Z_MEM_ERROR);
797
0
               }
798
543
            }
799
800
0
            else
801
0
            {
802
               /* inflateReset failed, store the error message */
803
0
               png_zstream_error(png_ptr, ret);
804
0
               ret = PNG_UNEXPECTED_ZLIB_RETURN;
805
0
            }
806
543
         }
807
808
676
         else if (ret == Z_OK)
809
0
            ret = PNG_UNEXPECTED_ZLIB_RETURN;
810
811
         /* Release the claimed stream */
812
1.21k
         png_ptr->zowner = 0;
813
1.21k
      }
814
815
0
      else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */
816
0
         ret = PNG_UNEXPECTED_ZLIB_RETURN;
817
818
1.21k
      return ret;
819
1.21k
   }
820
821
0
   else
822
0
   {
823
      /* Application/configuration limits exceeded */
824
0
      png_zstream_error(png_ptr, Z_MEM_ERROR);
825
0
      return Z_MEM_ERROR;
826
0
   }
827
1.21k
}
828
#endif /* READ_zTXt || READ_iTXt */
829
#endif /* READ_COMPRESSED_TEXT */
830
831
#ifdef PNG_READ_iCCP_SUPPORTED
832
/* Perform a partial read and decompress, producing 'avail_out' bytes and
833
 * reading from the current chunk as required.
834
 */
835
static int
836
png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
837
    png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
838
    int finish)
839
508
{
840
508
   if (png_ptr->zowner == png_ptr->chunk_name)
841
508
   {
842
508
      int ret;
843
844
      /* next_in and avail_in must have been initialized by the caller. */
845
508
      png_ptr->zstream.next_out = next_out;
846
508
      png_ptr->zstream.avail_out = 0; /* set in the loop */
847
848
508
      do
849
561
      {
850
561
         if (png_ptr->zstream.avail_in == 0)
851
56
         {
852
56
            if (read_size > *chunk_bytes)
853
53
               read_size = (uInt)*chunk_bytes;
854
56
            *chunk_bytes -= read_size;
855
856
56
            if (read_size > 0)
857
34
               png_crc_read(png_ptr, read_buffer, read_size);
858
859
56
            png_ptr->zstream.next_in = read_buffer;
860
56
            png_ptr->zstream.avail_in = read_size;
861
56
         }
862
863
561
         if (png_ptr->zstream.avail_out == 0)
864
508
         {
865
508
            uInt avail = ZLIB_IO_MAX;
866
508
            if (avail > *out_size)
867
508
               avail = (uInt)*out_size;
868
508
            *out_size -= avail;
869
870
508
            png_ptr->zstream.avail_out = avail;
871
508
         }
872
873
         /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all
874
          * the available output is produced; this allows reading of truncated
875
          * streams.
876
          */
877
561
         ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ?
878
561
             Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
879
561
      }
880
561
      while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
881
882
508
      *out_size += png_ptr->zstream.avail_out;
883
508
      png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */
884
885
      /* Ensure the error message pointer is always set: */
886
508
      png_zstream_error(png_ptr, ret);
887
508
      return ret;
888
508
   }
889
890
0
   else
891
0
   {
892
0
      png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
893
0
      return Z_STREAM_ERROR;
894
0
   }
895
508
}
896
#endif /* READ_iCCP */
897
898
/* CHUNK HANDLING */
899
/* Read and check the IDHR chunk */
900
static png_handle_result_code
901
png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
902
2.20k
{
903
2.20k
   png_byte buf[13];
904
2.20k
   png_uint_32 width, height;
905
2.20k
   int bit_depth, color_type, compression_type, filter_type;
906
2.20k
   int interlace_type;
907
908
2.20k
   png_debug(1, "in png_handle_IHDR");
909
910
   /* Length and position are checked by the caller. */
911
912
2.20k
   png_ptr->mode |= PNG_HAVE_IHDR;
913
914
2.20k
   png_crc_read(png_ptr, buf, 13);
915
2.20k
   png_crc_finish(png_ptr, 0);
916
917
2.20k
   width = png_get_uint_31(png_ptr, buf);
918
2.20k
   height = png_get_uint_31(png_ptr, buf + 4);
919
2.20k
   bit_depth = buf[8];
920
2.20k
   color_type = buf[9];
921
2.20k
   compression_type = buf[10];
922
2.20k
   filter_type = buf[11];
923
2.20k
   interlace_type = buf[12];
924
925
   /* Set internal variables */
926
2.20k
   png_ptr->width = width;
927
2.20k
   png_ptr->height = height;
928
2.20k
   png_ptr->bit_depth = (png_byte)bit_depth;
929
2.20k
   png_ptr->interlaced = (png_byte)interlace_type;
930
2.20k
   png_ptr->color_type = (png_byte)color_type;
931
2.20k
#ifdef PNG_MNG_FEATURES_SUPPORTED
932
2.20k
   png_ptr->filter_type = (png_byte)filter_type;
933
2.20k
#endif
934
2.20k
   png_ptr->compression_type = (png_byte)compression_type;
935
936
   /* Find number of channels */
937
2.20k
   switch (png_ptr->color_type)
938
2.20k
   {
939
5
      default: /* invalid, png_set_IHDR calls png_error */
940
934
      case PNG_COLOR_TYPE_GRAY:
941
1.38k
      case PNG_COLOR_TYPE_PALETTE:
942
1.38k
         png_ptr->channels = 1;
943
1.38k
         break;
944
945
250
      case PNG_COLOR_TYPE_RGB:
946
250
         png_ptr->channels = 3;
947
250
         break;
948
949
85
      case PNG_COLOR_TYPE_GRAY_ALPHA:
950
85
         png_ptr->channels = 2;
951
85
         break;
952
953
483
      case PNG_COLOR_TYPE_RGB_ALPHA:
954
483
         png_ptr->channels = 4;
955
483
         break;
956
2.20k
   }
957
958
   /* Set up other useful info */
959
2.20k
   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels);
960
2.20k
   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
961
2.20k
   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
962
2.20k
   png_debug1(3, "channels = %d", png_ptr->channels);
963
2.20k
   png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
964
965
   /* Rely on png_set_IHDR to completely validate the data and call png_error if
966
    * it's wrong.
967
    */
968
2.20k
   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
969
2.20k
       color_type, interlace_type, compression_type, filter_type);
970
971
2.20k
   return handled_ok;
972
0
   PNG_UNUSED(length)
973
0
}
974
975
/* Read and check the palette */
976
/* TODO: there are several obvious errors in this code when handling
977
 * out-of-place chunks and there is much over-complexity caused by trying to
978
 * patch up the problems.
979
 */
980
static png_handle_result_code
981
png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
982
1.40k
{
983
1.40k
   png_const_charp errmsg = NULL;
984
985
1.40k
   png_debug(1, "in png_handle_PLTE");
986
987
   /* 1.6.47: consistency.  This used to be especially treated as a critical
988
    * error even in an image which is not colour mapped, there isn't a good
989
    * justification for treating some errors here one way and others another so
990
    * everything uses the same logic.
991
    */
992
1.40k
   if ((png_ptr->mode & PNG_HAVE_PLTE) != 0)
993
67
      errmsg = "duplicate";
994
995
1.33k
   else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
996
94
      errmsg = "out of place";
997
998
1.24k
   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
999
765
      errmsg = "ignored in grayscale PNG";
1000
1001
480
   else if (length > 3*PNG_MAX_PALETTE_LENGTH || (length % 3) != 0)
1002
4
      errmsg = "invalid";
1003
1004
   /* This drops PLTE in favour of tRNS or bKGD because both of those chunks
1005
    * can have an effect on the rendering of the image whereas PLTE only matters
1006
    * in the case of an 8-bit display with a decoder which controls the palette.
1007
    *
1008
    * The alternative here is to ignore the error and store the palette anyway;
1009
    * destroying the tRNS will definately cause problems.
1010
    *
1011
    * NOTE: the case of PNG_COLOR_TYPE_PALETTE need not be considered because
1012
    * the png_handle_ routines for the three 'after PLTE' chunks tRNS, bKGD and
1013
    * hIST all check for a preceding PLTE in these cases.
1014
    */
1015
476
   else if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE &&
1016
476
            (png_has_chunk(png_ptr, tRNS) || png_has_chunk(png_ptr, bKGD)))
1017
100
      errmsg = "out of place";
1018
1019
376
   else
1020
376
   {
1021
      /* If the palette has 256 or fewer entries but is too large for the bit
1022
       * depth we don't issue an error to preserve the behavior of previous
1023
       * libpng versions. We silently truncate the unused extra palette entries
1024
       * here.
1025
       */
1026
376
      const unsigned max_palette_length =
1027
376
         (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
1028
366
            1U << png_ptr->bit_depth : PNG_MAX_PALETTE_LENGTH;
1029
1030
      /* The cast is safe because 'length' is less than
1031
       * 3*PNG_MAX_PALETTE_LENGTH
1032
       */
1033
376
      const unsigned num = (length > 3U*max_palette_length) ?
1034
375
         max_palette_length : (unsigned)length / 3U;
1035
1036
376
      unsigned i, j;
1037
376
      png_byte buf[3*PNG_MAX_PALETTE_LENGTH];
1038
376
      png_color palette[PNG_MAX_PALETTE_LENGTH];
1039
1040
      /* Read the chunk into the buffer then read to the end of the chunk. */
1041
376
      png_crc_read(png_ptr, buf, num*3U);
1042
376
      png_crc_finish_critical(png_ptr, length - 3U*num,
1043
            /* Handle as ancillary if PLTE is optional: */
1044
376
            png_ptr->color_type != PNG_COLOR_TYPE_PALETTE);
1045
1046
29.1k
      for (i = 0U, j = 0U; i < num; i++)
1047
28.7k
      {
1048
28.7k
         palette[i].red = buf[j++];
1049
28.7k
         palette[i].green = buf[j++];
1050
28.7k
         palette[i].blue = buf[j++];
1051
28.7k
      }
1052
1053
      /* A valid PLTE chunk has been read */
1054
376
      png_ptr->mode |= PNG_HAVE_PLTE;
1055
1056
      /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to
1057
       * its own copy of the palette.  This has the side effect that when
1058
       * png_start_row is called (this happens after any call to
1059
       * png_read_update_info) the info_ptr palette gets changed.  This is
1060
       * extremely unexpected and confusing.
1061
       *
1062
       * REVIEW: there have been consistent bugs in the past about gamma and
1063
       * similar transforms to colour mapped images being useless because the
1064
       * modified palette cannot be accessed because of the above.
1065
       *
1066
       * CONSIDER: Fix this by not sharing the palette in this way.  But does
1067
       * this completely fix the problem?
1068
       */
1069
376
      png_set_PLTE(png_ptr, info_ptr, palette, num);
1070
376
      return handled_ok;
1071
376
   }
1072
1073
   /* Here on error: errmsg is non NULL. */
1074
1.03k
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1075
3
   {
1076
3
      png_crc_finish(png_ptr, length);
1077
3
      png_chunk_error(png_ptr, errmsg);
1078
3
   }
1079
1080
1.02k
   else /* not critical to this image */
1081
1.02k
   {
1082
1.02k
      png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/);
1083
1.02k
      png_chunk_benign_error(png_ptr, errmsg);
1084
1.02k
   }
1085
1086
   /* Because PNG_UNUSED(errmsg) does not work if all the uses are compiled out
1087
    * (this does happen).
1088
    */
1089
1.02k
   return errmsg != NULL ? handled_error : handled_error;
1090
1.03k
}
1091
1092
/* On read the IDAT chunk is always handled specially, even if marked for
1093
 * unknown handling (this is allowed), so:
1094
 */
1095
#define png_handle_IDAT NULL
1096
1097
static png_handle_result_code
1098
png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1099
426
{
1100
426
   png_debug(1, "in png_handle_IEND");
1101
1102
426
   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
1103
1104
426
   if (length != 0)
1105
1
      png_chunk_benign_error(png_ptr, "invalid");
1106
1107
426
   png_crc_finish_critical(png_ptr, length, 1/*handle as ancillary*/);
1108
1109
426
   return handled_ok;
1110
0
   PNG_UNUSED(info_ptr)
1111
0
}
1112
1113
#ifdef PNG_READ_gAMA_SUPPORTED
1114
static png_handle_result_code
1115
png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1116
901
{
1117
901
   png_uint_32 ugamma;
1118
901
   png_byte buf[4];
1119
1120
901
   png_debug(1, "in png_handle_gAMA");
1121
1122
901
   png_crc_read(png_ptr, buf, 4);
1123
1124
901
   if (png_crc_finish(png_ptr, 0) != 0)
1125
114
      return handled_error;
1126
1127
787
   ugamma = png_get_uint_32(buf);
1128
1129
787
   if (ugamma > PNG_UINT_31_MAX)
1130
12
   {
1131
12
      png_chunk_benign_error(png_ptr, "invalid");
1132
12
      return handled_error;
1133
12
   }
1134
1135
775
   png_set_gAMA_fixed(png_ptr, info_ptr, (png_fixed_point)/*SAFE*/ugamma);
1136
1137
775
#ifdef PNG_READ_GAMMA_SUPPORTED
1138
      /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA.  gAMA is
1139
       * at the end of the chain so simply check for an unset value.
1140
       */
1141
775
      if (png_ptr->chunk_gamma == 0)
1142
712
         png_ptr->chunk_gamma = (png_fixed_point)/*SAFE*/ugamma;
1143
775
#endif /*READ_GAMMA*/
1144
1145
775
   return handled_ok;
1146
0
   PNG_UNUSED(length)
1147
0
}
1148
#else
1149
#  define png_handle_gAMA NULL
1150
#endif
1151
1152
#ifdef PNG_READ_sBIT_SUPPORTED
1153
static png_handle_result_code /* PRIVATE */
1154
png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1155
1.21k
{
1156
1.21k
   unsigned int truelen, i;
1157
1.21k
   png_byte sample_depth;
1158
1.21k
   png_byte buf[4];
1159
1160
1.21k
   png_debug(1, "in png_handle_sBIT");
1161
1162
1.21k
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1163
104
   {
1164
104
      truelen = 3;
1165
104
      sample_depth = 8;
1166
104
   }
1167
1168
1.11k
   else
1169
1.11k
   {
1170
1.11k
      truelen = png_ptr->channels;
1171
1.11k
      sample_depth = png_ptr->bit_depth;
1172
1.11k
   }
1173
1174
1.21k
   if (length != truelen)
1175
297
   {
1176
297
      png_crc_finish(png_ptr, length);
1177
297
      png_chunk_benign_error(png_ptr, "bad length");
1178
297
      return handled_error;
1179
297
   }
1180
1181
918
   buf[0] = buf[1] = buf[2] = buf[3] = sample_depth;
1182
918
   png_crc_read(png_ptr, buf, truelen);
1183
1184
918
   if (png_crc_finish(png_ptr, 0) != 0)
1185
76
      return handled_error;
1186
1187
2.86k
   for (i=0; i<truelen; ++i)
1188
2.67k
   {
1189
2.67k
      if (buf[i] == 0 || buf[i] > sample_depth)
1190
655
      {
1191
655
         png_chunk_benign_error(png_ptr, "invalid");
1192
655
         return handled_error;
1193
655
      }
1194
2.67k
   }
1195
1196
187
   if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
1197
186
   {
1198
186
      png_ptr->sig_bit.red = buf[0];
1199
186
      png_ptr->sig_bit.green = buf[1];
1200
186
      png_ptr->sig_bit.blue = buf[2];
1201
186
      png_ptr->sig_bit.alpha = buf[3];
1202
186
   }
1203
1204
1
   else /* grayscale */
1205
1
   {
1206
1
      png_ptr->sig_bit.gray = buf[0];
1207
1
      png_ptr->sig_bit.red = buf[0];
1208
1
      png_ptr->sig_bit.green = buf[0];
1209
1
      png_ptr->sig_bit.blue = buf[0];
1210
1
      png_ptr->sig_bit.alpha = buf[1];
1211
1
   }
1212
1213
187
   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
1214
187
   return handled_ok;
1215
842
}
1216
#else
1217
#  define png_handle_sBIT NULL
1218
#endif
1219
1220
#ifdef PNG_READ_cHRM_SUPPORTED
1221
static png_int_32
1222
png_get_int_32_checked(png_const_bytep buf, int *error)
1223
14.2k
{
1224
14.2k
   png_uint_32 uval = png_get_uint_32(buf);
1225
14.2k
   if ((uval & 0x80000000) == 0) /* non-negative */
1226
9.91k
      return (png_int_32)uval;
1227
1228
4.35k
   uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
1229
4.35k
   if ((uval & 0x80000000) == 0) /* no overflow */
1230
3.13k
      return -(png_int_32)uval;
1231
1232
   /* This version of png_get_int_32 has a way of returning the error to the
1233
    * caller, so:
1234
    */
1235
1.22k
   *error = 1;
1236
1.22k
   return 0; /* Safe */
1237
4.35k
}
1238
1239
static png_handle_result_code /* PRIVATE */
1240
png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1241
2.16k
{
1242
2.16k
   int error = 0;
1243
2.16k
   png_xy xy;
1244
2.16k
   png_byte buf[32];
1245
1246
2.16k
   png_debug(1, "in png_handle_cHRM");
1247
1248
2.16k
   png_crc_read(png_ptr, buf, 32);
1249
1250
2.16k
   if (png_crc_finish(png_ptr, 0) != 0)
1251
382
      return handled_error;
1252
1253
1.78k
   xy.whitex = png_get_int_32_checked(buf +  0, &error);
1254
1.78k
   xy.whitey = png_get_int_32_checked(buf +  4, &error);
1255
1.78k
   xy.redx   = png_get_int_32_checked(buf +  8, &error);
1256
1.78k
   xy.redy   = png_get_int_32_checked(buf + 12, &error);
1257
1.78k
   xy.greenx = png_get_int_32_checked(buf + 16, &error);
1258
1.78k
   xy.greeny = png_get_int_32_checked(buf + 20, &error);
1259
1.78k
   xy.bluex  = png_get_int_32_checked(buf + 24, &error);
1260
1.78k
   xy.bluey  = png_get_int_32_checked(buf + 28, &error);
1261
1262
1.78k
   if (error)
1263
1.19k
   {
1264
1.19k
      png_chunk_benign_error(png_ptr, "invalid");
1265
1.19k
      return handled_error;
1266
1.19k
   }
1267
1268
   /* png_set_cHRM may complain about some of the values but this doesn't matter
1269
    * because it was a cHRM and it did have vaguely (if, perhaps, ridiculous)
1270
    * values.  Ridiculousity will be checked if the values are used later.
1271
    */
1272
589
   png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy,
1273
589
         xy.greenx, xy.greeny, xy.bluex, xy.bluey);
1274
1275
   /* We only use 'chromaticities' for RGB to gray */
1276
589
#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1277
      /* There is no need to check sRGB here, cICP is NYI and iCCP is not
1278
       * supported so just check mDCV.
1279
       */
1280
589
      if (!png_has_chunk(png_ptr, mDCV))
1281
482
      {
1282
482
         png_ptr->chromaticities = xy;
1283
482
      }
1284
589
#  endif /* READ_RGB_TO_GRAY */
1285
1286
589
   return handled_ok;
1287
0
   PNG_UNUSED(length)
1288
0
}
1289
#else
1290
#  define png_handle_cHRM NULL
1291
#endif
1292
1293
#ifdef PNG_READ_sRGB_SUPPORTED
1294
static png_handle_result_code /* PRIVATE */
1295
png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1296
291
{
1297
291
   png_byte intent;
1298
1299
291
   png_debug(1, "in png_handle_sRGB");
1300
1301
291
   png_crc_read(png_ptr, &intent, 1);
1302
1303
291
   if (png_crc_finish(png_ptr, 0) != 0)
1304
45
      return handled_error;
1305
1306
   /* This checks the range of the "rendering intent" because it is specified in
1307
    * the PNG spec itself; the "reserved" values will result in the chunk not
1308
    * being accepted, just as they do with the various "reserved" values in
1309
    * IHDR.
1310
    */
1311
246
   if (intent > 3/*PNGv3 spec*/)
1312
20
   {
1313
20
      png_chunk_benign_error(png_ptr, "invalid");
1314
20
      return handled_error;
1315
20
   }
1316
1317
226
   png_set_sRGB(png_ptr, info_ptr, intent);
1318
   /* NOTE: png_struct::chromaticities is not set here because the RGB to gray
1319
    * coefficients are known without a need for the chromaticities.
1320
    */
1321
1322
226
#ifdef PNG_READ_GAMMA_SUPPORTED
1323
      /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA.  iCCP is
1324
       * not supported by libpng so the only requirement is to check for cICP
1325
       * setting the gamma (this is NYI, but this check is safe.)
1326
       */
1327
226
      if (!png_has_chunk(png_ptr, cICP) || png_ptr->chunk_gamma == 0)
1328
219
         png_ptr->chunk_gamma = PNG_GAMMA_sRGB_INVERSE;
1329
226
#endif /*READ_GAMMA*/
1330
1331
226
   return handled_ok;
1332
0
   PNG_UNUSED(length)
1333
0
}
1334
#else
1335
#  define png_handle_sRGB NULL
1336
#endif /* READ_sRGB */
1337
1338
#ifdef PNG_READ_iCCP_SUPPORTED
1339
static png_handle_result_code /* PRIVATE */
1340
png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1341
/* Note: this does not properly handle profiles that are > 64K under DOS */
1342
551
{
1343
551
   png_const_charp errmsg = NULL; /* error message output, or no error */
1344
551
   int finished = 0; /* crc checked */
1345
1346
551
   png_debug(1, "in png_handle_iCCP");
1347
1348
   /* PNGv3: allow PNG files with both sRGB and iCCP because the PNG spec only
1349
    * ever said that there "should" be only one, not "shall" and the PNGv3
1350
    * colour chunk precedence rules give a handling for this case anyway.
1351
    */
1352
551
   {
1353
551
      uInt read_length, keyword_length;
1354
551
      char keyword[81];
1355
1356
      /* Find the keyword; the keyword plus separator and compression method
1357
       * bytes can be at most 81 characters long.
1358
       */
1359
551
      read_length = 81; /* maximum */
1360
551
      if (read_length > length)
1361
12
         read_length = (uInt)/*SAFE*/length;
1362
1363
551
      png_crc_read(png_ptr, (png_bytep)keyword, read_length);
1364
551
      length -= read_length;
1365
1366
551
      if (length < LZ77Min)
1367
12
      {
1368
12
         png_crc_finish(png_ptr, length);
1369
12
         png_chunk_benign_error(png_ptr, "too short");
1370
12
         return handled_error;
1371
12
      }
1372
1373
539
      keyword_length = 0;
1374
4.09k
      while (keyword_length < 80 && keyword_length < read_length &&
1375
4.09k
         keyword[keyword_length] != 0)
1376
3.55k
         ++keyword_length;
1377
1378
      /* TODO: make the keyword checking common */
1379
539
      if (keyword_length >= 1 && keyword_length <= 79)
1380
523
      {
1381
         /* We only understand '0' compression - deflate - so if we get a
1382
          * different value we can't safely decode the chunk.
1383
          */
1384
523
         if (keyword_length+1 < read_length &&
1385
523
            keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE)
1386
508
         {
1387
508
            read_length -= keyword_length+2;
1388
1389
508
            if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
1390
508
            {
1391
508
               Byte profile_header[132]={0};
1392
508
               Byte local_buffer[PNG_INFLATE_BUF_SIZE];
1393
508
               png_alloc_size_t size = (sizeof profile_header);
1394
1395
508
               png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
1396
508
               png_ptr->zstream.avail_in = read_length;
1397
508
               (void)png_inflate_read(png_ptr, local_buffer,
1398
508
                   (sizeof local_buffer), &length, profile_header, &size,
1399
508
                   0/*finish: don't, because the output is too small*/);
1400
1401
508
               if (size == 0)
1402
47
               {
1403
                  /* We have the ICC profile header; do the basic header checks.
1404
                   */
1405
47
                  png_uint_32 profile_length = png_get_uint_32(profile_header);
1406
1407
47
                  if (png_icc_check_length(png_ptr, keyword, profile_length) !=
1408
47
                      0)
1409
17
                  {
1410
                     /* The length is apparently ok, so we can check the 132
1411
                      * byte header.
1412
                      */
1413
17
                     if (png_icc_check_header(png_ptr, keyword, profile_length,
1414
17
                              profile_header, png_ptr->color_type) != 0)
1415
0
                     {
1416
                        /* Now read the tag table; a variable size buffer is
1417
                         * needed at this point, allocate one for the whole
1418
                         * profile.  The header check has already validated
1419
                         * that none of this stuff will overflow.
1420
                         */
1421
0
                        png_uint_32 tag_count =
1422
0
                           png_get_uint_32(profile_header + 128);
1423
0
                        png_bytep profile = png_read_buffer(png_ptr,
1424
0
                              profile_length);
1425
1426
0
                        if (profile != NULL)
1427
0
                        {
1428
0
                           memcpy(profile, profile_header,
1429
0
                               (sizeof profile_header));
1430
1431
0
                           size = 12 * tag_count;
1432
1433
0
                           (void)png_inflate_read(png_ptr, local_buffer,
1434
0
                               (sizeof local_buffer), &length,
1435
0
                               profile + (sizeof profile_header), &size, 0);
1436
1437
                           /* Still expect a buffer error because we expect
1438
                            * there to be some tag data!
1439
                            */
1440
0
                           if (size == 0)
1441
0
                           {
1442
0
                              if (png_icc_check_tag_table(png_ptr,
1443
0
                                       keyword, profile_length, profile) != 0)
1444
0
                              {
1445
                                 /* The profile has been validated for basic
1446
                                  * security issues, so read the whole thing in.
1447
                                  */
1448
0
                                 size = profile_length - (sizeof profile_header)
1449
0
                                     - 12 * tag_count;
1450
1451
0
                                 (void)png_inflate_read(png_ptr, local_buffer,
1452
0
                                     (sizeof local_buffer), &length,
1453
0
                                     profile + (sizeof profile_header) +
1454
0
                                     12 * tag_count, &size, 1/*finish*/);
1455
1456
0
                                 if (length > 0 && !(png_ptr->flags &
1457
0
                                     PNG_FLAG_BENIGN_ERRORS_WARN))
1458
0
                                    errmsg = "extra compressed data";
1459
1460
                                 /* But otherwise allow extra data: */
1461
0
                                 else if (size == 0)
1462
0
                                 {
1463
0
                                    if (length > 0)
1464
0
                                    {
1465
                                       /* This can be handled completely, so
1466
                                        * keep going.
1467
                                        */
1468
0
                                       png_chunk_warning(png_ptr,
1469
0
                                           "extra compressed data");
1470
0
                                    }
1471
1472
0
                                    png_crc_finish(png_ptr, length);
1473
0
                                    finished = 1;
1474
1475
                                    /* Steal the profile for info_ptr. */
1476
0
                                    if (info_ptr != NULL)
1477
0
                                    {
1478
0
                                       png_free_data(png_ptr, info_ptr,
1479
0
                                           PNG_FREE_ICCP, 0);
1480
1481
0
                                       info_ptr->iccp_name = png_voidcast(char*,
1482
0
                                           png_malloc_base(png_ptr,
1483
0
                                           keyword_length+1));
1484
0
                                       if (info_ptr->iccp_name != NULL)
1485
0
                                       {
1486
0
                                          memcpy(info_ptr->iccp_name, keyword,
1487
0
                                              keyword_length+1);
1488
0
                                          info_ptr->iccp_proflen =
1489
0
                                              profile_length;
1490
0
                                          info_ptr->iccp_profile = profile;
1491
0
                                          png_ptr->read_buffer = NULL; /*steal*/
1492
0
                                          info_ptr->free_me |= PNG_FREE_ICCP;
1493
0
                                          info_ptr->valid |= PNG_INFO_iCCP;
1494
0
                                       }
1495
1496
0
                                       else
1497
0
                                          errmsg = "out of memory";
1498
0
                                    }
1499
1500
                                    /* else the profile remains in the read
1501
                                     * buffer which gets reused for subsequent
1502
                                     * chunks.
1503
                                     */
1504
1505
0
                                    if (errmsg == NULL)
1506
0
                                    {
1507
0
                                       png_ptr->zowner = 0;
1508
0
                                       return handled_ok;
1509
0
                                    }
1510
0
                                 }
1511
0
                                 if (errmsg == NULL)
1512
0
                                    errmsg = png_ptr->zstream.msg;
1513
0
                              }
1514
                              /* else png_icc_check_tag_table output an error */
1515
0
                           }
1516
0
                           else /* profile truncated */
1517
0
                              errmsg = png_ptr->zstream.msg;
1518
0
                        }
1519
1520
0
                        else
1521
0
                           errmsg = "out of memory";
1522
0
                     }
1523
1524
                     /* else png_icc_check_header output an error */
1525
17
                  }
1526
1527
                  /* else png_icc_check_length output an error */
1528
47
               }
1529
1530
461
               else /* profile truncated */
1531
461
                  errmsg = png_ptr->zstream.msg;
1532
1533
               /* Release the stream */
1534
508
               png_ptr->zowner = 0;
1535
508
            }
1536
1537
0
            else /* png_inflate_claim failed */
1538
0
               errmsg = png_ptr->zstream.msg;
1539
508
         }
1540
1541
15
         else
1542
15
            errmsg = "bad compression method"; /* or missing */
1543
523
      }
1544
1545
16
      else
1546
16
         errmsg = "bad keyword";
1547
539
   }
1548
1549
   /* Failure: the reason is in 'errmsg' */
1550
539
   if (finished == 0)
1551
531
      png_crc_finish(png_ptr, length);
1552
1553
539
   if (errmsg != NULL) /* else already output */
1554
456
      png_chunk_benign_error(png_ptr, errmsg);
1555
1556
539
   return handled_error;
1557
539
}
1558
#else
1559
#  define png_handle_iCCP NULL
1560
#endif /* READ_iCCP */
1561
1562
#ifdef PNG_READ_sPLT_SUPPORTED
1563
static png_handle_result_code /* PRIVATE */
1564
png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1565
/* Note: this does not properly handle chunks that are > 64K under DOS */
1566
851
{
1567
851
   png_bytep entry_start, buffer;
1568
851
   png_sPLT_t new_palette;
1569
851
   png_sPLT_entryp pp;
1570
851
   png_uint_32 data_length;
1571
851
   int entry_size, i;
1572
851
   png_uint_32 skip = 0;
1573
851
   png_uint_32 dl;
1574
851
   size_t max_dl;
1575
1576
851
   png_debug(1, "in png_handle_sPLT");
1577
1578
851
#ifdef PNG_USER_LIMITS_SUPPORTED
1579
851
   if (png_ptr->user_chunk_cache_max != 0)
1580
851
   {
1581
851
      if (png_ptr->user_chunk_cache_max == 1)
1582
0
      {
1583
0
         png_crc_finish(png_ptr, length);
1584
0
         return handled_error;
1585
0
      }
1586
1587
851
      if (--png_ptr->user_chunk_cache_max == 1)
1588
0
      {
1589
0
         png_warning(png_ptr, "No space in chunk cache for sPLT");
1590
0
         png_crc_finish(png_ptr, length);
1591
0
         return handled_error;
1592
0
      }
1593
851
   }
1594
851
#endif
1595
1596
851
   buffer = png_read_buffer(png_ptr, length+1);
1597
851
   if (buffer == NULL)
1598
2
   {
1599
2
      png_crc_finish(png_ptr, length);
1600
2
      png_chunk_benign_error(png_ptr, "out of memory");
1601
2
      return handled_error;
1602
2
   }
1603
1604
1605
   /* WARNING: this may break if size_t is less than 32 bits; it is assumed
1606
    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
1607
    * potential breakage point if the types in pngconf.h aren't exactly right.
1608
    */
1609
849
   png_crc_read(png_ptr, buffer, length);
1610
1611
849
   if (png_crc_finish(png_ptr, skip) != 0)
1612
178
      return handled_error;
1613
1614
671
   buffer[length] = 0;
1615
1616
31.9k
   for (entry_start = buffer; *entry_start; entry_start++)
1617
31.2k
      /* Empty loop to find end of name */ ;
1618
1619
671
   ++entry_start;
1620
1621
   /* A sample depth should follow the separator, and we should be on it  */
1622
671
   if (length < 2U || entry_start > buffer + (length - 2U))
1623
2
   {
1624
2
      png_warning(png_ptr, "malformed sPLT chunk");
1625
2
      return handled_error;
1626
2
   }
1627
1628
669
   new_palette.depth = *entry_start++;
1629
669
   entry_size = (new_palette.depth == 8 ? 6 : 10);
1630
   /* This must fit in a png_uint_32 because it is derived from the original
1631
    * chunk data length.
1632
    */
1633
669
   data_length = length - (png_uint_32)(entry_start - buffer);
1634
1635
   /* Integrity-check the data length */
1636
669
   if ((data_length % (unsigned int)entry_size) != 0)
1637
260
   {
1638
260
      png_warning(png_ptr, "sPLT chunk has bad length");
1639
260
      return handled_error;
1640
260
   }
1641
1642
409
   dl = (png_uint_32)(data_length / (unsigned int)entry_size);
1643
409
   max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
1644
1645
409
   if (dl > max_dl)
1646
0
   {
1647
0
      png_warning(png_ptr, "sPLT chunk too long");
1648
0
      return handled_error;
1649
0
   }
1650
1651
409
   new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size);
1652
1653
409
   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
1654
409
       (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry)));
1655
1656
409
   if (new_palette.entries == NULL)
1657
0
   {
1658
0
      png_warning(png_ptr, "sPLT chunk requires too much memory");
1659
0
      return handled_error;
1660
0
   }
1661
1662
3.82k
   for (i = 0; i < new_palette.nentries; i++)
1663
3.41k
   {
1664
3.41k
      pp = new_palette.entries + i;
1665
1666
3.41k
      if (new_palette.depth == 8)
1667
257
      {
1668
257
         pp->red = *entry_start++;
1669
257
         pp->green = *entry_start++;
1670
257
         pp->blue = *entry_start++;
1671
257
         pp->alpha = *entry_start++;
1672
257
      }
1673
1674
3.15k
      else
1675
3.15k
      {
1676
3.15k
         pp->red   = png_get_uint_16(entry_start); entry_start += 2;
1677
3.15k
         pp->green = png_get_uint_16(entry_start); entry_start += 2;
1678
3.15k
         pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
1679
3.15k
         pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1680
3.15k
      }
1681
1682
3.41k
      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1683
3.41k
   }
1684
1685
   /* Discard all chunk data except the name and stash that */
1686
409
   new_palette.name = (png_charp)buffer;
1687
1688
409
   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1689
1690
409
   png_free(png_ptr, new_palette.entries);
1691
409
   return handled_ok;
1692
409
}
1693
#else
1694
#  define png_handle_sPLT NULL
1695
#endif /* READ_sPLT */
1696
1697
#ifdef PNG_READ_tRNS_SUPPORTED
1698
static png_handle_result_code /* PRIVATE */
1699
png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1700
911
{
1701
911
   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1702
1703
911
   png_debug(1, "in png_handle_tRNS");
1704
1705
911
   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1706
381
   {
1707
381
      png_byte buf[2];
1708
1709
381
      if (length != 2)
1710
11
      {
1711
11
         png_crc_finish(png_ptr, length);
1712
11
         png_chunk_benign_error(png_ptr, "invalid");
1713
11
         return handled_error;
1714
11
      }
1715
1716
370
      png_crc_read(png_ptr, buf, 2);
1717
370
      png_ptr->num_trans = 1;
1718
370
      png_ptr->trans_color.gray = png_get_uint_16(buf);
1719
370
   }
1720
1721
530
   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1722
170
   {
1723
170
      png_byte buf[6];
1724
1725
170
      if (length != 6)
1726
41
      {
1727
41
         png_crc_finish(png_ptr, length);
1728
41
         png_chunk_benign_error(png_ptr, "invalid");
1729
41
         return handled_error;
1730
41
      }
1731
1732
129
      png_crc_read(png_ptr, buf, length);
1733
129
      png_ptr->num_trans = 1;
1734
129
      png_ptr->trans_color.red = png_get_uint_16(buf);
1735
129
      png_ptr->trans_color.green = png_get_uint_16(buf + 2);
1736
129
      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
1737
129
   }
1738
1739
360
   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1740
215
   {
1741
215
      if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
1742
67
      {
1743
67
         png_crc_finish(png_ptr, length);
1744
67
         png_chunk_benign_error(png_ptr, "out of place");
1745
67
         return handled_error;
1746
67
      }
1747
1748
148
      if (length > (unsigned int) png_ptr->num_palette ||
1749
148
         length > (unsigned int) PNG_MAX_PALETTE_LENGTH ||
1750
148
         length == 0)
1751
11
      {
1752
11
         png_crc_finish(png_ptr, length);
1753
11
         png_chunk_benign_error(png_ptr, "invalid");
1754
11
         return handled_error;
1755
11
      }
1756
1757
137
      png_crc_read(png_ptr, readbuf, length);
1758
137
      png_ptr->num_trans = (png_uint_16)length;
1759
137
   }
1760
1761
145
   else
1762
145
   {
1763
145
      png_crc_finish(png_ptr, length);
1764
145
      png_chunk_benign_error(png_ptr, "invalid with alpha channel");
1765
145
      return handled_error;
1766
145
   }
1767
1768
636
   if (png_crc_finish(png_ptr, 0) != 0)
1769
39
   {
1770
39
      png_ptr->num_trans = 0;
1771
39
      return handled_error;
1772
39
   }
1773
1774
   /* TODO: this is a horrible side effect in the palette case because the
1775
    * png_struct ends up with a pointer to the tRNS buffer owned by the
1776
    * png_info.  Fix this.
1777
    */
1778
597
   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1779
597
       &(png_ptr->trans_color));
1780
597
   return handled_ok;
1781
636
}
1782
#else
1783
#  define png_handle_tRNS NULL
1784
#endif
1785
1786
#ifdef PNG_READ_bKGD_SUPPORTED
1787
static png_handle_result_code /* PRIVATE */
1788
png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1789
926
{
1790
926
   unsigned int truelen;
1791
926
   png_byte buf[6];
1792
926
   png_color_16 background;
1793
1794
926
   png_debug(1, "in png_handle_bKGD");
1795
1796
926
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1797
155
   {
1798
155
      if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
1799
66
      {
1800
66
         png_crc_finish(png_ptr, length);
1801
66
         png_chunk_benign_error(png_ptr, "out of place");
1802
66
         return handled_error;
1803
66
      }
1804
1805
89
      truelen = 1;
1806
89
   }
1807
1808
771
   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
1809
366
      truelen = 6;
1810
1811
405
   else
1812
405
      truelen = 2;
1813
1814
860
   if (length != truelen)
1815
274
   {
1816
274
      png_crc_finish(png_ptr, length);
1817
274
      png_chunk_benign_error(png_ptr, "invalid");
1818
274
      return handled_error;
1819
274
   }
1820
1821
586
   png_crc_read(png_ptr, buf, truelen);
1822
1823
586
   if (png_crc_finish(png_ptr, 0) != 0)
1824
57
      return handled_error;
1825
1826
   /* We convert the index value into RGB components so that we can allow
1827
    * arbitrary RGB values for background when we have transparency, and
1828
    * so it is easy to determine the RGB values of the background color
1829
    * from the info_ptr struct.
1830
    */
1831
529
   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1832
21
   {
1833
21
      background.index = buf[0];
1834
1835
21
      if (info_ptr != NULL && info_ptr->num_palette != 0)
1836
21
      {
1837
21
         if (buf[0] >= info_ptr->num_palette)
1838
10
         {
1839
10
            png_chunk_benign_error(png_ptr, "invalid index");
1840
10
            return handled_error;
1841
10
         }
1842
1843
11
         background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
1844
11
         background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
1845
11
         background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
1846
11
      }
1847
1848
0
      else
1849
0
         background.red = background.green = background.blue = 0;
1850
1851
11
      background.gray = 0;
1852
11
   }
1853
1854
508
   else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */
1855
251
   {
1856
251
      if (png_ptr->bit_depth <= 8)
1857
223
      {
1858
223
         if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth))
1859
203
         {
1860
203
            png_chunk_benign_error(png_ptr, "invalid gray level");
1861
203
            return handled_error;
1862
203
         }
1863
223
      }
1864
1865
48
      background.index = 0;
1866
48
      background.red =
1867
48
      background.green =
1868
48
      background.blue =
1869
48
      background.gray = png_get_uint_16(buf);
1870
48
   }
1871
1872
257
   else
1873
257
   {
1874
257
      if (png_ptr->bit_depth <= 8)
1875
225
      {
1876
225
         if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0)
1877
54
         {
1878
54
            png_chunk_benign_error(png_ptr, "invalid color");
1879
54
            return handled_error;
1880
54
         }
1881
225
      }
1882
1883
203
      background.index = 0;
1884
203
      background.red = png_get_uint_16(buf);
1885
203
      background.green = png_get_uint_16(buf + 2);
1886
203
      background.blue = png_get_uint_16(buf + 4);
1887
203
      background.gray = 0;
1888
203
   }
1889
1890
262
   png_set_bKGD(png_ptr, info_ptr, &background);
1891
262
   return handled_ok;
1892
529
}
1893
#else
1894
#  define png_handle_bKGD NULL
1895
#endif
1896
1897
#ifdef PNG_READ_cICP_SUPPORTED
1898
static png_handle_result_code /* PRIVATE */
1899
png_handle_cICP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1900
328
{
1901
328
   png_byte buf[4];
1902
1903
328
   png_debug(1, "in png_handle_cICP");
1904
1905
328
   png_crc_read(png_ptr, buf, 4);
1906
1907
328
   if (png_crc_finish(png_ptr, 0) != 0)
1908
196
      return handled_error;
1909
1910
132
   png_set_cICP(png_ptr, info_ptr, buf[0], buf[1],  buf[2], buf[3]);
1911
1912
   /* We only use 'chromaticities' for RGB to gray */
1913
132
#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1914
132
      if (!png_has_chunk(png_ptr, mDCV))
1915
33
      {
1916
         /* TODO: png_ptr->chromaticities = chromaticities; */
1917
33
      }
1918
132
#  endif /* READ_RGB_TO_GRAY */
1919
1920
132
#ifdef PNG_READ_GAMMA_SUPPORTED
1921
      /* PNGv3: chunk precedence for gamma is cICP, [iCCP], sRGB, gAMA.  cICP is
1922
       * at the head so simply set the gamma if it can be determined.  If not
1923
       * chunk_gamma remains unchanged; sRGB and gAMA handling check it for
1924
       * being zero.
1925
       */
1926
      /* TODO: set png_struct::chunk_gamma when possible */
1927
132
#endif /*READ_GAMMA*/
1928
1929
132
   return handled_ok;
1930
0
   PNG_UNUSED(length)
1931
0
}
1932
#else
1933
#  define png_handle_cICP NULL
1934
#endif
1935
1936
#ifdef PNG_READ_cLLI_SUPPORTED
1937
static png_handle_result_code /* PRIVATE */
1938
png_handle_cLLI(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1939
252
{
1940
252
   png_byte buf[8];
1941
1942
252
   png_debug(1, "in png_handle_cLLI");
1943
1944
252
   png_crc_read(png_ptr, buf, 8);
1945
1946
252
   if (png_crc_finish(png_ptr, 0) != 0)
1947
32
      return handled_error;
1948
1949
   /* The error checking happens here, this puts it in just one place: */
1950
220
   png_set_cLLI_fixed(png_ptr, info_ptr, png_get_uint_32(buf),
1951
220
         png_get_uint_32(buf+4));
1952
220
   return handled_ok;
1953
0
   PNG_UNUSED(length)
1954
0
}
1955
#else
1956
#  define png_handle_cLLI NULL
1957
#endif
1958
1959
#ifdef PNG_READ_mDCV_SUPPORTED
1960
static png_handle_result_code /* PRIVATE */
1961
png_handle_mDCV(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
1962
187
{
1963
187
   png_xy chromaticities;
1964
187
   png_byte buf[24];
1965
1966
187
   png_debug(1, "in png_handle_mDCV");
1967
1968
187
   png_crc_read(png_ptr, buf, 24);
1969
1970
187
   if (png_crc_finish(png_ptr, 0) != 0)
1971
33
      return handled_error;
1972
1973
   /* The error checking happens here, this puts it in just one place.  The
1974
    * odd /50000 scaling factor makes it more difficult but the (x.y) values are
1975
    * only two bytes so a <<1 is safe.
1976
    *
1977
    * WARNING: the PNG specification defines the cHRM chunk to **start** with
1978
    * the white point (x,y).  The W3C PNG v3 specification puts the white point
1979
    * **after* R,G,B.  The x,y values in mDCV are also scaled by 50,000 and
1980
    * stored in just two bytes, whereas those in cHRM are scaled by 100,000 and
1981
    * stored in four bytes.  This is very, very confusing.  These APIs remove
1982
    * the confusion by copying the existing, well established, API.
1983
    */
1984
154
   chromaticities.redx   = png_get_uint_16(buf+ 0U) << 1; /* red x */
1985
154
   chromaticities.redy   = png_get_uint_16(buf+ 2U) << 1; /* red y */
1986
154
   chromaticities.greenx = png_get_uint_16(buf+ 4U) << 1; /* green x */
1987
154
   chromaticities.greeny = png_get_uint_16(buf+ 6U) << 1; /* green y */
1988
154
   chromaticities.bluex  = png_get_uint_16(buf+ 8U) << 1; /* blue x */
1989
154
   chromaticities.bluey  = png_get_uint_16(buf+10U) << 1; /* blue y */
1990
154
   chromaticities.whitex = png_get_uint_16(buf+12U) << 1; /* white x */
1991
154
   chromaticities.whitey = png_get_uint_16(buf+14U) << 1; /* white y */
1992
1993
154
   png_set_mDCV_fixed(png_ptr, info_ptr,
1994
154
         chromaticities.whitex, chromaticities.whitey,
1995
154
         chromaticities.redx, chromaticities.redy,
1996
154
         chromaticities.greenx, chromaticities.greeny,
1997
154
         chromaticities.bluex, chromaticities.bluey,
1998
154
         png_get_uint_32(buf+16U), /* peak luminance */
1999
154
         png_get_uint_32(buf+20U));/* minimum perceivable luminance */
2000
2001
   /* We only use 'chromaticities' for RGB to gray */
2002
154
#  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2003
154
      png_ptr->chromaticities = chromaticities;
2004
154
#  endif /* READ_RGB_TO_GRAY */
2005
2006
154
   return handled_ok;
2007
0
   PNG_UNUSED(length)
2008
0
}
2009
#else
2010
#  define png_handle_mDCV NULL
2011
#endif
2012
2013
#ifdef PNG_READ_eXIf_SUPPORTED
2014
static png_handle_result_code /* PRIVATE */
2015
png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2016
116
{
2017
116
   png_bytep buffer = NULL;
2018
2019
116
   png_debug(1, "in png_handle_eXIf");
2020
2021
116
   buffer = png_read_buffer(png_ptr, length);
2022
2023
116
   if (buffer == NULL)
2024
0
   {
2025
0
      png_crc_finish(png_ptr, length);
2026
0
      png_chunk_benign_error(png_ptr, "out of memory");
2027
0
      return handled_error;
2028
0
   }
2029
2030
116
   png_crc_read(png_ptr, buffer, length);
2031
2032
116
   if (png_crc_finish(png_ptr, 0) != 0)
2033
26
      return handled_error;
2034
2035
   /* PNGv3: the code used to check the byte order mark at the start for MM or
2036
    * II, however PNGv3 states that the the first 4 bytes should be checked.
2037
    * The caller ensures that there are four bytes available.
2038
    */
2039
90
   {
2040
90
      png_uint_32 header = png_get_uint_32(buffer);
2041
2042
      /* These numbers are copied from the PNGv3 spec: */
2043
90
      if (header != 0x49492A00 && header != 0x4D4D002A)
2044
62
      {
2045
62
         png_chunk_benign_error(png_ptr, "invalid");
2046
62
         return handled_error;
2047
62
      }
2048
90
   }
2049
2050
28
   png_set_eXIf_1(png_ptr, info_ptr, length, buffer);
2051
28
   return handled_ok;
2052
90
}
2053
#else
2054
#  define png_handle_eXIf NULL
2055
#endif
2056
2057
#ifdef PNG_READ_hIST_SUPPORTED
2058
static png_handle_result_code /* PRIVATE */
2059
png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2060
23
{
2061
23
   unsigned int num, i;
2062
23
   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
2063
2064
23
   png_debug(1, "in png_handle_hIST");
2065
2066
   /* This cast is safe because the chunk definition limits the length to a
2067
    * maximum of 1024 bytes.
2068
    *
2069
    * TODO: maybe use png_uint_32 anyway, not unsigned int, to reduce the
2070
    * casts.
2071
    */
2072
23
   num = (unsigned int)length / 2 ;
2073
2074
23
   if (length != num * 2 ||
2075
23
       num != (unsigned int)png_ptr->num_palette ||
2076
23
       num > (unsigned int)PNG_MAX_PALETTE_LENGTH)
2077
22
   {
2078
22
      png_crc_finish(png_ptr, length);
2079
22
      png_chunk_benign_error(png_ptr, "invalid");
2080
22
      return handled_error;
2081
22
   }
2082
2083
1
   for (i = 0; i < num; i++)
2084
0
   {
2085
0
      png_byte buf[2];
2086
2087
0
      png_crc_read(png_ptr, buf, 2);
2088
0
      readbuf[i] = png_get_uint_16(buf);
2089
0
   }
2090
2091
1
   if (png_crc_finish(png_ptr, 0) != 0)
2092
0
      return handled_error;
2093
2094
1
   png_set_hIST(png_ptr, info_ptr, readbuf);
2095
1
   return handled_ok;
2096
1
}
2097
#else
2098
#  define png_handle_hIST NULL
2099
#endif
2100
2101
#ifdef PNG_READ_pHYs_SUPPORTED
2102
static png_handle_result_code /* PRIVATE */
2103
png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2104
61
{
2105
61
   png_byte buf[9];
2106
61
   png_uint_32 res_x, res_y;
2107
61
   int unit_type;
2108
2109
61
   png_debug(1, "in png_handle_pHYs");
2110
2111
61
   png_crc_read(png_ptr, buf, 9);
2112
2113
61
   if (png_crc_finish(png_ptr, 0) != 0)
2114
2
      return handled_error;
2115
2116
59
   res_x = png_get_uint_32(buf);
2117
59
   res_y = png_get_uint_32(buf + 4);
2118
59
   unit_type = buf[8];
2119
59
   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
2120
59
   return handled_ok;
2121
0
   PNG_UNUSED(length)
2122
0
}
2123
#else
2124
#  define png_handle_pHYs NULL
2125
#endif
2126
2127
#ifdef PNG_READ_oFFs_SUPPORTED
2128
static png_handle_result_code /* PRIVATE */
2129
png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2130
277
{
2131
277
   png_byte buf[9];
2132
277
   png_int_32 offset_x, offset_y;
2133
277
   int unit_type;
2134
2135
277
   png_debug(1, "in png_handle_oFFs");
2136
2137
277
   png_crc_read(png_ptr, buf, 9);
2138
2139
277
   if (png_crc_finish(png_ptr, 0) != 0)
2140
106
      return handled_error;
2141
2142
171
   offset_x = png_get_int_32(buf);
2143
171
   offset_y = png_get_int_32(buf + 4);
2144
171
   unit_type = buf[8];
2145
171
   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
2146
171
   return handled_ok;
2147
0
   PNG_UNUSED(length)
2148
0
}
2149
#else
2150
#  define png_handle_oFFs NULL
2151
#endif
2152
2153
#ifdef PNG_READ_pCAL_SUPPORTED
2154
/* Read the pCAL chunk (described in the PNG Extensions document) */
2155
static png_handle_result_code /* PRIVATE */
2156
png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2157
1.61k
{
2158
1.61k
   png_int_32 X0, X1;
2159
1.61k
   png_byte type, nparams;
2160
1.61k
   png_bytep buffer, buf, units, endptr;
2161
1.61k
   png_charpp params;
2162
1.61k
   int i;
2163
2164
1.61k
   png_debug(1, "in png_handle_pCAL");
2165
1.61k
   png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
2166
1.61k
       length + 1);
2167
2168
1.61k
   buffer = png_read_buffer(png_ptr, length+1);
2169
2170
1.61k
   if (buffer == NULL)
2171
1
   {
2172
1
      png_crc_finish(png_ptr, length);
2173
1
      png_chunk_benign_error(png_ptr, "out of memory");
2174
1
      return handled_error;
2175
1
   }
2176
2177
1.61k
   png_crc_read(png_ptr, buffer, length);
2178
2179
1.61k
   if (png_crc_finish(png_ptr, 0) != 0)
2180
123
      return handled_error;
2181
2182
1.49k
   buffer[length] = 0; /* Null terminate the last string */
2183
2184
1.49k
   png_debug(3, "Finding end of pCAL purpose string");
2185
21.5k
   for (buf = buffer; *buf; buf++)
2186
20.0k
      /* Empty loop */ ;
2187
2188
1.49k
   endptr = buffer + length;
2189
2190
   /* We need to have at least 12 bytes after the purpose string
2191
    * in order to get the parameter information.
2192
    */
2193
1.49k
   if (endptr - buf <= 12)
2194
15
   {
2195
15
      png_chunk_benign_error(png_ptr, "invalid");
2196
15
      return handled_error;
2197
15
   }
2198
2199
1.48k
   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
2200
1.48k
   X0 = png_get_int_32((png_bytep)buf+1);
2201
1.48k
   X1 = png_get_int_32((png_bytep)buf+5);
2202
1.48k
   type = buf[9];
2203
1.48k
   nparams = buf[10];
2204
1.48k
   units = buf + 11;
2205
2206
1.48k
   png_debug(3, "Checking pCAL equation type and number of parameters");
2207
   /* Check that we have the right number of parameters for known
2208
    * equation types.
2209
    */
2210
1.48k
   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
2211
1.48k
       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
2212
1.48k
       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
2213
1.48k
       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
2214
893
   {
2215
893
      png_chunk_benign_error(png_ptr, "invalid parameter count");
2216
893
      return handled_error;
2217
893
   }
2218
2219
587
   else if (type >= PNG_EQUATION_LAST)
2220
469
   {
2221
469
      png_chunk_benign_error(png_ptr, "unrecognized equation type");
2222
469
   }
2223
2224
4.54k
   for (buf = units; *buf; buf++)
2225
3.95k
      /* Empty loop to move past the units string. */ ;
2226
2227
587
   png_debug(3, "Allocating pCAL parameters array");
2228
2229
587
   params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
2230
587
       nparams * (sizeof (png_charp))));
2231
2232
587
   if (params == NULL)
2233
0
   {
2234
0
      png_chunk_benign_error(png_ptr, "out of memory");
2235
0
      return handled_error;
2236
0
   }
2237
2238
   /* Get pointers to the start of each parameter string. */
2239
2.31k
   for (i = 0; i < nparams; i++)
2240
2.19k
   {
2241
2.19k
      buf++; /* Skip the null string terminator from previous parameter. */
2242
2243
2.19k
      png_debug1(3, "Reading pCAL parameter %d", i);
2244
2245
6.56k
      for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++)
2246
4.37k
         /* Empty loop to move past each parameter string */ ;
2247
2248
      /* Make sure we haven't run out of data yet */
2249
2.19k
      if (buf > endptr)
2250
465
      {
2251
465
         png_free(png_ptr, params);
2252
465
         png_chunk_benign_error(png_ptr, "invalid data");
2253
465
         return handled_error;
2254
465
      }
2255
2.19k
   }
2256
2257
122
   png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
2258
122
       (png_charp)units, params);
2259
2260
   /* TODO: BUG: png_set_pCAL calls png_chunk_report which, in this case, calls
2261
    * png_benign_error and that can error out.
2262
    *
2263
    * png_read_buffer needs to be allocated with space for both nparams and the
2264
    * parameter strings.  Not hard to do.
2265
    */
2266
122
   png_free(png_ptr, params);
2267
122
   return handled_ok;
2268
587
}
2269
#else
2270
#  define png_handle_pCAL NULL
2271
#endif
2272
2273
#ifdef PNG_READ_sCAL_SUPPORTED
2274
/* Read the sCAL chunk */
2275
static png_handle_result_code /* PRIVATE */
2276
png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2277
1.03k
{
2278
1.03k
   png_bytep buffer;
2279
1.03k
   size_t i;
2280
1.03k
   int state;
2281
2282
1.03k
   png_debug(1, "in png_handle_sCAL");
2283
1.03k
   png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
2284
1.03k
       length + 1);
2285
2286
1.03k
   buffer = png_read_buffer(png_ptr, length+1);
2287
2288
1.03k
   if (buffer == NULL)
2289
1
   {
2290
1
      png_crc_finish(png_ptr, length);
2291
1
      png_chunk_benign_error(png_ptr, "out of memory");
2292
1
      return handled_error;
2293
1
   }
2294
2295
1.03k
   png_crc_read(png_ptr, buffer, length);
2296
1.03k
   buffer[length] = 0; /* Null terminate the last string */
2297
2298
1.03k
   if (png_crc_finish(png_ptr, 0) != 0)
2299
195
      return handled_error;
2300
2301
   /* Validate the unit. */
2302
838
   if (buffer[0] != 1 && buffer[0] != 2)
2303
138
   {
2304
138
      png_chunk_benign_error(png_ptr, "invalid unit");
2305
138
      return handled_error;
2306
138
   }
2307
2308
   /* Validate the ASCII numbers, need two ASCII numbers separated by
2309
    * a '\0' and they need to fit exactly in the chunk data.
2310
    */
2311
700
   i = 1;
2312
700
   state = 0;
2313
2314
700
   if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 ||
2315
700
       i >= length || buffer[i++] != 0)
2316
79
      png_chunk_benign_error(png_ptr, "bad width format");
2317
2318
621
   else if (PNG_FP_IS_POSITIVE(state) == 0)
2319
3
      png_chunk_benign_error(png_ptr, "non-positive width");
2320
2321
618
   else
2322
618
   {
2323
618
      size_t heighti = i;
2324
2325
618
      state = 0;
2326
618
      if (png_check_fp_number((png_const_charp)buffer, length,
2327
618
          &state, &i) == 0 || i != length)
2328
526
         png_chunk_benign_error(png_ptr, "bad height format");
2329
2330
92
      else if (PNG_FP_IS_POSITIVE(state) == 0)
2331
3
         png_chunk_benign_error(png_ptr, "non-positive height");
2332
2333
89
      else
2334
89
      {
2335
         /* This is the (only) success case. */
2336
89
         png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
2337
89
             (png_charp)buffer+1, (png_charp)buffer+heighti);
2338
89
         return handled_ok;
2339
89
      }
2340
618
   }
2341
2342
611
   return handled_error;
2343
700
}
2344
#else
2345
#  define png_handle_sCAL NULL
2346
#endif
2347
2348
#ifdef PNG_READ_tIME_SUPPORTED
2349
static png_handle_result_code /* PRIVATE */
2350
png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2351
70
{
2352
70
   png_byte buf[7];
2353
70
   png_time mod_time;
2354
2355
70
   png_debug(1, "in png_handle_tIME");
2356
2357
   /* TODO: what is this doing here?  It should be happened in pngread.c and
2358
    * pngpread.c, although it could be moved to png_handle_chunk below and
2359
    * thereby avoid some code duplication.
2360
    */
2361
70
   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
2362
1
      png_ptr->mode |= PNG_AFTER_IDAT;
2363
2364
70
   png_crc_read(png_ptr, buf, 7);
2365
2366
70
   if (png_crc_finish(png_ptr, 0) != 0)
2367
1
      return handled_error;
2368
2369
69
   mod_time.second = buf[6];
2370
69
   mod_time.minute = buf[5];
2371
69
   mod_time.hour = buf[4];
2372
69
   mod_time.day = buf[3];
2373
69
   mod_time.month = buf[2];
2374
69
   mod_time.year = png_get_uint_16(buf);
2375
2376
69
   png_set_tIME(png_ptr, info_ptr, &mod_time);
2377
69
   return handled_ok;
2378
0
   PNG_UNUSED(length)
2379
0
}
2380
#else
2381
#  define png_handle_tIME NULL
2382
#endif
2383
2384
#ifdef PNG_READ_tEXt_SUPPORTED
2385
/* Note: this does not properly handle chunks that are > 64K under DOS */
2386
static png_handle_result_code /* PRIVATE */
2387
png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2388
5.54k
{
2389
5.54k
   png_text  text_info;
2390
5.54k
   png_bytep buffer;
2391
5.54k
   png_charp key;
2392
5.54k
   png_charp text;
2393
5.54k
   png_uint_32 skip = 0;
2394
2395
5.54k
   png_debug(1, "in png_handle_tEXt");
2396
2397
5.54k
#ifdef PNG_USER_LIMITS_SUPPORTED
2398
5.54k
   if (png_ptr->user_chunk_cache_max != 0)
2399
5.54k
   {
2400
5.54k
      if (png_ptr->user_chunk_cache_max == 1)
2401
0
      {
2402
0
         png_crc_finish(png_ptr, length);
2403
0
         return handled_error;
2404
0
      }
2405
2406
5.54k
      if (--png_ptr->user_chunk_cache_max == 1)
2407
0
      {
2408
0
         png_crc_finish(png_ptr, length);
2409
0
         png_chunk_benign_error(png_ptr, "no space in chunk cache");
2410
0
         return handled_error;
2411
0
      }
2412
5.54k
   }
2413
5.54k
#endif
2414
2415
   /* TODO: this doesn't work and shouldn't be necessary. */
2416
5.54k
   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
2417
1.98k
      png_ptr->mode |= PNG_AFTER_IDAT;
2418
2419
5.54k
   buffer = png_read_buffer(png_ptr, length+1);
2420
2421
5.54k
   if (buffer == NULL)
2422
2
   {
2423
2
      png_crc_finish(png_ptr, length);
2424
2
      png_chunk_benign_error(png_ptr, "out of memory");
2425
2
      return handled_error;
2426
2
   }
2427
2428
5.54k
   png_crc_read(png_ptr, buffer, length);
2429
2430
5.54k
   if (png_crc_finish(png_ptr, skip) != 0)
2431
790
      return handled_error;
2432
2433
4.75k
   key = (png_charp)buffer;
2434
4.75k
   key[length] = 0;
2435
2436
43.4k
   for (text = key; *text; text++)
2437
38.6k
      /* Empty loop to find end of key */ ;
2438
2439
4.75k
   if (text != key + length)
2440
4.72k
      text++;
2441
2442
4.75k
   text_info.compression = PNG_TEXT_COMPRESSION_NONE;
2443
4.75k
   text_info.key = key;
2444
4.75k
   text_info.lang = NULL;
2445
4.75k
   text_info.lang_key = NULL;
2446
4.75k
   text_info.itxt_length = 0;
2447
4.75k
   text_info.text = text;
2448
4.75k
   text_info.text_length = strlen(text);
2449
2450
4.75k
   if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) == 0)
2451
4.75k
      return handled_ok;
2452
2453
6
   png_chunk_benign_error(png_ptr, "out of memory");
2454
6
   return handled_error;
2455
4.75k
}
2456
#else
2457
#  define png_handle_tEXt NULL
2458
#endif
2459
2460
#ifdef PNG_READ_zTXt_SUPPORTED
2461
/* Note: this does not correctly handle chunks that are > 64K under DOS */
2462
static png_handle_result_code /* PRIVATE */
2463
png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2464
348
{
2465
348
   png_const_charp errmsg = NULL;
2466
348
   png_bytep       buffer;
2467
348
   png_uint_32     keyword_length;
2468
2469
348
   png_debug(1, "in png_handle_zTXt");
2470
2471
348
#ifdef PNG_USER_LIMITS_SUPPORTED
2472
348
   if (png_ptr->user_chunk_cache_max != 0)
2473
348
   {
2474
348
      if (png_ptr->user_chunk_cache_max == 1)
2475
0
      {
2476
0
         png_crc_finish(png_ptr, length);
2477
0
         return handled_error;
2478
0
      }
2479
2480
348
      if (--png_ptr->user_chunk_cache_max == 1)
2481
0
      {
2482
0
         png_crc_finish(png_ptr, length);
2483
0
         png_chunk_benign_error(png_ptr, "no space in chunk cache");
2484
0
         return handled_error;
2485
0
      }
2486
348
   }
2487
348
#endif
2488
2489
   /* TODO: should not be necessary. */
2490
348
   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
2491
60
      png_ptr->mode |= PNG_AFTER_IDAT;
2492
2493
   /* Note, "length" is sufficient here; we won't be adding
2494
    * a null terminator later.  The limit check in png_handle_chunk should be
2495
    * sufficient.
2496
    */
2497
348
   buffer = png_read_buffer(png_ptr, length);
2498
2499
348
   if (buffer == NULL)
2500
0
   {
2501
0
      png_crc_finish(png_ptr, length);
2502
0
      png_chunk_benign_error(png_ptr, "out of memory");
2503
0
      return handled_error;
2504
0
   }
2505
2506
348
   png_crc_read(png_ptr, buffer, length);
2507
2508
348
   if (png_crc_finish(png_ptr, 0) != 0)
2509
21
      return handled_error;
2510
2511
   /* TODO: also check that the keyword contents match the spec! */
2512
327
   for (keyword_length = 0;
2513
3.12k
      keyword_length < length && buffer[keyword_length] != 0;
2514
2.79k
      ++keyword_length)
2515
2.79k
      /* Empty loop to find end of name */ ;
2516
2517
327
   if (keyword_length > 79 || keyword_length < 1)
2518
21
      errmsg = "bad keyword";
2519
2520
   /* zTXt must have some LZ data after the keyword, although it may expand to
2521
    * zero bytes; we need a '\0' at the end of the keyword, the compression type
2522
    * then the LZ data:
2523
    */
2524
306
   else if (keyword_length + 3 > length)
2525
42
      errmsg = "truncated";
2526
2527
264
   else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE)
2528
210
      errmsg = "unknown compression type";
2529
2530
54
   else
2531
54
   {
2532
54
      png_alloc_size_t uncompressed_length = PNG_SIZE_MAX;
2533
2534
      /* TODO: at present png_decompress_chunk imposes a single application
2535
       * level memory limit, this should be split to different values for iCCP
2536
       * and text chunks.
2537
       */
2538
54
      if (png_decompress_chunk(png_ptr, length, keyword_length+2,
2539
54
          &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
2540
13
      {
2541
13
         png_text text;
2542
2543
13
         if (png_ptr->read_buffer == NULL)
2544
0
           errmsg="Read failure in png_handle_zTXt";
2545
13
         else
2546
13
         {
2547
            /* It worked; png_ptr->read_buffer now looks like a tEXt chunk
2548
             * except for the extra compression type byte and the fact that
2549
             * it isn't necessarily '\0' terminated.
2550
             */
2551
13
            buffer = png_ptr->read_buffer;
2552
13
            buffer[uncompressed_length+(keyword_length+2)] = 0;
2553
2554
13
            text.compression = PNG_TEXT_COMPRESSION_zTXt;
2555
13
            text.key = (png_charp)buffer;
2556
13
            text.text = (png_charp)(buffer + keyword_length+2);
2557
13
            text.text_length = uncompressed_length;
2558
13
            text.itxt_length = 0;
2559
13
            text.lang = NULL;
2560
13
            text.lang_key = NULL;
2561
2562
13
            if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0)
2563
13
               return handled_ok;
2564
2565
0
            errmsg = "out of memory";
2566
0
         }
2567
13
      }
2568
2569
41
      else
2570
41
         errmsg = png_ptr->zstream.msg;
2571
54
   }
2572
2573
314
   png_chunk_benign_error(png_ptr, errmsg);
2574
314
   return handled_error;
2575
327
}
2576
#else
2577
#  define png_handle_zTXt NULL
2578
#endif
2579
2580
#ifdef PNG_READ_iTXt_SUPPORTED
2581
/* Note: this does not correctly handle chunks that are > 64K under DOS */
2582
static png_handle_result_code /* PRIVATE */
2583
png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
2584
1.69k
{
2585
1.69k
   png_const_charp errmsg = NULL;
2586
1.69k
   png_bytep buffer;
2587
1.69k
   png_uint_32 prefix_length;
2588
2589
1.69k
   png_debug(1, "in png_handle_iTXt");
2590
2591
1.69k
#ifdef PNG_USER_LIMITS_SUPPORTED
2592
1.69k
   if (png_ptr->user_chunk_cache_max != 0)
2593
1.69k
   {
2594
1.69k
      if (png_ptr->user_chunk_cache_max == 1)
2595
0
      {
2596
0
         png_crc_finish(png_ptr, length);
2597
0
         return handled_error;
2598
0
      }
2599
2600
1.69k
      if (--png_ptr->user_chunk_cache_max == 1)
2601
0
      {
2602
0
         png_crc_finish(png_ptr, length);
2603
0
         png_chunk_benign_error(png_ptr, "no space in chunk cache");
2604
0
         return handled_error;
2605
0
      }
2606
1.69k
   }
2607
1.69k
#endif
2608
2609
   /* TODO: should not be necessary. */
2610
1.69k
   if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
2611
532
      png_ptr->mode |= PNG_AFTER_IDAT;
2612
2613
1.69k
   buffer = png_read_buffer(png_ptr, length+1);
2614
2615
1.69k
   if (buffer == NULL)
2616
1
   {
2617
1
      png_crc_finish(png_ptr, length);
2618
1
      png_chunk_benign_error(png_ptr, "out of memory");
2619
1
      return handled_error;
2620
1
   }
2621
2622
1.68k
   png_crc_read(png_ptr, buffer, length);
2623
2624
1.68k
   if (png_crc_finish(png_ptr, 0) != 0)
2625
197
      return handled_error;
2626
2627
   /* First the keyword. */
2628
1.49k
   for (prefix_length=0;
2629
20.0k
      prefix_length < length && buffer[prefix_length] != 0;
2630
18.5k
      ++prefix_length)
2631
18.5k
      /* Empty loop */ ;
2632
2633
   /* Perform a basic check on the keyword length here. */
2634
1.49k
   if (prefix_length > 79 || prefix_length < 1)
2635
42
      errmsg = "bad keyword";
2636
2637
   /* Expect keyword, compression flag, compression type, language, translated
2638
    * keyword (both may be empty but are 0 terminated) then the text, which may
2639
    * be empty.
2640
    */
2641
1.45k
   else if (prefix_length + 5 > length)
2642
18
      errmsg = "truncated";
2643
2644
1.43k
   else if (buffer[prefix_length+1] == 0 ||
2645
1.43k
      (buffer[prefix_length+1] == 1 &&
2646
1.23k
      buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE))
2647
1.38k
   {
2648
1.38k
      int compressed = buffer[prefix_length+1] != 0;
2649
1.38k
      png_uint_32 language_offset, translated_keyword_offset;
2650
1.38k
      png_alloc_size_t uncompressed_length = 0;
2651
2652
      /* Now the language tag */
2653
1.38k
      prefix_length += 3;
2654
1.38k
      language_offset = prefix_length;
2655
2656
8.87k
      for (; prefix_length < length && buffer[prefix_length] != 0;
2657
7.49k
         ++prefix_length)
2658
7.49k
         /* Empty loop */ ;
2659
2660
      /* WARNING: the length may be invalid here, this is checked below. */
2661
1.38k
      translated_keyword_offset = ++prefix_length;
2662
2663
3.12k
      for (; prefix_length < length && buffer[prefix_length] != 0;
2664
1.74k
         ++prefix_length)
2665
1.74k
         /* Empty loop */ ;
2666
2667
      /* prefix_length should now be at the trailing '\0' of the translated
2668
       * keyword, but it may already be over the end.  None of this arithmetic
2669
       * can overflow because chunks are at most 2^31 bytes long, but on 16-bit
2670
       * systems the available allocation may overflow.
2671
       */
2672
1.38k
      ++prefix_length;
2673
2674
1.38k
      if (compressed == 0 && prefix_length <= length)
2675
103
         uncompressed_length = length - prefix_length;
2676
2677
1.28k
      else if (compressed != 0 && prefix_length < length)
2678
1.17k
      {
2679
1.17k
         uncompressed_length = PNG_SIZE_MAX;
2680
2681
         /* TODO: at present png_decompress_chunk imposes a single application
2682
          * level memory limit, this should be split to different values for
2683
          * iCCP and text chunks.
2684
          */
2685
1.17k
         if (png_decompress_chunk(png_ptr, length, prefix_length,
2686
1.17k
             &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
2687
530
            buffer = png_ptr->read_buffer;
2688
2689
643
         else
2690
643
            errmsg = png_ptr->zstream.msg;
2691
1.17k
      }
2692
2693
108
      else
2694
108
         errmsg = "truncated";
2695
2696
1.38k
      if (errmsg == NULL)
2697
633
      {
2698
633
         png_text text;
2699
2700
633
         buffer[uncompressed_length+prefix_length] = 0;
2701
2702
633
         if (compressed == 0)
2703
103
            text.compression = PNG_ITXT_COMPRESSION_NONE;
2704
2705
530
         else
2706
530
            text.compression = PNG_ITXT_COMPRESSION_zTXt;
2707
2708
633
         text.key = (png_charp)buffer;
2709
633
         text.lang = (png_charp)buffer + language_offset;
2710
633
         text.lang_key = (png_charp)buffer + translated_keyword_offset;
2711
633
         text.text = (png_charp)buffer + prefix_length;
2712
633
         text.text_length = 0;
2713
633
         text.itxt_length = uncompressed_length;
2714
2715
633
         if (png_set_text_2(png_ptr, info_ptr, &text, 1) == 0)
2716
633
            return handled_ok;
2717
2718
0
         errmsg = "out of memory";
2719
0
      }
2720
1.38k
   }
2721
2722
48
   else
2723
48
      errmsg = "bad compression info";
2724
2725
859
   if (errmsg != NULL)
2726
852
      png_chunk_benign_error(png_ptr, errmsg);
2727
859
   return handled_error;
2728
1.49k
}
2729
#else
2730
#  define png_handle_iTXt NULL
2731
#endif
2732
2733
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2734
/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
2735
static int
2736
png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
2737
0
{
2738
0
   const png_alloc_size_t limit = png_chunk_max(png_ptr);
2739
2740
0
   if (png_ptr->unknown_chunk.data != NULL)
2741
0
   {
2742
0
      png_free(png_ptr, png_ptr->unknown_chunk.data);
2743
0
      png_ptr->unknown_chunk.data = NULL;
2744
0
   }
2745
2746
0
   if (length <= limit)
2747
0
   {
2748
0
      PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
2749
      /* The following is safe because of the PNG_SIZE_MAX init above */
2750
0
      png_ptr->unknown_chunk.size = (size_t)length/*SAFE*/;
2751
      /* 'mode' is a flag array, only the bottom four bits matter here */
2752
0
      png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;
2753
2754
0
      if (length == 0)
2755
0
         png_ptr->unknown_chunk.data = NULL;
2756
2757
0
      else
2758
0
      {
2759
         /* Do a 'warn' here - it is handled below. */
2760
0
         png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
2761
0
             png_malloc_warn(png_ptr, length));
2762
0
      }
2763
0
   }
2764
2765
0
   if (png_ptr->unknown_chunk.data == NULL && length > 0)
2766
0
   {
2767
      /* This is benign because we clean up correctly */
2768
0
      png_crc_finish(png_ptr, length);
2769
0
      png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits");
2770
0
      return 0;
2771
0
   }
2772
2773
0
   else
2774
0
   {
2775
0
      if (length > 0)
2776
0
         png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
2777
0
      png_crc_finish(png_ptr, 0);
2778
0
      return 1;
2779
0
   }
2780
0
}
2781
#endif /* READ_UNKNOWN_CHUNKS */
2782
2783
/* Handle an unknown, or known but disabled, chunk */
2784
png_handle_result_code /*PRIVATE*/
2785
png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
2786
    png_uint_32 length, int keep)
2787
1.84k
{
2788
1.84k
   png_handle_result_code handled = handled_discarded; /* the default */
2789
2790
1.84k
   png_debug(1, "in png_handle_unknown");
2791
2792
1.84k
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2793
   /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing
2794
    * the bug which meant that setting a non-default behavior for a specific
2795
    * chunk would be ignored (the default was always used unless a user
2796
    * callback was installed).
2797
    *
2798
    * 'keep' is the value from the png_chunk_unknown_handling, the setting for
2799
    * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it
2800
    * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here.
2801
    * This is just an optimization to avoid multiple calls to the lookup
2802
    * function.
2803
    */
2804
#  ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2805
#     ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
2806
   keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
2807
#     endif
2808
#  endif
2809
2810
   /* One of the following methods will read the chunk or skip it (at least one
2811
    * of these is always defined because this is the only way to switch on
2812
    * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2813
    */
2814
1.84k
#  ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2815
   /* The user callback takes precedence over the chunk keep value, but the
2816
    * keep value is still required to validate a save of a critical chunk.
2817
    */
2818
1.84k
   if (png_ptr->read_user_chunk_fn != NULL)
2819
0
   {
2820
0
      if (png_cache_unknown_chunk(png_ptr, length) != 0)
2821
0
      {
2822
         /* Callback to user unknown chunk handler */
2823
0
         int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
2824
0
             &png_ptr->unknown_chunk);
2825
2826
         /* ret is:
2827
          * negative: An error occurred; png_chunk_error will be called.
2828
          *     zero: The chunk was not handled, the chunk will be discarded
2829
          *           unless png_set_keep_unknown_chunks has been used to set
2830
          *           a 'keep' behavior for this particular chunk, in which
2831
          *           case that will be used.  A critical chunk will cause an
2832
          *           error at this point unless it is to be saved.
2833
          * positive: The chunk was handled, libpng will ignore/discard it.
2834
          */
2835
0
         if (ret < 0) /* handled_error */
2836
0
            png_chunk_error(png_ptr, "error in user chunk");
2837
2838
0
         else if (ret == 0)
2839
0
         {
2840
            /* If the keep value is 'default' or 'never' override it, but
2841
             * still error out on critical chunks unless the keep value is
2842
             * 'always'  While this is weird it is the behavior in 1.4.12.
2843
             * A possible improvement would be to obey the value set for the
2844
             * chunk, but this would be an API change that would probably
2845
             * damage some applications.
2846
             *
2847
             * The png_app_warning below catches the case that matters, where
2848
             * the application has not set specific save or ignore for this
2849
             * chunk or global save or ignore.
2850
             */
2851
0
            if (keep < PNG_HANDLE_CHUNK_IF_SAFE)
2852
0
            {
2853
0
#              ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
2854
0
               if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE)
2855
0
               {
2856
0
                  png_chunk_warning(png_ptr, "Saving unknown chunk:");
2857
0
                  png_app_warning(png_ptr,
2858
0
                      "forcing save of an unhandled chunk;"
2859
0
                      " please call png_set_keep_unknown_chunks");
2860
                      /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
2861
0
               }
2862
0
#              endif
2863
0
               keep = PNG_HANDLE_CHUNK_IF_SAFE;
2864
0
            }
2865
0
         }
2866
2867
0
         else /* chunk was handled */
2868
0
         {
2869
0
            handled = handled_ok;
2870
            /* Critical chunks can be safely discarded at this point. */
2871
0
            keep = PNG_HANDLE_CHUNK_NEVER;
2872
0
         }
2873
0
      }
2874
2875
0
      else
2876
0
         keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */
2877
0
   }
2878
2879
1.84k
   else
2880
   /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */
2881
1.84k
#  endif /* READ_USER_CHUNKS */
2882
2883
1.84k
#  ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
2884
1.84k
   {
2885
      /* keep is currently just the per-chunk setting, if there was no
2886
       * setting change it to the global default now (not that this may
2887
       * still be AS_DEFAULT) then obtain the cache of the chunk if required,
2888
       * if not simply skip the chunk.
2889
       */
2890
1.84k
      if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
2891
1.84k
         keep = png_ptr->unknown_default;
2892
2893
1.84k
      if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
2894
1.84k
         (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
2895
1.84k
          PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
2896
0
      {
2897
0
         if (png_cache_unknown_chunk(png_ptr, length) == 0)
2898
0
            keep = PNG_HANDLE_CHUNK_NEVER;
2899
0
      }
2900
2901
1.84k
      else
2902
1.84k
         png_crc_finish(png_ptr, length);
2903
1.84k
   }
2904
#  else
2905
#     ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2906
#        error no method to support READ_UNKNOWN_CHUNKS
2907
#     endif
2908
2909
   {
2910
      /* If here there is no read callback pointer set and no support is
2911
       * compiled in to just save the unknown chunks, so simply skip this
2912
       * chunk.  If 'keep' is something other than AS_DEFAULT or NEVER then
2913
       * the app has erroneously asked for unknown chunk saving when there
2914
       * is no support.
2915
       */
2916
      if (keep > PNG_HANDLE_CHUNK_NEVER)
2917
         png_app_error(png_ptr, "no unknown chunk support available");
2918
2919
      png_crc_finish(png_ptr, length);
2920
   }
2921
#  endif
2922
2923
1.84k
#  ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
2924
   /* Now store the chunk in the chunk list if appropriate, and if the limits
2925
    * permit it.
2926
    */
2927
1.84k
   if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
2928
1.84k
      (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
2929
1.82k
       PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
2930
0
   {
2931
0
#     ifdef PNG_USER_LIMITS_SUPPORTED
2932
0
      switch (png_ptr->user_chunk_cache_max)
2933
0
      {
2934
0
         case 2:
2935
0
            png_ptr->user_chunk_cache_max = 1;
2936
0
            png_chunk_benign_error(png_ptr, "no space in chunk cache");
2937
            /* FALLTHROUGH */
2938
0
         case 1:
2939
            /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
2940
             * chunk being skipped, now there will be a hard error below.
2941
             */
2942
0
            break;
2943
2944
0
         default: /* not at limit */
2945
0
            --(png_ptr->user_chunk_cache_max);
2946
            /* FALLTHROUGH */
2947
0
         case 0: /* no limit */
2948
0
#  endif /* USER_LIMITS */
2949
            /* Here when the limit isn't reached or when limits are compiled
2950
             * out; store the chunk.
2951
             */
2952
0
            png_set_unknown_chunks(png_ptr, info_ptr,
2953
0
                &png_ptr->unknown_chunk, 1);
2954
0
            handled = handled_saved;
2955
0
#  ifdef PNG_USER_LIMITS_SUPPORTED
2956
0
            break;
2957
0
      }
2958
0
#  endif
2959
0
   }
2960
#  else /* no store support: the chunk must be handled by the user callback */
2961
   PNG_UNUSED(info_ptr)
2962
#  endif
2963
2964
   /* Regardless of the error handling below the cached data (if any) can be
2965
    * freed now.  Notice that the data is not freed if there is a png_error, but
2966
    * it will be freed by destroy_read_struct.
2967
    */
2968
1.84k
   if (png_ptr->unknown_chunk.data != NULL)
2969
0
      png_free(png_ptr, png_ptr->unknown_chunk.data);
2970
1.84k
   png_ptr->unknown_chunk.data = NULL;
2971
2972
#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
2973
   /* There is no support to read an unknown chunk, so just skip it. */
2974
   png_crc_finish(png_ptr, length);
2975
   PNG_UNUSED(info_ptr)
2976
   PNG_UNUSED(keep)
2977
#endif /* !READ_UNKNOWN_CHUNKS */
2978
2979
   /* Check for unhandled critical chunks */
2980
1.84k
   if (handled < handled_saved && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
2981
1
      png_chunk_error(png_ptr, "unhandled critical chunk");
2982
2983
1.83k
   return handled;
2984
1.84k
}
2985
2986
/* APNG handling: the minimal implementation of APNG handling in libpng 1.6
2987
 * requires that those significant applications which already handle APNG not
2988
 * get hosed.  To do this ensure the code here will have to ensure than APNG
2989
 * data by default (at least in 1.6) gets stored in the unknown chunk list.
2990
 * Maybe this can be relaxed in a few years but at present it's just the only
2991
 * safe way.
2992
 *
2993
 * ATM just cause unknown handling for all three chunks:
2994
 */
2995
#define png_handle_acTL NULL
2996
#define png_handle_fcTL NULL
2997
#define png_handle_fdAT NULL
2998
2999
/*
3000
 * 1.6.47: This is the new table driven interface to all the chunk handling.
3001
 *
3002
 * The table describes the PNG standard rules for **reading** known chunks -
3003
 * every chunk which has an entry in PNG_KNOWN_CHUNKS.  The table contains an
3004
 * entry for each PNG_INDEX_cHNK describing the rules.
3005
 *
3006
 * In this initial version the only information in the entry is the
3007
 * png_handle_cHNK function for the chunk in question.  When chunk support is
3008
 * compiled out the entry will be NULL.
3009
 */
3010
static const struct
3011
{
3012
   png_handle_result_code (*handler)(
3013
         png_structrp, png_inforp, png_uint_32 length);
3014
      /* A chunk-specific 'handler', NULL if the chunk is not supported in this
3015
       * build.
3016
       */
3017
3018
   /* Crushing these values helps on modern 32-bit architectures because the
3019
    * pointer and the following bit fields both end up requiring 32 bits.
3020
    * Typically this will halve the table size.  On 64-bit architectures the
3021
    * table entries will typically be 8 bytes.
3022
    */
3023
   png_uint_32 max_length :12; /* Length min, max in bytes */
3024
   png_uint_32 min_length :8;
3025
      /* Length errors on critical chunks have special handling to preserve the
3026
       * existing behaviour in libpng 1.6.  Anciallary chunks are checked below
3027
       * and produce a 'benign' error.
3028
       */
3029
   png_uint_32 pos_before :4; /* PNG_HAVE_ values chunk must precede */
3030
   png_uint_32 pos_after  :4; /* PNG_HAVE_ values chunk must follow */
3031
      /* NOTE: PLTE, tRNS and bKGD require special handling which depends on
3032
       * the colour type of the base image.
3033
       */
3034
   png_uint_32 multiple   :1; /* Multiple occurences permitted */
3035
      /* This is enabled for PLTE because PLTE may, in practice, be optional */
3036
}
3037
read_chunks[PNG_INDEX_unknown] =
3038
{
3039
   /* Definitions as above but done indirectly by #define so that
3040
    * PNG_KNOWN_CHUNKS can be used safely to build the table in order.
3041
    *
3042
    * Each CDcHNK definition lists the values for the parameters **after**
3043
    * the first, 'handler', function.  'handler' is NULL when the chunk has no
3044
    * compiled in support.
3045
    */
3046
12.0k
#  define NoCheck 0x801U      /* Do not check the maximum length */
3047
1.49k
#  define Limit   0x802U      /* Limit to png_chunk_max bytes */
3048
#  define LKMin   3U+LZ77Min  /* Minimum length of keyword+LZ77 */
3049
3050
#define hIHDR PNG_HAVE_IHDR
3051
#define hPLTE PNG_HAVE_PLTE
3052
#define hIDAT PNG_HAVE_IDAT
3053
   /* For the two chunks, tRNS and bKGD which can occur in PNGs without a PLTE
3054
    * but must occur after the PLTE use this and put the check in the handler
3055
    * routine for colour mapped images were PLTE is required.  Also put a check
3056
    * in PLTE for other image types to drop the PLTE if tRNS or bKGD have been
3057
    * seen.
3058
    */
3059
#define hCOL  (PNG_HAVE_PLTE|PNG_HAVE_IDAT)
3060
   /* Used for the decoding chunks which must be before PLTE. */
3061
#define aIDAT PNG_AFTER_IDAT
3062
3063
   /* Chunks from W3C PNG v3: */
3064
   /*       cHNK  max_len,   min, before, after, multiple */
3065
#  define CDIHDR      13U,   13U,  hIHDR,     0,        0
3066
#  define CDPLTE  NoCheck,    0U,      0, hIHDR,        1
3067
      /* PLTE errors are only critical for colour-map images, consequently the
3068
       * hander does all the checks.
3069
       */
3070
#  define CDIDAT  NoCheck,    0U,  aIDAT, hIHDR,        1
3071
#  define CDIEND  NoCheck,    0U,      0, aIDAT,        0
3072
      /* Historically data was allowed in IEND */
3073
#  define CDtRNS     256U,    0U,  hIDAT, hIHDR,        0
3074
#  define CDcHRM      32U,   32U,   hCOL, hIHDR,        0
3075
#  define CDgAMA       4U,    4U,   hCOL, hIHDR,        0
3076
#  define CDiCCP  NoCheck, LKMin,   hCOL, hIHDR,        0
3077
#  define CDsBIT       4U,    1U,   hCOL, hIHDR,        0
3078
#  define CDsRGB       1U,    1U,   hCOL, hIHDR,        0
3079
#  define CDcICP       4U,    4U,   hCOL, hIHDR,        0
3080
#  define CDmDCV      24U,   24U,   hCOL, hIHDR,        0
3081
#  define CDeXIf    Limit,    4U,      0, hIHDR,        0
3082
#  define CDcLLI       8U,    8U,   hCOL, hIHDR,        0
3083
#  define CDtEXt  NoCheck,    2U,      0, hIHDR,        1
3084
      /* Allocates 'length+1'; checked in the handler */
3085
#  define CDzTXt    Limit, LKMin,      0, hIHDR,        1
3086
#  define CDiTXt  NoCheck,    6U,      0, hIHDR,        1
3087
      /* Allocates 'length+1'; checked in the handler */
3088
#  define CDbKGD       6U,    1U,  hIDAT, hIHDR,        0
3089
#  define CDhIST    1024U,    0U,  hPLTE, hIHDR,        0
3090
#  define CDpHYs       9U,    9U,  hIDAT, hIHDR,        0
3091
#  define CDsPLT  NoCheck,    3U,  hIDAT, hIHDR,        1
3092
      /* Allocates 'length+1'; checked in the handler */
3093
#  define CDtIME       7U,    7U,      0, hIHDR,        0
3094
#  define CDacTL       8U,    8U,  hIDAT, hIHDR,        0
3095
#  define CDfcTL      25U,   26U,      0, hIHDR,        1
3096
#  define CDfdAT    Limit,    4U,  hIDAT, hIHDR,        1
3097
   /* Supported chunks from PNG extensions 1.5.0, NYI so limit */
3098
#  define CDoFFs       9U,    9U,  hIDAT, hIHDR,        0
3099
#  define CDpCAL  NoCheck,   14U,  hIDAT, hIHDR,        0
3100
      /* Allocates 'length+1'; checked in the handler */
3101
#  define CDsCAL    Limit,    4U,  hIDAT, hIHDR,        0
3102
      /* Allocates 'length+1'; checked in the handler */
3103
3104
#  define PNG_CHUNK(cHNK, index) { png_handle_ ## cHNK, CD ## cHNK },
3105
   PNG_KNOWN_CHUNKS
3106
#  undef PNG_CHUNK
3107
};
3108
3109
3110
static png_index
3111
png_chunk_index_from_name(png_uint_32 chunk_name)
3112
35.7k
{
3113
   /* For chunk png_cHNK return PNG_INDEX_cHNK.  Return PNG_INDEX_unknown if
3114
    * chunk_name is not known.  Notice that in a particular build "known" does
3115
    * not necessarily mean "supported", although the inverse applies.
3116
    */
3117
35.7k
   switch (chunk_name)
3118
35.7k
   {
3119
0
#     define PNG_CHUNK(cHNK, index)\
3120
34.0k
         case png_ ## cHNK: return PNG_INDEX_ ## cHNK; /* == index */
3121
3122
0
      PNG_KNOWN_CHUNKS
3123
3124
0
#     undef PNG_CHUNK
3125
3126
1.72k
      default: return PNG_INDEX_unknown;
3127
35.7k
   }
3128
35.7k
}
3129
3130
png_handle_result_code /*PRIVATE*/
3131
png_handle_chunk(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
3132
35.7k
{
3133
   /* CSE: these things don't change, these autos are just to save typing and
3134
    * make the code more clear.
3135
    */
3136
35.7k
   const png_uint_32 chunk_name = png_ptr->chunk_name;
3137
35.7k
   const png_index chunk_index = png_chunk_index_from_name(chunk_name);
3138
3139
35.7k
   png_handle_result_code handled = handled_error;
3140
35.7k
   png_const_charp errmsg = NULL;
3141
3142
   /* Is this a known chunk?  If not there are no checks performed here;
3143
    * png_handle_unknown does the correct checks.  This means that the values
3144
    * for known but unsupported chunks in the above table are not used here
3145
    * however the chunks_seen fields in png_struct are still set.
3146
    */
3147
35.7k
   if (chunk_index == PNG_INDEX_unknown ||
3148
35.7k
       read_chunks[chunk_index].handler == NULL)
3149
1.84k
   {
3150
1.84k
      handled = png_handle_unknown(
3151
1.84k
            png_ptr, info_ptr, length, PNG_HANDLE_CHUNK_AS_DEFAULT);
3152
1.84k
   }
3153
3154
   /* First check the position.   The first check is historical; the stream must
3155
    * start with IHDR and anything else causes libpng to give up immediately.
3156
    */
3157
33.8k
   else if (chunk_index != PNG_INDEX_IHDR &&
3158
33.8k
            (png_ptr->mode & PNG_HAVE_IHDR) == 0)
3159
2
      png_chunk_error(png_ptr, "missing IHDR"); /* NORETURN */
3160
3161
   /* Before all the pos_before chunks, after all the pos_after chunks. */
3162
33.8k
   else if (((png_ptr->mode & read_chunks[chunk_index].pos_before) != 0) ||
3163
33.8k
            ((png_ptr->mode & read_chunks[chunk_index].pos_after) !=
3164
32.6k
             read_chunks[chunk_index].pos_after))
3165
1.21k
   {
3166
1.21k
      errmsg = "out of place";
3167
1.21k
   }
3168
3169
   /* Now check for duplicates: duplicated critical chunks also produce a
3170
    * full error.
3171
    */
3172
32.6k
   else if (read_chunks[chunk_index].multiple == 0 &&
3173
32.6k
            png_file_has_chunk(png_ptr, chunk_index))
3174
9.08k
   {
3175
9.08k
      errmsg = "duplicate";
3176
9.08k
   }
3177
3178
23.5k
   else if (length < read_chunks[chunk_index].min_length)
3179
115
      errmsg = "too short";
3180
23.4k
   else
3181
23.4k
   {
3182
      /* NOTE: apart from IHDR the critical chunks (PLTE, IDAT and IEND) are set
3183
       * up above not to do any length checks.
3184
       *
3185
       * The png_chunk_max check ensures that the variable length chunks are
3186
       * always checked at this point for being within the system allocation
3187
       * limits.
3188
       */
3189
23.4k
      unsigned max_length = read_chunks[chunk_index].max_length;
3190
3191
23.4k
      switch (max_length)
3192
23.4k
      {
3193
1.49k
         case Limit:
3194
            /* png_read_chunk_header has already png_error'ed chunks with a
3195
             * length exceeding the 31-bit PNG limit, so just check the memory
3196
             * limit:
3197
             */
3198
1.49k
            if (length <= png_chunk_max(png_ptr))
3199
1.49k
               goto MeetsLimit;
3200
3201
1
            errmsg = "length exceeds libpng limit";
3202
1
            break;
3203
3204
9.89k
         default:
3205
9.89k
            if (length <= max_length)
3206
9.81k
               goto MeetsLimit;
3207
3208
77
            errmsg = "too long";
3209
77
            break;
3210
3211
12.0k
         case NoCheck:
3212
23.4k
         MeetsLimit:
3213
23.4k
            handled = read_chunks[chunk_index].handler(
3214
23.4k
                  png_ptr, info_ptr, length);
3215
23.4k
            break;
3216
23.4k
      }
3217
23.4k
   }
3218
3219
   /* If there was an error or the chunk was simply skipped it is not counted as
3220
    * 'seen'.
3221
    */
3222
35.5k
   if (errmsg != NULL)
3223
10.4k
   {
3224
10.4k
      if (PNG_CHUNK_CRITICAL(chunk_name)) /* stop immediately */
3225
3
         png_chunk_error(png_ptr, errmsg);
3226
10.4k
      else /* ancillary chunk */
3227
10.4k
      {
3228
         /* The chunk data is skipped: */
3229
10.4k
         png_crc_finish(png_ptr, length);
3230
10.4k
         png_chunk_benign_error(png_ptr, errmsg);
3231
10.4k
      }
3232
10.4k
   }
3233
3234
25.0k
   else if (handled >= handled_saved)
3235
12.4k
   {
3236
12.4k
      if (chunk_index != PNG_INDEX_unknown)
3237
12.4k
         png_file_add_chunk(png_ptr, chunk_index);
3238
12.4k
   }
3239
3240
35.5k
   return handled;
3241
35.5k
}
3242
3243
/* Combines the row recently read in with the existing pixels in the row.  This
3244
 * routine takes care of alpha and transparency if requested.  This routine also
3245
 * handles the two methods of progressive display of interlaced images,
3246
 * depending on the 'display' value; if 'display' is true then the whole row
3247
 * (dp) is filled from the start by replicating the available pixels.  If
3248
 * 'display' is false only those pixels present in the pass are filled in.
3249
 */
3250
void /* PRIVATE */
3251
png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
3252
118k
{
3253
118k
   unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
3254
118k
   png_const_bytep sp = png_ptr->row_buf + 1;
3255
118k
   png_alloc_size_t row_width = png_ptr->width;
3256
118k
   unsigned int pass = png_ptr->pass;
3257
118k
   png_bytep end_ptr = 0;
3258
118k
   png_byte end_byte = 0;
3259
118k
   unsigned int end_mask;
3260
3261
118k
   png_debug(1, "in png_combine_row");
3262
3263
   /* Added in 1.5.6: it should not be possible to enter this routine until at
3264
    * least one row has been read from the PNG data and transformed.
3265
    */
3266
118k
   if (pixel_depth == 0)
3267
0
      png_error(png_ptr, "internal row logic error");
3268
3269
   /* Added in 1.5.4: the pixel depth should match the information returned by
3270
    * any call to png_read_update_info at this point.  Do not continue if we got
3271
    * this wrong.
3272
    */
3273
118k
   if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
3274
118k
          PNG_ROWBYTES(pixel_depth, row_width))
3275
0
      png_error(png_ptr, "internal row size calculation error");
3276
3277
   /* Don't expect this to ever happen: */
3278
118k
   if (row_width == 0)
3279
0
      png_error(png_ptr, "internal row width error");
3280
3281
   /* Preserve the last byte in cases where only part of it will be overwritten,
3282
    * the multiply below may overflow, we don't care because ANSI-C guarantees
3283
    * we get the low bits.
3284
    */
3285
118k
   end_mask = (pixel_depth * row_width) & 7;
3286
118k
   if (end_mask != 0)
3287
0
   {
3288
      /* end_ptr == NULL is a flag to say do nothing */
3289
0
      end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
3290
0
      end_byte = *end_ptr;
3291
0
#     ifdef PNG_READ_PACKSWAP_SUPPORTED
3292
0
      if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
3293
         /* little-endian byte */
3294
0
         end_mask = (unsigned int)(0xff << end_mask);
3295
3296
0
      else /* big-endian byte */
3297
0
#     endif
3298
0
      end_mask = 0xff >> end_mask;
3299
      /* end_mask is now the bits to *keep* from the destination row */
3300
0
   }
3301
3302
   /* For non-interlaced images this reduces to a memcpy(). A memcpy()
3303
    * will also happen if interlacing isn't supported or if the application
3304
    * does not call png_set_interlace_handling().  In the latter cases the
3305
    * caller just gets a sequence of the unexpanded rows from each interlace
3306
    * pass.
3307
    */
3308
118k
#ifdef PNG_READ_INTERLACING_SUPPORTED
3309
118k
   if (png_ptr->interlaced != 0 &&
3310
118k
       (png_ptr->transformations & PNG_INTERLACE) != 0 &&
3311
118k
       pass < 6 && (display == 0 ||
3312
       /* The following copies everything for 'display' on passes 0, 2 and 4. */
3313
46.4k
       (display == 1 && (pass & 1) != 0)))
3314
46.4k
   {
3315
      /* Narrow images may have no bits in a pass; the caller should handle
3316
       * this, but this test is cheap:
3317
       */
3318
46.4k
      if (row_width <= PNG_PASS_START_COL(pass))
3319
0
         return;
3320
3321
46.4k
      if (pixel_depth < 8)
3322
0
      {
3323
         /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
3324
          * into 32 bits, then a single loop over the bytes using the four byte
3325
          * values in the 32-bit mask can be used.  For the 'display' option the
3326
          * expanded mask may also not require any masking within a byte.  To
3327
          * make this work the PACKSWAP option must be taken into account - it
3328
          * simply requires the pixels to be reversed in each byte.
3329
          *
3330
          * The 'regular' case requires a mask for each of the first 6 passes,
3331
          * the 'display' case does a copy for the even passes in the range
3332
          * 0..6.  This has already been handled in the test above.
3333
          *
3334
          * The masks are arranged as four bytes with the first byte to use in
3335
          * the lowest bits (little-endian) regardless of the order (PACKSWAP or
3336
          * not) of the pixels in each byte.
3337
          *
3338
          * NOTE: the whole of this logic depends on the caller of this function
3339
          * only calling it on rows appropriate to the pass.  This function only
3340
          * understands the 'x' logic; the 'y' logic is handled by the caller.
3341
          *
3342
          * The following defines allow generation of compile time constant bit
3343
          * masks for each pixel depth and each possibility of swapped or not
3344
          * swapped bytes.  Pass 'p' is in the range 0..6; 'x', a pixel index,
3345
          * is in the range 0..7; and the result is 1 if the pixel is to be
3346
          * copied in the pass, 0 if not.  'S' is for the sparkle method, 'B'
3347
          * for the block method.
3348
          *
3349
          * With some compilers a compile time expression of the general form:
3350
          *
3351
          *    (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
3352
          *
3353
          * Produces warnings with values of 'shift' in the range 33 to 63
3354
          * because the right hand side of the ?: expression is evaluated by
3355
          * the compiler even though it isn't used.  Microsoft Visual C (various
3356
          * versions) and the Intel C compiler are known to do this.  To avoid
3357
          * this the following macros are used in 1.5.6.  This is a temporary
3358
          * solution to avoid destabilizing the code during the release process.
3359
          */
3360
0
#        if PNG_USE_COMPILE_TIME_MASKS
3361
0
#           define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
3362
0
#           define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
3363
#        else
3364
#           define PNG_LSR(x,s) ((x)>>(s))
3365
#           define PNG_LSL(x,s) ((x)<<(s))
3366
#        endif
3367
0
#        define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
3368
0
           PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
3369
0
#        define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
3370
0
           PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
3371
3372
         /* Return a mask for pass 'p' pixel 'x' at depth 'd'.  The mask is
3373
          * little endian - the first pixel is at bit 0 - however the extra
3374
          * parameter 's' can be set to cause the mask position to be swapped
3375
          * within each byte, to match the PNG format.  This is done by XOR of
3376
          * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
3377
          */
3378
0
#        define PIXEL_MASK(p,x,d,s) \
3379
0
            (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
3380
3381
         /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
3382
          */
3383
0
#        define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
3384
0
#        define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
3385
3386
         /* Combine 8 of these to get the full mask.  For the 1-bpp and 2-bpp
3387
          * cases the result needs replicating, for the 4-bpp case the above
3388
          * generates a full 32 bits.
3389
          */
3390
0
#        define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
3391
3392
0
#        define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
3393
0
            S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
3394
0
            S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
3395
3396
0
#        define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
3397
0
            B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
3398
0
            B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
3399
3400
0
#if PNG_USE_COMPILE_TIME_MASKS
3401
         /* Utility macros to construct all the masks for a depth/swap
3402
          * combination.  The 's' parameter says whether the format is PNG
3403
          * (big endian bytes) or not.  Only the three odd-numbered passes are
3404
          * required for the display/block algorithm.
3405
          */
3406
0
#        define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
3407
0
            S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
3408
3409
0
#        define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) }
3410
3411
0
#        define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
3412
3413
         /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
3414
          * then pass:
3415
          */
3416
0
         static const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
3417
0
         {
3418
            /* Little-endian byte masks for PACKSWAP */
3419
0
            { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
3420
            /* Normal (big-endian byte) masks - PNG format */
3421
0
            { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
3422
0
         };
3423
3424
         /* display_mask has only three entries for the odd passes, so index by
3425
          * pass>>1.
3426
          */
3427
0
         static const png_uint_32 display_mask[2][3][3] =
3428
0
         {
3429
            /* Little-endian byte masks for PACKSWAP */
3430
0
            { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
3431
            /* Normal (big-endian byte) masks - PNG format */
3432
0
            { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
3433
0
         };
3434
3435
0
#        define MASK(pass,depth,display,png)\
3436
0
            ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
3437
0
               row_mask[png][DEPTH_INDEX(depth)][pass])
3438
3439
#else /* !PNG_USE_COMPILE_TIME_MASKS */
3440
         /* This is the runtime alternative: it seems unlikely that this will
3441
          * ever be either smaller or faster than the compile time approach.
3442
          */
3443
#        define MASK(pass,depth,display,png)\
3444
            ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
3445
#endif /* !USE_COMPILE_TIME_MASKS */
3446
3447
         /* Use the appropriate mask to copy the required bits.  In some cases
3448
          * the byte mask will be 0 or 0xff; optimize these cases.  row_width is
3449
          * the number of pixels, but the code copies bytes, so it is necessary
3450
          * to special case the end.
3451
          */
3452
0
         png_uint_32 pixels_per_byte = 8 / pixel_depth;
3453
0
         png_uint_32 mask;
3454
3455
0
#        ifdef PNG_READ_PACKSWAP_SUPPORTED
3456
0
         if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
3457
0
            mask = MASK(pass, pixel_depth, display, 0);
3458
3459
0
         else
3460
0
#        endif
3461
0
         mask = MASK(pass, pixel_depth, display, 1);
3462
3463
0
         for (;;)
3464
0
         {
3465
0
            png_uint_32 m;
3466
3467
            /* It doesn't matter in the following if png_uint_32 has more than
3468
             * 32 bits because the high bits always match those in m<<24; it is,
3469
             * however, essential to use OR here, not +, because of this.
3470
             */
3471
0
            m = mask;
3472
0
            mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
3473
0
            m &= 0xff;
3474
3475
0
            if (m != 0) /* something to copy */
3476
0
            {
3477
0
               if (m != 0xff)
3478
0
                  *dp = (png_byte)((*dp & ~m) | (*sp & m));
3479
0
               else
3480
0
                  *dp = *sp;
3481
0
            }
3482
3483
            /* NOTE: this may overwrite the last byte with garbage if the image
3484
             * is not an exact number of bytes wide; libpng has always done
3485
             * this.
3486
             */
3487
0
            if (row_width <= pixels_per_byte)
3488
0
               break; /* May need to restore part of the last byte */
3489
3490
0
            row_width -= pixels_per_byte;
3491
0
            ++dp;
3492
0
            ++sp;
3493
0
         }
3494
0
      }
3495
3496
46.4k
      else /* pixel_depth >= 8 */
3497
46.4k
      {
3498
46.4k
         unsigned int bytes_to_copy, bytes_to_jump;
3499
3500
         /* Validate the depth - it must be a multiple of 8 */
3501
46.4k
         if (pixel_depth & 7)
3502
0
            png_error(png_ptr, "invalid user transform pixel depth");
3503
3504
46.4k
         pixel_depth >>= 3; /* now in bytes */
3505
46.4k
         row_width *= pixel_depth;
3506
3507
         /* Regardless of pass number the Adam 7 interlace always results in a
3508
          * fixed number of pixels to copy then to skip.  There may be a
3509
          * different number of pixels to skip at the start though.
3510
          */
3511
46.4k
         {
3512
46.4k
            unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
3513
3514
46.4k
            row_width -= offset;
3515
46.4k
            dp += offset;
3516
46.4k
            sp += offset;
3517
46.4k
         }
3518
3519
         /* Work out the bytes to copy. */
3520
46.4k
         if (display != 0)
3521
0
         {
3522
            /* When doing the 'block' algorithm the pixel in the pass gets
3523
             * replicated to adjacent pixels.  This is why the even (0,2,4,6)
3524
             * passes are skipped above - the entire expanded row is copied.
3525
             */
3526
0
            bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
3527
3528
            /* But don't allow this number to exceed the actual row width. */
3529
0
            if (bytes_to_copy > row_width)
3530
0
               bytes_to_copy = (unsigned int)/*SAFE*/row_width;
3531
0
         }
3532
3533
46.4k
         else /* normal row; Adam7 only ever gives us one pixel to copy. */
3534
46.4k
            bytes_to_copy = pixel_depth;
3535
3536
         /* In Adam7 there is a constant offset between where the pixels go. */
3537
46.4k
         bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
3538
3539
         /* And simply copy these bytes.  Some optimization is possible here,
3540
          * depending on the value of 'bytes_to_copy'.  Special case the low
3541
          * byte counts, which we know to be frequent.
3542
          *
3543
          * Notice that these cases all 'return' rather than 'break' - this
3544
          * avoids an unnecessary test on whether to restore the last byte
3545
          * below.
3546
          */
3547
46.4k
         switch (bytes_to_copy)
3548
46.4k
         {
3549
0
            case 1:
3550
0
               for (;;)
3551
0
               {
3552
0
                  *dp = *sp;
3553
3554
0
                  if (row_width <= bytes_to_jump)
3555
0
                     return;
3556
3557
0
                  dp += bytes_to_jump;
3558
0
                  sp += bytes_to_jump;
3559
0
                  row_width -= bytes_to_jump;
3560
0
               }
3561
3562
0
            case 2:
3563
               /* There is a possibility of a partial copy at the end here; this
3564
                * slows the code down somewhat.
3565
                */
3566
0
               do
3567
0
               {
3568
0
                  dp[0] = sp[0]; dp[1] = sp[1];
3569
3570
0
                  if (row_width <= bytes_to_jump)
3571
0
                     return;
3572
3573
0
                  sp += bytes_to_jump;
3574
0
                  dp += bytes_to_jump;
3575
0
                  row_width -= bytes_to_jump;
3576
0
               }
3577
0
               while (row_width > 1);
3578
3579
               /* And there can only be one byte left at this point: */
3580
0
               *dp = *sp;
3581
0
               return;
3582
3583
27.1k
            case 3:
3584
               /* This can only be the RGB case, so each copy is exactly one
3585
                * pixel and it is not necessary to check for a partial copy.
3586
                */
3587
27.1k
               for (;;)
3588
51.9k
               {
3589
51.9k
                  dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2];
3590
3591
51.9k
                  if (row_width <= bytes_to_jump)
3592
27.1k
                     return;
3593
3594
24.7k
                  sp += bytes_to_jump;
3595
24.7k
                  dp += bytes_to_jump;
3596
24.7k
                  row_width -= bytes_to_jump;
3597
24.7k
               }
3598
3599
19.2k
            default:
3600
19.2k
#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
3601
               /* Check for double byte alignment and, if possible, use a
3602
                * 16-bit copy.  Don't attempt this for narrow images - ones that
3603
                * are less than an interlace panel wide.  Don't attempt it for
3604
                * wide bytes_to_copy either - use the memcpy there.
3605
                */
3606
19.2k
               if (bytes_to_copy < 16 /*else use memcpy*/ &&
3607
19.2k
                   png_isaligned(dp, png_uint_16) &&
3608
19.2k
                   png_isaligned(sp, png_uint_16) &&
3609
19.2k
                   bytes_to_copy % (sizeof (png_uint_16)) == 0 &&
3610
19.2k
                   bytes_to_jump % (sizeof (png_uint_16)) == 0)
3611
19.2k
               {
3612
                  /* Everything is aligned for png_uint_16 copies, but try for
3613
                   * png_uint_32 first.
3614
                   */
3615
19.2k
                  if (png_isaligned(dp, png_uint_32) &&
3616
19.2k
                      png_isaligned(sp, png_uint_32) &&
3617
19.2k
                      bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
3618
19.2k
                      bytes_to_jump % (sizeof (png_uint_32)) == 0)
3619
19.2k
                  {
3620
19.2k
                     png_uint_32p dp32 = png_aligncast(png_uint_32p,dp);
3621
19.2k
                     png_const_uint_32p sp32 = png_aligncastconst(
3622
19.2k
                         png_const_uint_32p, sp);
3623
19.2k
                     size_t skip = (bytes_to_jump-bytes_to_copy) /
3624
19.2k
                         (sizeof (png_uint_32));
3625
3626
19.2k
                     do
3627
616k
                     {
3628
616k
                        size_t c = bytes_to_copy;
3629
616k
                        do
3630
616k
                        {
3631
616k
                           *dp32++ = *sp32++;
3632
616k
                           c -= (sizeof (png_uint_32));
3633
616k
                        }
3634
616k
                        while (c > 0);
3635
3636
616k
                        if (row_width <= bytes_to_jump)
3637
19.2k
                           return;
3638
3639
597k
                        dp32 += skip;
3640
597k
                        sp32 += skip;
3641
597k
                        row_width -= bytes_to_jump;
3642
597k
                     }
3643
597k
                     while (bytes_to_copy <= row_width);
3644
3645
                     /* Get to here when the row_width truncates the final copy.
3646
                      * There will be 1-3 bytes left to copy, so don't try the
3647
                      * 16-bit loop below.
3648
                      */
3649
0
                     dp = (png_bytep)dp32;
3650
0
                     sp = (png_const_bytep)sp32;
3651
0
                     do
3652
0
                        *dp++ = *sp++;
3653
0
                     while (--row_width > 0);
3654
0
                     return;
3655
19.2k
                  }
3656
3657
                  /* Else do it in 16-bit quantities, but only if the size is
3658
                   * not too large.
3659
                   */
3660
0
                  else
3661
0
                  {
3662
0
                     png_uint_16p dp16 = png_aligncast(png_uint_16p, dp);
3663
0
                     png_const_uint_16p sp16 = png_aligncastconst(
3664
0
                        png_const_uint_16p, sp);
3665
0
                     size_t skip = (bytes_to_jump-bytes_to_copy) /
3666
0
                        (sizeof (png_uint_16));
3667
3668
0
                     do
3669
0
                     {
3670
0
                        size_t c = bytes_to_copy;
3671
0
                        do
3672
0
                        {
3673
0
                           *dp16++ = *sp16++;
3674
0
                           c -= (sizeof (png_uint_16));
3675
0
                        }
3676
0
                        while (c > 0);
3677
3678
0
                        if (row_width <= bytes_to_jump)
3679
0
                           return;
3680
3681
0
                        dp16 += skip;
3682
0
                        sp16 += skip;
3683
0
                        row_width -= bytes_to_jump;
3684
0
                     }
3685
0
                     while (bytes_to_copy <= row_width);
3686
3687
                     /* End of row - 1 byte left, bytes_to_copy > row_width: */
3688
0
                     dp = (png_bytep)dp16;
3689
0
                     sp = (png_const_bytep)sp16;
3690
0
                     do
3691
0
                        *dp++ = *sp++;
3692
0
                     while (--row_width > 0);
3693
0
                     return;
3694
0
                  }
3695
19.2k
               }
3696
0
#endif /* ALIGN_TYPE code */
3697
3698
               /* The true default - use a memcpy: */
3699
0
               for (;;)
3700
0
               {
3701
0
                  memcpy(dp, sp, bytes_to_copy);
3702
3703
0
                  if (row_width <= bytes_to_jump)
3704
0
                     return;
3705
3706
0
                  sp += bytes_to_jump;
3707
0
                  dp += bytes_to_jump;
3708
0
                  row_width -= bytes_to_jump;
3709
0
                  if (bytes_to_copy > row_width)
3710
0
                     bytes_to_copy = (unsigned int)/*SAFE*/row_width;
3711
0
               }
3712
46.4k
         }
3713
3714
         /* NOT REACHED*/
3715
46.4k
      } /* pixel_depth >= 8 */
3716
3717
      /* Here if pixel_depth < 8 to check 'end_ptr' below. */
3718
46.4k
   }
3719
71.8k
   else
3720
71.8k
#endif /* READ_INTERLACING */
3721
3722
   /* If here then the switch above wasn't used so just memcpy the whole row
3723
    * from the temporary row buffer (notice that this overwrites the end of the
3724
    * destination row if it is a partial byte.)
3725
    */
3726
71.8k
   memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
3727
3728
   /* Restore the overwritten bits from the last byte if necessary. */
3729
71.8k
   if (end_ptr != NULL)
3730
0
      *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
3731
71.8k
}
3732
3733
#ifdef PNG_READ_INTERLACING_SUPPORTED
3734
void /* PRIVATE */
3735
png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
3736
    png_uint_32 transformations /* Because these may affect the byte layout */)
3737
46.4k
{
3738
46.4k
   png_debug(1, "in png_do_read_interlace");
3739
46.4k
   if (row != NULL && row_info != NULL)
3740
46.4k
   {
3741
46.4k
      png_uint_32 final_width;
3742
3743
46.4k
      final_width = row_info->width * png_pass_inc[pass];
3744
3745
46.4k
      switch (row_info->pixel_depth)
3746
46.4k
      {
3747
0
         case 1:
3748
0
         {
3749
0
            png_bytep sp = row + (size_t)((row_info->width - 1) >> 3);
3750
0
            png_bytep dp = row + (size_t)((final_width - 1) >> 3);
3751
0
            unsigned int sshift, dshift;
3752
0
            unsigned int s_start, s_end;
3753
0
            int s_inc;
3754
0
            int jstop = (int)png_pass_inc[pass];
3755
0
            png_byte v;
3756
0
            png_uint_32 i;
3757
0
            int j;
3758
3759
0
#ifdef PNG_READ_PACKSWAP_SUPPORTED
3760
0
            if ((transformations & PNG_PACKSWAP) != 0)
3761
0
            {
3762
0
                sshift = ((row_info->width + 7) & 0x07);
3763
0
                dshift = ((final_width + 7) & 0x07);
3764
0
                s_start = 7;
3765
0
                s_end = 0;
3766
0
                s_inc = -1;
3767
0
            }
3768
3769
0
            else
3770
0
#endif
3771
0
            {
3772
0
                sshift = 7 - ((row_info->width + 7) & 0x07);
3773
0
                dshift = 7 - ((final_width + 7) & 0x07);
3774
0
                s_start = 0;
3775
0
                s_end = 7;
3776
0
                s_inc = 1;
3777
0
            }
3778
3779
0
            for (i = 0; i < row_info->width; i++)
3780
0
            {
3781
0
               v = (png_byte)((*sp >> sshift) & 0x01);
3782
0
               for (j = 0; j < jstop; j++)
3783
0
               {
3784
0
                  unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
3785
0
                  tmp |= (unsigned int)(v << dshift);
3786
0
                  *dp = (png_byte)(tmp & 0xff);
3787
3788
0
                  if (dshift == s_end)
3789
0
                  {
3790
0
                     dshift = s_start;
3791
0
                     dp--;
3792
0
                  }
3793
3794
0
                  else
3795
0
                     dshift = (unsigned int)((int)dshift + s_inc);
3796
0
               }
3797
3798
0
               if (sshift == s_end)
3799
0
               {
3800
0
                  sshift = s_start;
3801
0
                  sp--;
3802
0
               }
3803
3804
0
               else
3805
0
                  sshift = (unsigned int)((int)sshift + s_inc);
3806
0
            }
3807
0
            break;
3808
0
         }
3809
3810
0
         case 2:
3811
0
         {
3812
0
            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
3813
0
            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
3814
0
            unsigned int sshift, dshift;
3815
0
            unsigned int s_start, s_end;
3816
0
            int s_inc;
3817
0
            int jstop = (int)png_pass_inc[pass];
3818
0
            png_uint_32 i;
3819
3820
0
#ifdef PNG_READ_PACKSWAP_SUPPORTED
3821
0
            if ((transformations & PNG_PACKSWAP) != 0)
3822
0
            {
3823
0
               sshift = (((row_info->width + 3) & 0x03) << 1);
3824
0
               dshift = (((final_width + 3) & 0x03) << 1);
3825
0
               s_start = 6;
3826
0
               s_end = 0;
3827
0
               s_inc = -2;
3828
0
            }
3829
3830
0
            else
3831
0
#endif
3832
0
            {
3833
0
               sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1);
3834
0
               dshift = ((3 - ((final_width + 3) & 0x03)) << 1);
3835
0
               s_start = 0;
3836
0
               s_end = 6;
3837
0
               s_inc = 2;
3838
0
            }
3839
3840
0
            for (i = 0; i < row_info->width; i++)
3841
0
            {
3842
0
               png_byte v;
3843
0
               int j;
3844
3845
0
               v = (png_byte)((*sp >> sshift) & 0x03);
3846
0
               for (j = 0; j < jstop; j++)
3847
0
               {
3848
0
                  unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
3849
0
                  tmp |= (unsigned int)(v << dshift);
3850
0
                  *dp = (png_byte)(tmp & 0xff);
3851
3852
0
                  if (dshift == s_end)
3853
0
                  {
3854
0
                     dshift = s_start;
3855
0
                     dp--;
3856
0
                  }
3857
3858
0
                  else
3859
0
                     dshift = (unsigned int)((int)dshift + s_inc);
3860
0
               }
3861
3862
0
               if (sshift == s_end)
3863
0
               {
3864
0
                  sshift = s_start;
3865
0
                  sp--;
3866
0
               }
3867
3868
0
               else
3869
0
                  sshift = (unsigned int)((int)sshift + s_inc);
3870
0
            }
3871
0
            break;
3872
0
         }
3873
3874
0
         case 4:
3875
0
         {
3876
0
            png_bytep sp = row + (size_t)((row_info->width - 1) >> 1);
3877
0
            png_bytep dp = row + (size_t)((final_width - 1) >> 1);
3878
0
            unsigned int sshift, dshift;
3879
0
            unsigned int s_start, s_end;
3880
0
            int s_inc;
3881
0
            png_uint_32 i;
3882
0
            int jstop = (int)png_pass_inc[pass];
3883
3884
0
#ifdef PNG_READ_PACKSWAP_SUPPORTED
3885
0
            if ((transformations & PNG_PACKSWAP) != 0)
3886
0
            {
3887
0
               sshift = (((row_info->width + 1) & 0x01) << 2);
3888
0
               dshift = (((final_width + 1) & 0x01) << 2);
3889
0
               s_start = 4;
3890
0
               s_end = 0;
3891
0
               s_inc = -4;
3892
0
            }
3893
3894
0
            else
3895
0
#endif
3896
0
            {
3897
0
               sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2);
3898
0
               dshift = ((1 - ((final_width + 1) & 0x01)) << 2);
3899
0
               s_start = 0;
3900
0
               s_end = 4;
3901
0
               s_inc = 4;
3902
0
            }
3903
3904
0
            for (i = 0; i < row_info->width; i++)
3905
0
            {
3906
0
               png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
3907
0
               int j;
3908
3909
0
               for (j = 0; j < jstop; j++)
3910
0
               {
3911
0
                  unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
3912
0
                  tmp |= (unsigned int)(v << dshift);
3913
0
                  *dp = (png_byte)(tmp & 0xff);
3914
3915
0
                  if (dshift == s_end)
3916
0
                  {
3917
0
                     dshift = s_start;
3918
0
                     dp--;
3919
0
                  }
3920
3921
0
                  else
3922
0
                     dshift = (unsigned int)((int)dshift + s_inc);
3923
0
               }
3924
3925
0
               if (sshift == s_end)
3926
0
               {
3927
0
                  sshift = s_start;
3928
0
                  sp--;
3929
0
               }
3930
3931
0
               else
3932
0
                  sshift = (unsigned int)((int)sshift + s_inc);
3933
0
            }
3934
0
            break;
3935
0
         }
3936
3937
46.4k
         default:
3938
46.4k
         {
3939
46.4k
            size_t pixel_bytes = (row_info->pixel_depth >> 3);
3940
3941
46.4k
            png_bytep sp = row + (size_t)(row_info->width - 1)
3942
46.4k
                * pixel_bytes;
3943
3944
46.4k
            png_bytep dp = row + (size_t)(final_width - 1) * pixel_bytes;
3945
3946
46.4k
            int jstop = (int)png_pass_inc[pass];
3947
46.4k
            png_uint_32 i;
3948
3949
715k
            for (i = 0; i < row_info->width; i++)
3950
668k
            {
3951
668k
               png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */
3952
668k
               int j;
3953
3954
668k
               memcpy(v, sp, pixel_bytes);
3955
3956
2.70M
               for (j = 0; j < jstop; j++)
3957
2.03M
               {
3958
2.03M
                  memcpy(dp, v, pixel_bytes);
3959
2.03M
                  dp -= pixel_bytes;
3960
2.03M
               }
3961
3962
668k
               sp -= pixel_bytes;
3963
668k
            }
3964
46.4k
            break;
3965
0
         }
3966
46.4k
      }
3967
3968
46.4k
      row_info->width = final_width;
3969
46.4k
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
3970
46.4k
   }
3971
#ifndef PNG_READ_PACKSWAP_SUPPORTED
3972
   PNG_UNUSED(transformations)  /* Silence compiler warning */
3973
#endif
3974
46.4k
}
3975
#endif /* READ_INTERLACING */
3976
3977
static void
3978
png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
3979
    png_const_bytep prev_row)
3980
11.2k
{
3981
11.2k
   size_t i;
3982
11.2k
   size_t istop = row_info->rowbytes;
3983
11.2k
   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
3984
11.2k
   png_bytep rp = row + bpp;
3985
3986
11.2k
   PNG_UNUSED(prev_row)
3987
3988
1.34M
   for (i = bpp; i < istop; i++)
3989
1.33M
   {
3990
1.33M
      *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
3991
1.33M
      rp++;
3992
1.33M
   }
3993
11.2k
}
3994
3995
static void
3996
png_read_filter_row_up(png_row_infop row_info, png_bytep row,
3997
    png_const_bytep prev_row)
3998
44.3k
{
3999
44.3k
   size_t i;
4000
44.3k
   size_t istop = row_info->rowbytes;
4001
44.3k
   png_bytep rp = row;
4002
44.3k
   png_const_bytep pp = prev_row;
4003
4004
26.9M
   for (i = 0; i < istop; i++)
4005
26.8M
   {
4006
26.8M
      *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
4007
26.8M
      rp++;
4008
26.8M
   }
4009
44.3k
}
4010
4011
static void
4012
png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
4013
    png_const_bytep prev_row)
4014
1.88k
{
4015
1.88k
   size_t i;
4016
1.88k
   png_bytep rp = row;
4017
1.88k
   png_const_bytep pp = prev_row;
4018
1.88k
   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
4019
1.88k
   size_t istop = row_info->rowbytes - bpp;
4020
4021
8.48k
   for (i = 0; i < bpp; i++)
4022
6.59k
   {
4023
6.59k
      *rp = (png_byte)(((int)(*rp) +
4024
6.59k
         ((int)(*pp++) / 2 )) & 0xff);
4025
4026
6.59k
      rp++;
4027
6.59k
   }
4028
4029
557k
   for (i = 0; i < istop; i++)
4030
555k
   {
4031
555k
      *rp = (png_byte)(((int)(*rp) +
4032
555k
         (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
4033
4034
555k
      rp++;
4035
555k
   }
4036
1.88k
}
4037
4038
static void
4039
png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
4040
    png_const_bytep prev_row)
4041
1.53k
{
4042
1.53k
   png_bytep rp_end = row + row_info->rowbytes;
4043
1.53k
   int a, c;
4044
4045
   /* First pixel/byte */
4046
1.53k
   c = *prev_row++;
4047
1.53k
   a = *row + c;
4048
1.53k
   *row++ = (png_byte)a;
4049
4050
   /* Remainder */
4051
44.4k
   while (row < rp_end)
4052
42.9k
   {
4053
42.9k
      int b, pa, pb, pc, p;
4054
4055
42.9k
      a &= 0xff; /* From previous iteration or start */
4056
42.9k
      b = *prev_row++;
4057
4058
42.9k
      p = b - c;
4059
42.9k
      pc = a - c;
4060
4061
#ifdef PNG_USE_ABS
4062
      pa = abs(p);
4063
      pb = abs(pc);
4064
      pc = abs(p + pc);
4065
#else
4066
42.9k
      pa = p < 0 ? -p : p;
4067
42.9k
      pb = pc < 0 ? -pc : pc;
4068
42.9k
      pc = (p + pc) < 0 ? -(p + pc) : p + pc;
4069
42.9k
#endif
4070
4071
      /* Find the best predictor, the least of pa, pb, pc favoring the earlier
4072
       * ones in the case of a tie.
4073
       */
4074
42.9k
      if (pb < pa)
4075
3.79k
      {
4076
3.79k
         pa = pb; a = b;
4077
3.79k
      }
4078
42.9k
      if (pc < pa) a = c;
4079
4080
      /* Calculate the current pixel in a, and move the previous row pixel to c
4081
       * for the next time round the loop
4082
       */
4083
42.9k
      c = b;
4084
42.9k
      a += *row;
4085
42.9k
      *row++ = (png_byte)a;
4086
42.9k
   }
4087
1.53k
}
4088
4089
static void
4090
png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
4091
    png_const_bytep prev_row)
4092
7.44k
{
4093
7.44k
   unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
4094
7.44k
   png_bytep rp_end = row + bpp;
4095
4096
   /* Process the first pixel in the row completely (this is the same as 'up'
4097
    * because there is only one candidate predictor for the first row).
4098
    */
4099
38.9k
   while (row < rp_end)
4100
31.4k
   {
4101
31.4k
      int a = *row + *prev_row++;
4102
31.4k
      *row++ = (png_byte)a;
4103
31.4k
   }
4104
4105
   /* Remainder */
4106
7.44k
   rp_end = rp_end + (row_info->rowbytes - bpp);
4107
4108
1.93M
   while (row < rp_end)
4109
1.92M
   {
4110
1.92M
      int a, b, c, pa, pb, pc, p;
4111
4112
1.92M
      c = *(prev_row - bpp);
4113
1.92M
      a = *(row - bpp);
4114
1.92M
      b = *prev_row++;
4115
4116
1.92M
      p = b - c;
4117
1.92M
      pc = a - c;
4118
4119
#ifdef PNG_USE_ABS
4120
      pa = abs(p);
4121
      pb = abs(pc);
4122
      pc = abs(p + pc);
4123
#else
4124
1.92M
      pa = p < 0 ? -p : p;
4125
1.92M
      pb = pc < 0 ? -pc : pc;
4126
1.92M
      pc = (p + pc) < 0 ? -(p + pc) : p + pc;
4127
1.92M
#endif
4128
4129
1.92M
      if (pb < pa)
4130
435k
      {
4131
435k
         pa = pb; a = b;
4132
435k
      }
4133
1.92M
      if (pc < pa) a = c;
4134
4135
1.92M
      a += *row;
4136
1.92M
      *row++ = (png_byte)a;
4137
1.92M
   }
4138
7.44k
}
4139
4140
static void
4141
png_init_filter_functions(png_structrp pp)
4142
   /* This function is called once for every PNG image (except for PNG images
4143
    * that only use PNG_FILTER_VALUE_NONE for all rows) to set the
4144
    * implementations required to reverse the filtering of PNG rows.  Reversing
4145
    * the filter is the first transformation performed on the row data.  It is
4146
    * performed in place, therefore an implementation can be selected based on
4147
    * the image pixel format.  If the implementation depends on image width then
4148
    * take care to ensure that it works correctly if the image is interlaced -
4149
    * interlacing causes the actual row width to vary.
4150
    */
4151
814
{
4152
814
   unsigned int bpp = (pp->pixel_depth + 7) >> 3;
4153
4154
814
   pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
4155
814
   pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
4156
814
   pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
4157
814
   if (bpp == 1)
4158
357
      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
4159
357
         png_read_filter_row_paeth_1byte_pixel;
4160
457
   else
4161
457
      pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
4162
457
         png_read_filter_row_paeth_multibyte_pixel;
4163
4164
#ifdef PNG_FILTER_OPTIMIZATIONS
4165
   /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to
4166
    * call to install hardware optimizations for the above functions; simply
4167
    * replace whatever elements of the pp->read_filter[] array with a hardware
4168
    * specific (or, for that matter, generic) optimization.
4169
    *
4170
    * To see an example of this examine what configure.ac does when
4171
    * --enable-arm-neon is specified on the command line.
4172
    */
4173
   PNG_FILTER_OPTIMIZATIONS(pp, bpp);
4174
#endif
4175
814
}
4176
4177
void /* PRIVATE */
4178
png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
4179
    png_const_bytep prev_row, int filter)
4180
66.4k
{
4181
   /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
4182
    * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
4183
    * implementations.  See png_init_filter_functions above.
4184
    */
4185
66.4k
   if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
4186
66.4k
   {
4187
66.4k
      if (pp->read_filter[0] == NULL)
4188
814
         png_init_filter_functions(pp);
4189
4190
66.4k
      pp->read_filter[filter-1](row_info, row, prev_row);
4191
66.4k
   }
4192
66.4k
}
4193
4194
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
4195
void /* PRIVATE */
4196
png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
4197
    png_alloc_size_t avail_out)
4198
118k
{
4199
   /* Loop reading IDATs and decompressing the result into output[avail_out] */
4200
118k
   png_ptr->zstream.next_out = output;
4201
118k
   png_ptr->zstream.avail_out = 0; /* safety: set below */
4202
4203
118k
   if (output == NULL)
4204
308
      avail_out = 0;
4205
4206
118k
   do
4207
134k
   {
4208
134k
      int ret;
4209
134k
      png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
4210
4211
134k
      if (png_ptr->zstream.avail_in == 0)
4212
1.42k
      {
4213
1.42k
         uInt avail_in;
4214
1.42k
         png_bytep buffer;
4215
4216
1.46k
         while (png_ptr->idat_size == 0)
4217
38
         {
4218
38
            png_crc_finish(png_ptr, 0);
4219
4220
38
            png_ptr->idat_size = png_read_chunk_header(png_ptr);
4221
            /* This is an error even in the 'check' case because the code just
4222
             * consumed a non-IDAT header.
4223
             */
4224
38
            if (png_ptr->chunk_name != png_IDAT)
4225
1
               png_error(png_ptr, "Not enough image data");
4226
38
         }
4227
4228
1.42k
         avail_in = png_ptr->IDAT_read_size;
4229
4230
1.42k
         if (avail_in > png_chunk_max(png_ptr))
4231
0
            avail_in = (uInt)/*SAFE*/png_chunk_max(png_ptr);
4232
4233
1.42k
         if (avail_in > png_ptr->idat_size)
4234
1.36k
            avail_in = (uInt)png_ptr->idat_size;
4235
4236
         /* A PNG with a gradually increasing IDAT size will defeat this attempt
4237
          * to minimize memory usage by causing lots of re-allocs, but
4238
          * realistically doing IDAT_read_size re-allocs is not likely to be a
4239
          * big problem.
4240
          *
4241
          * An error here corresponds to the system being out of memory.
4242
          */
4243
1.42k
         buffer = png_read_buffer(png_ptr, avail_in);
4244
4245
1.42k
         if (buffer == NULL)
4246
0
            png_chunk_error(png_ptr, "out of memory");
4247
4248
1.42k
         png_crc_read(png_ptr, buffer, avail_in);
4249
1.42k
         png_ptr->idat_size -= avail_in;
4250
4251
1.42k
         png_ptr->zstream.next_in = buffer;
4252
1.42k
         png_ptr->zstream.avail_in = avail_in;
4253
1.42k
      }
4254
4255
      /* And set up the output side. */
4256
134k
      if (output != NULL) /* standard read */
4257
118k
      {
4258
118k
         uInt out = ZLIB_IO_MAX;
4259
4260
118k
         if (out > avail_out)
4261
118k
            out = (uInt)avail_out;
4262
4263
118k
         avail_out -= out;
4264
118k
         png_ptr->zstream.avail_out = out;
4265
118k
      }
4266
4267
15.9k
      else /* after last row, checking for end */
4268
15.9k
      {
4269
15.9k
         png_ptr->zstream.next_out = tmpbuf;
4270
15.9k
         png_ptr->zstream.avail_out = (sizeof tmpbuf);
4271
15.9k
      }
4272
4273
      /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the
4274
       * process.  If the LZ stream is truncated the sequential reader will
4275
       * terminally damage the stream, above, by reading the chunk header of the
4276
       * following chunk (it then exits with png_error).
4277
       *
4278
       * TODO: deal more elegantly with truncated IDAT lists.
4279
       */
4280
134k
      ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH);
4281
4282
      /* Take the unconsumed output back. */
4283
134k
      if (output != NULL)
4284
118k
         avail_out += png_ptr->zstream.avail_out;
4285
4286
15.9k
      else /* avail_out counts the extra bytes */
4287
15.9k
         avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out;
4288
4289
134k
      png_ptr->zstream.avail_out = 0;
4290
4291
134k
      if (ret == Z_STREAM_END)
4292
725
      {
4293
         /* Do this for safety; we won't read any more into this row. */
4294
725
         png_ptr->zstream.next_out = NULL;
4295
4296
725
         png_ptr->mode |= PNG_AFTER_IDAT;
4297
725
         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
4298
4299
725
         if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
4300
5
            png_chunk_benign_error(png_ptr, "Extra compressed data");
4301
725
         break;
4302
725
      }
4303
4304
133k
      if (ret != Z_OK)
4305
351
      {
4306
351
         png_zstream_error(png_ptr, ret);
4307
4308
351
         if (output != NULL)
4309
137
            png_chunk_error(png_ptr, png_ptr->zstream.msg);
4310
4311
214
         else /* checking */
4312
214
         {
4313
214
            png_chunk_benign_error(png_ptr, png_ptr->zstream.msg);
4314
214
            return;
4315
214
         }
4316
351
      }
4317
133k
   } while (avail_out > 0);
4318
4319
118k
   if (avail_out > 0)
4320
81
   {
4321
      /* The stream ended before the image; this is the same as too few IDATs so
4322
       * should be handled the same way.
4323
       */
4324
81
      if (output != NULL)
4325
2
         png_error(png_ptr, "Not enough image data");
4326
4327
79
      else /* the deflate stream contained extra data */
4328
79
         png_chunk_benign_error(png_ptr, "Too much image data");
4329
81
   }
4330
118k
}
4331
4332
void /* PRIVATE */
4333
png_read_finish_IDAT(png_structrp png_ptr)
4334
1.45k
{
4335
   /* We don't need any more data and the stream should have ended, however the
4336
    * LZ end code may actually not have been processed.  In this case we must
4337
    * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk
4338
    * may still remain to be consumed.
4339
    */
4340
1.45k
   if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
4341
308
   {
4342
      /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in
4343
       * the compressed stream, but the stream may be damaged too, so even after
4344
       * this call we may need to terminate the zstream ownership.
4345
       */
4346
308
      png_read_IDAT_data(png_ptr, NULL, 0);
4347
308
      png_ptr->zstream.next_out = NULL; /* safety */
4348
4349
      /* Now clear everything out for safety; the following may not have been
4350
       * done.
4351
       */
4352
308
      if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
4353
214
      {
4354
214
         png_ptr->mode |= PNG_AFTER_IDAT;
4355
214
         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
4356
214
      }
4357
308
   }
4358
4359
   /* If the zstream has not been released do it now *and* terminate the reading
4360
    * of the final IDAT chunk.
4361
    */
4362
1.45k
   if (png_ptr->zowner == png_IDAT)
4363
936
   {
4364
      /* Always do this; the pointers otherwise point into the read buffer. */
4365
936
      png_ptr->zstream.next_in = NULL;
4366
936
      png_ptr->zstream.avail_in = 0;
4367
4368
      /* Now we no longer own the zstream. */
4369
936
      png_ptr->zowner = 0;
4370
4371
      /* The slightly weird semantics of the sequential IDAT reading is that we
4372
       * are always in or at the end of an IDAT chunk, so we always need to do a
4373
       * crc_finish here.  If idat_size is non-zero we also need to read the
4374
       * spurious bytes at the end of the chunk now.
4375
       */
4376
936
      (void)png_crc_finish(png_ptr, png_ptr->idat_size);
4377
936
   }
4378
1.45k
}
4379
4380
void /* PRIVATE */
4381
png_read_finish_row(png_structrp png_ptr)
4382
494k
{
4383
494k
   png_debug(1, "in png_read_finish_row");
4384
494k
   png_ptr->row_number++;
4385
494k
   if (png_ptr->row_number < png_ptr->num_rows)
4386
492k
      return;
4387
4388
2.69k
   if (png_ptr->interlaced != 0)
4389
1.93k
   {
4390
1.93k
      png_ptr->row_number = 0;
4391
4392
      /* TO DO: don't do this if prev_row isn't needed (requires
4393
       * read-ahead of the next row's filter byte.
4394
       */
4395
1.93k
      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
4396
4397
1.93k
      do
4398
1.93k
      {
4399
1.93k
         png_ptr->pass++;
4400
4401
1.93k
         if (png_ptr->pass >= 7)
4402
191
            break;
4403
4404
1.73k
         png_ptr->iwidth = (png_ptr->width +
4405
1.73k
            png_pass_inc[png_ptr->pass] - 1 -
4406
1.73k
            png_pass_start[png_ptr->pass]) /
4407
1.73k
            png_pass_inc[png_ptr->pass];
4408
4409
1.73k
         if ((png_ptr->transformations & PNG_INTERLACE) == 0)
4410
0
         {
4411
0
            png_ptr->num_rows = (png_ptr->height +
4412
0
                png_pass_yinc[png_ptr->pass] - 1 -
4413
0
                png_pass_ystart[png_ptr->pass]) /
4414
0
                png_pass_yinc[png_ptr->pass];
4415
0
         }
4416
4417
1.73k
         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
4418
1.73k
            break; /* libpng deinterlacing sees every row */
4419
4420
1.73k
      } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
4421
4422
1.93k
      if (png_ptr->pass < 7)
4423
1.73k
         return;
4424
1.93k
   }
4425
4426
   /* Here after at the end of the last row of the last pass. */
4427
951
   png_read_finish_IDAT(png_ptr);
4428
951
}
4429
#endif /* SEQUENTIAL_READ */
4430
4431
void /* PRIVATE */
4432
png_read_start_row(png_structrp png_ptr)
4433
1.38k
{
4434
1.38k
   unsigned int max_pixel_depth;
4435
1.38k
   size_t row_bytes;
4436
4437
1.38k
   png_debug(1, "in png_read_start_row");
4438
4439
1.38k
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
4440
1.38k
   png_init_read_transformations(png_ptr);
4441
1.38k
#endif
4442
1.38k
   if (png_ptr->interlaced != 0)
4443
407
   {
4444
407
      if ((png_ptr->transformations & PNG_INTERLACE) == 0)
4445
0
         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
4446
0
             png_pass_ystart[0]) / png_pass_yinc[0];
4447
4448
407
      else
4449
407
         png_ptr->num_rows = png_ptr->height;
4450
4451
407
      png_ptr->iwidth = (png_ptr->width +
4452
407
          png_pass_inc[png_ptr->pass] - 1 -
4453
407
          png_pass_start[png_ptr->pass]) /
4454
407
          png_pass_inc[png_ptr->pass];
4455
407
   }
4456
4457
981
   else
4458
981
   {
4459
981
      png_ptr->num_rows = png_ptr->height;
4460
981
      png_ptr->iwidth = png_ptr->width;
4461
981
   }
4462
4463
1.38k
   max_pixel_depth = (unsigned int)png_ptr->pixel_depth;
4464
4465
   /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of
4466
    * calculations to calculate the final pixel depth, then
4467
    * png_do_read_transforms actually does the transforms.  This means that the
4468
    * code which effectively calculates this value is actually repeated in three
4469
    * separate places.  They must all match.  Innocent changes to the order of
4470
    * transformations can and will break libpng in a way that causes memory
4471
    * overwrites.
4472
    *
4473
    * TODO: fix this.
4474
    */
4475
1.38k
#ifdef PNG_READ_PACK_SUPPORTED
4476
1.38k
   if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8)
4477
452
      max_pixel_depth = 8;
4478
1.38k
#endif
4479
4480
1.38k
#ifdef PNG_READ_EXPAND_SUPPORTED
4481
1.38k
   if ((png_ptr->transformations & PNG_EXPAND) != 0)
4482
1.38k
   {
4483
1.38k
      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
4484
321
      {
4485
321
         if (png_ptr->num_trans != 0)
4486
128
            max_pixel_depth = 32;
4487
4488
193
         else
4489
193
            max_pixel_depth = 24;
4490
321
      }
4491
4492
1.06k
      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
4493
629
      {
4494
629
         if (max_pixel_depth < 8)
4495
168
            max_pixel_depth = 8;
4496
4497
629
         if (png_ptr->num_trans != 0)
4498
264
            max_pixel_depth *= 2;
4499
629
      }
4500
4501
438
      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
4502
194
      {
4503
194
         if (png_ptr->num_trans != 0)
4504
116
         {
4505
116
            max_pixel_depth *= 4;
4506
116
            max_pixel_depth /= 3;
4507
116
         }
4508
194
      }
4509
1.38k
   }
4510
1.38k
#endif
4511
4512
1.38k
#ifdef PNG_READ_EXPAND_16_SUPPORTED
4513
1.38k
   if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
4514
0
   {
4515
0
#  ifdef PNG_READ_EXPAND_SUPPORTED
4516
      /* In fact it is an error if it isn't supported, but checking is
4517
       * the safe way.
4518
       */
4519
0
      if ((png_ptr->transformations & PNG_EXPAND) != 0)
4520
0
      {
4521
0
         if (png_ptr->bit_depth < 16)
4522
0
            max_pixel_depth *= 2;
4523
0
      }
4524
0
      else
4525
0
#  endif
4526
0
      png_ptr->transformations &= ~PNG_EXPAND_16;
4527
0
   }
4528
1.38k
#endif
4529
4530
1.38k
#ifdef PNG_READ_FILLER_SUPPORTED
4531
1.38k
   if ((png_ptr->transformations & (PNG_FILLER)) != 0)
4532
179
   {
4533
179
      if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
4534
96
      {
4535
96
         if (max_pixel_depth <= 8)
4536
83
            max_pixel_depth = 16;
4537
4538
13
         else
4539
13
            max_pixel_depth = 32;
4540
96
      }
4541
4542
83
      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
4543
83
         png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
4544
83
      {
4545
83
         if (max_pixel_depth <= 32)
4546
70
            max_pixel_depth = 32;
4547
4548
13
         else
4549
13
            max_pixel_depth = 64;
4550
83
      }
4551
179
   }
4552
1.38k
#endif
4553
4554
1.38k
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4555
1.38k
   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
4556
1.17k
   {
4557
1.17k
      if (
4558
1.17k
#ifdef PNG_READ_EXPAND_SUPPORTED
4559
1.17k
          (png_ptr->num_trans != 0 &&
4560
1.17k
          (png_ptr->transformations & PNG_EXPAND) != 0) ||
4561
1.17k
#endif
4562
1.17k
#ifdef PNG_READ_FILLER_SUPPORTED
4563
1.17k
          (png_ptr->transformations & (PNG_FILLER)) != 0 ||
4564
1.17k
#endif
4565
1.17k
          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
4566
602
      {
4567
602
         if (max_pixel_depth <= 16)
4568
329
            max_pixel_depth = 32;
4569
4570
273
         else
4571
273
            max_pixel_depth = 64;
4572
602
      }
4573
4574
577
      else
4575
577
      {
4576
577
         if (max_pixel_depth <= 8)
4577
225
         {
4578
225
            if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4579
0
               max_pixel_depth = 32;
4580
4581
225
            else
4582
225
               max_pixel_depth = 24;
4583
225
         }
4584
4585
352
         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4586
120
            max_pixel_depth = 64;
4587
4588
232
         else
4589
232
            max_pixel_depth = 48;
4590
577
      }
4591
1.17k
   }
4592
1.38k
#endif
4593
4594
1.38k
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
4595
1.38k
defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
4596
1.38k
   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
4597
0
   {
4598
0
      unsigned int user_pixel_depth = png_ptr->user_transform_depth *
4599
0
         png_ptr->user_transform_channels;
4600
4601
0
      if (user_pixel_depth > max_pixel_depth)
4602
0
         max_pixel_depth = user_pixel_depth;
4603
0
   }
4604
1.38k
#endif
4605
4606
   /* This value is stored in png_struct and double checked in the row read
4607
    * code.
4608
    */
4609
1.38k
   png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
4610
1.38k
   png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
4611
4612
   /* Align the width on the next larger 8 pixels.  Mainly used
4613
    * for interlacing
4614
    */
4615
1.38k
   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
4616
   /* Calculate the maximum bytes needed, adding a byte and a pixel
4617
    * for safety's sake
4618
    */
4619
1.38k
   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
4620
1.38k
       1 + ((max_pixel_depth + 7) >> 3U);
4621
4622
#ifdef PNG_MAX_MALLOC_64K
4623
   if (row_bytes > (png_uint_32)65536L)
4624
      png_error(png_ptr, "This image requires a row greater than 64KB");
4625
#endif
4626
4627
1.38k
   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
4628
1.38k
   {
4629
1.38k
      png_free(png_ptr, png_ptr->big_row_buf);
4630
1.38k
      png_free(png_ptr, png_ptr->big_prev_row);
4631
4632
1.38k
      if (png_ptr->interlaced != 0)
4633
407
         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
4634
407
             row_bytes + 48);
4635
4636
981
      else
4637
981
         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
4638
4639
1.38k
      png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
4640
4641
1.38k
#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
4642
      /* Use 16-byte aligned memory for row_buf with at least 16 bytes
4643
       * of padding before and after row_buf; treat prev_row similarly.
4644
       * NOTE: the alignment is to the start of the pixels, one beyond the start
4645
       * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
4646
       * was incorrect; the filter byte was aligned, which had the exact
4647
       * opposite effect of that intended.
4648
       */
4649
1.38k
      {
4650
1.38k
         png_bytep temp = png_ptr->big_row_buf + 32;
4651
1.38k
         size_t extra = (size_t)temp & 0x0f;
4652
1.38k
         png_ptr->row_buf = temp - extra - 1/*filter byte*/;
4653
4654
1.38k
         temp = png_ptr->big_prev_row + 32;
4655
1.38k
         extra = (size_t)temp & 0x0f;
4656
1.38k
         png_ptr->prev_row = temp - extra - 1/*filter byte*/;
4657
1.38k
      }
4658
#else
4659
      /* Use 31 bytes of padding before and 17 bytes after row_buf. */
4660
      png_ptr->row_buf = png_ptr->big_row_buf + 31;
4661
      png_ptr->prev_row = png_ptr->big_prev_row + 31;
4662
#endif
4663
1.38k
      png_ptr->old_big_row_buf_size = row_bytes + 48;
4664
1.38k
   }
4665
4666
#ifdef PNG_MAX_MALLOC_64K
4667
   if (png_ptr->rowbytes > 65535)
4668
      png_error(png_ptr, "This image requires a row greater than 64KB");
4669
4670
#endif
4671
1.38k
   if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
4672
0
      png_error(png_ptr, "Row has too many bytes to allocate in memory");
4673
4674
1.38k
   memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
4675
4676
1.38k
   png_debug1(3, "width = %u,", png_ptr->width);
4677
1.38k
   png_debug1(3, "height = %u,", png_ptr->height);
4678
1.38k
   png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
4679
1.38k
   png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
4680
1.38k
   png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
4681
1.38k
   png_debug1(3, "irowbytes = %lu",
4682
1.38k
       (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
4683
4684
   /* The sequential reader needs a buffer for IDAT, but the progressive reader
4685
    * does not, so free the read buffer now regardless; the sequential reader
4686
    * reallocates it on demand.
4687
    */
4688
1.38k
   if (png_ptr->read_buffer != NULL)
4689
745
   {
4690
745
      png_bytep buffer = png_ptr->read_buffer;
4691
4692
745
      png_ptr->read_buffer_size = 0;
4693
745
      png_ptr->read_buffer = NULL;
4694
745
      png_free(png_ptr, buffer);
4695
745
   }
4696
4697
   /* Finally claim the zstream for the inflate of the IDAT data, use the bits
4698
    * value from the stream (note that this will result in a fatal error if the
4699
    * IDAT stream has a bogus deflate header window_bits value, but this should
4700
    * not be happening any longer!)
4701
    */
4702
1.38k
   if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK)
4703
0
      png_error(png_ptr, png_ptr->zstream.msg);
4704
4705
1.38k
   png_ptr->flags |= PNG_FLAG_ROW_INIT;
4706
1.38k
}
4707
#endif /* READ */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngset.c.html b/part1/report/w_corpus/src/libpng/pngset.c.html new file mode 100644 index 0000000..0c0a3a7 --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngset.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngset.c
Line
Count
Source (jump to first uncovered line)
1
/* pngset.c - storage of image information into info struct
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 * The functions here are used during reads to store data from the file
13
 * into the info struct, and during writes to store application data
14
 * into the info struct for writing into the file.  This abstracts the
15
 * info struct and allows us to change the structure in the future.
16
 */
17
18
#include "pngpriv.h"
19
20
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
21
22
#ifdef PNG_bKGD_SUPPORTED
23
void PNGAPI
24
png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
25
    png_const_color_16p background)
26
261
{
27
261
   png_debug1(1, "in %s storage function", "bKGD");
28
29
261
   if (png_ptr == NULL || info_ptr == NULL || background == NULL)
30
0
      return;
31
32
261
   info_ptr->background = *background;
33
261
   info_ptr->valid |= PNG_INFO_bKGD;
34
261
}
35
#endif
36
37
#ifdef PNG_cHRM_SUPPORTED
38
void PNGFAPI
39
png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
40
    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
41
    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
42
    png_fixed_point blue_x, png_fixed_point blue_y)
43
589
{
44
589
   png_debug1(1, "in %s storage function", "cHRM fixed");
45
46
589
   if (png_ptr == NULL || info_ptr == NULL)
47
0
      return;
48
49
589
   info_ptr->cHRM.redx = red_x;
50
589
   info_ptr->cHRM.redy = red_y;
51
589
   info_ptr->cHRM.greenx = green_x;
52
589
   info_ptr->cHRM.greeny = green_y;
53
589
   info_ptr->cHRM.bluex = blue_x;
54
589
   info_ptr->cHRM.bluey = blue_y;
55
589
   info_ptr->cHRM.whitex = white_x;
56
589
   info_ptr->cHRM.whitey = white_y;
57
58
589
   info_ptr->valid |= PNG_INFO_cHRM;
59
589
}
60
61
void PNGFAPI
62
png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
63
    png_fixed_point int_red_X, png_fixed_point int_red_Y,
64
    png_fixed_point int_red_Z, png_fixed_point int_green_X,
65
    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
66
    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
67
    png_fixed_point int_blue_Z)
68
0
{
69
0
   png_XYZ XYZ;
70
0
   png_xy xy;
71
72
0
   png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
73
74
0
   if (png_ptr == NULL || info_ptr == NULL)
75
0
      return;
76
77
0
   XYZ.red_X = int_red_X;
78
0
   XYZ.red_Y = int_red_Y;
79
0
   XYZ.red_Z = int_red_Z;
80
0
   XYZ.green_X = int_green_X;
81
0
   XYZ.green_Y = int_green_Y;
82
0
   XYZ.green_Z = int_green_Z;
83
0
   XYZ.blue_X = int_blue_X;
84
0
   XYZ.blue_Y = int_blue_Y;
85
0
   XYZ.blue_Z = int_blue_Z;
86
87
0
   if (png_xy_from_XYZ(&xy, &XYZ) == 0)
88
0
   {
89
0
      info_ptr->cHRM = xy;
90
0
      info_ptr->valid |= PNG_INFO_cHRM;
91
0
   }
92
93
0
   else
94
0
      png_app_error(png_ptr, "invalid cHRM XYZ");
95
0
}
96
97
#  ifdef PNG_FLOATING_POINT_SUPPORTED
98
void PNGAPI
99
png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
100
    double white_x, double white_y, double red_x, double red_y,
101
    double green_x, double green_y, double blue_x, double blue_y)
102
0
{
103
0
   png_set_cHRM_fixed(png_ptr, info_ptr,
104
0
       png_fixed(png_ptr, white_x, "cHRM White X"),
105
0
       png_fixed(png_ptr, white_y, "cHRM White Y"),
106
0
       png_fixed(png_ptr, red_x, "cHRM Red X"),
107
0
       png_fixed(png_ptr, red_y, "cHRM Red Y"),
108
0
       png_fixed(png_ptr, green_x, "cHRM Green X"),
109
0
       png_fixed(png_ptr, green_y, "cHRM Green Y"),
110
0
       png_fixed(png_ptr, blue_x, "cHRM Blue X"),
111
0
       png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
112
0
}
113
114
void PNGAPI
115
png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
116
    double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
117
    double blue_X, double blue_Y, double blue_Z)
118
0
{
119
0
   png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
120
0
       png_fixed(png_ptr, red_X, "cHRM Red X"),
121
0
       png_fixed(png_ptr, red_Y, "cHRM Red Y"),
122
0
       png_fixed(png_ptr, red_Z, "cHRM Red Z"),
123
0
       png_fixed(png_ptr, green_X, "cHRM Green X"),
124
0
       png_fixed(png_ptr, green_Y, "cHRM Green Y"),
125
0
       png_fixed(png_ptr, green_Z, "cHRM Green Z"),
126
0
       png_fixed(png_ptr, blue_X, "cHRM Blue X"),
127
0
       png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
128
0
       png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
129
0
}
130
#  endif /* FLOATING_POINT */
131
132
#endif /* cHRM */
133
134
#ifdef PNG_cICP_SUPPORTED
135
void PNGAPI
136
png_set_cICP(png_const_structrp png_ptr, png_inforp info_ptr,
137
             png_byte colour_primaries, png_byte transfer_function,
138
             png_byte matrix_coefficients, png_byte video_full_range_flag)
139
132
{
140
132
   png_debug1(1, "in %s storage function", "cICP");
141
142
132
   if (png_ptr == NULL || info_ptr == NULL)
143
0
      return;
144
145
132
   info_ptr->cicp_colour_primaries = colour_primaries;
146
132
   info_ptr->cicp_transfer_function = transfer_function;
147
132
   info_ptr->cicp_matrix_coefficients = matrix_coefficients;
148
132
   info_ptr->cicp_video_full_range_flag = video_full_range_flag;
149
150
132
   if (info_ptr->cicp_matrix_coefficients != 0)
151
43
   {
152
43
      png_warning(png_ptr, "Invalid cICP matrix coefficients");
153
43
      return;
154
43
   }
155
156
89
   info_ptr->valid |= PNG_INFO_cICP;
157
89
}
158
#endif /* cICP */
159
160
#ifdef PNG_cLLI_SUPPORTED
161
void PNGFAPI
162
png_set_cLLI_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
163
    /* The values below are in cd/m2 (nits) and are scaled by 10,000; not
164
     * 100,000 as in the case of png_fixed_point.
165
     */
166
    png_uint_32 maxCLL, png_uint_32 maxFALL)
167
220
{
168
220
   png_debug1(1, "in %s storage function", "cLLI");
169
170
220
   if (png_ptr == NULL || info_ptr == NULL)
171
0
      return;
172
173
   /* Check the light level range: */
174
220
   if (maxCLL > 0x7FFFFFFFU || maxFALL > 0x7FFFFFFFU)
175
20
   {
176
      /* The limit is 200kcd/m2; somewhat bright but not inconceivable because
177
       * human vision is said to run up to 100Mcd/m2.  The sun is about 2Gcd/m2.
178
       *
179
       * The reference sRGB monitor is 80cd/m2 and the limit of PQ encoding is
180
       * 2kcd/m2.
181
       */
182
20
      png_chunk_report(png_ptr, "cLLI light level exceeds PNG limit",
183
20
            PNG_CHUNK_WRITE_ERROR);
184
20
      return;
185
20
   }
186
187
200
   info_ptr->maxCLL = maxCLL;
188
200
   info_ptr->maxFALL = maxFALL;
189
200
   info_ptr->valid |= PNG_INFO_cLLI;
190
200
}
191
192
#  ifdef PNG_FLOATING_POINT_SUPPORTED
193
void PNGAPI
194
png_set_cLLI(png_const_structrp png_ptr, png_inforp info_ptr,
195
   double maxCLL, double maxFALL)
196
0
{
197
0
   png_set_cLLI_fixed(png_ptr, info_ptr,
198
0
       png_fixed_ITU(png_ptr, maxCLL, "png_set_cLLI(maxCLL)"),
199
0
       png_fixed_ITU(png_ptr, maxFALL, "png_set_cLLI(maxFALL)"));
200
0
}
201
#  endif /* FLOATING_POINT */
202
#endif /* cLLI */
203
204
#ifdef PNG_mDCV_SUPPORTED
205
static png_uint_16
206
png_ITU_fixed_16(int *error, png_fixed_point v)
207
1.23k
{
208
   /* Return a safe uint16_t value scaled according to the ITU H273 rules for
209
    * 16-bit display chromaticities.  Functions like the corresponding
210
    * png_fixed() internal function with regard to errors: it's an error on
211
    * write, a chunk_benign_error on read: See the definition of
212
    * png_chunk_report in pngpriv.h.
213
    */
214
1.23k
   v /= 2; /* rounds to 0 in C: avoids insignificant arithmetic errors */
215
1.23k
   if (v > 65535 || v < 0)
216
0
   {
217
0
      *error = 1;
218
0
      return 0;
219
0
   }
220
221
1.23k
   return (png_uint_16)/*SAFE*/v;
222
1.23k
}
223
224
void PNGAPI
225
png_set_mDCV_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
226
    png_fixed_point white_x, png_fixed_point white_y,
227
    png_fixed_point red_x, png_fixed_point red_y,
228
    png_fixed_point green_x, png_fixed_point green_y,
229
    png_fixed_point blue_x, png_fixed_point blue_y,
230
    png_uint_32 maxDL,
231
    png_uint_32 minDL)
232
154
{
233
154
   png_uint_16 rx, ry, gx, gy, bx, by, wx, wy;
234
154
   int error;
235
236
154
   png_debug1(1, "in %s storage function", "mDCV");
237
238
154
   if (png_ptr == NULL || info_ptr == NULL)
239
0
      return;
240
241
   /* Check the input values to ensure they are in the expected range: */
242
154
   error = 0;
243
154
   rx = png_ITU_fixed_16(&error, red_x);
244
154
   ry = png_ITU_fixed_16(&error, red_y);
245
154
   gx = png_ITU_fixed_16(&error, green_x);
246
154
   gy = png_ITU_fixed_16(&error, green_y);
247
154
   bx = png_ITU_fixed_16(&error, blue_x);
248
154
   by = png_ITU_fixed_16(&error, blue_y);
249
154
   wx = png_ITU_fixed_16(&error, white_x);
250
154
   wy = png_ITU_fixed_16(&error, white_y);
251
252
154
   if (error)
253
0
   {
254
0
      png_chunk_report(png_ptr,
255
0
         "mDCV chromaticities outside representable range",
256
0
         PNG_CHUNK_WRITE_ERROR);
257
0
      return;
258
0
   }
259
260
   /* Check the light level range: */
261
154
   if (maxDL > 0x7FFFFFFFU || minDL > 0x7FFFFFFFU)
262
6
   {
263
      /* The limit is 200kcd/m2; somewhat bright but not inconceivable because
264
       * human vision is said to run up to 100Mcd/m2.  The sun is about 2Gcd/m2.
265
       *
266
       * The reference sRGB monitor is 80cd/m2 and the limit of PQ encoding is
267
       * 2kcd/m2.
268
       */
269
6
      png_chunk_report(png_ptr, "mDCV display light level exceeds PNG limit",
270
6
            PNG_CHUNK_WRITE_ERROR);
271
6
      return;
272
6
   }
273
274
   /* All values are safe, the settings are accepted.
275
    *
276
    * IMPLEMENTATION NOTE: in practice the values can be checked and assigned
277
    * but the result is confusing if a writing app calls png_set_mDCV more than
278
    * once, the second time with an invalid value.  This approach is more
279
    * obviously correct at the cost of typing and a very slight machine
280
    * overhead.
281
    */
282
148
   info_ptr->mastering_red_x = rx;
283
148
   info_ptr->mastering_red_y = ry;
284
148
   info_ptr->mastering_green_x = gx;
285
148
   info_ptr->mastering_green_y = gy;
286
148
   info_ptr->mastering_blue_x = bx;
287
148
   info_ptr->mastering_blue_y = by;
288
148
   info_ptr->mastering_white_x = wx;
289
148
   info_ptr->mastering_white_y = wy;
290
148
   info_ptr->mastering_maxDL = maxDL;
291
148
   info_ptr->mastering_minDL = minDL;
292
148
   info_ptr->valid |= PNG_INFO_mDCV;
293
148
}
294
295
#  ifdef PNG_FLOATING_POINT_SUPPORTED
296
void PNGAPI
297
png_set_mDCV(png_const_structrp png_ptr, png_inforp info_ptr,
298
    double white_x, double white_y, double red_x, double red_y, double green_x,
299
    double green_y, double blue_x, double blue_y,
300
    double maxDL, double minDL)
301
0
{
302
0
   png_set_mDCV_fixed(png_ptr, info_ptr,
303
0
      png_fixed(png_ptr, white_x, "png_set_mDCV(white(x))"),
304
0
      png_fixed(png_ptr, white_y, "png_set_mDCV(white(y))"),
305
0
      png_fixed(png_ptr, red_x, "png_set_mDCV(red(x))"),
306
0
      png_fixed(png_ptr, red_y, "png_set_mDCV(red(y))"),
307
0
      png_fixed(png_ptr, green_x, "png_set_mDCV(green(x))"),
308
0
      png_fixed(png_ptr, green_y, "png_set_mDCV(green(y))"),
309
0
      png_fixed(png_ptr, blue_x, "png_set_mDCV(blue(x))"),
310
0
      png_fixed(png_ptr, blue_y, "png_set_mDCV(blue(y))"),
311
0
      png_fixed_ITU(png_ptr, maxDL, "png_set_mDCV(maxDL)"),
312
0
      png_fixed_ITU(png_ptr, minDL, "png_set_mDCV(minDL)"));
313
0
}
314
#  endif /* FLOATING_POINT */
315
#endif /* mDCV */
316
317
#ifdef PNG_eXIf_SUPPORTED
318
void PNGAPI
319
png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
320
    png_bytep exif)
321
0
{
322
0
  png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
323
0
  PNG_UNUSED(info_ptr)
324
0
  PNG_UNUSED(exif)
325
0
}
326
327
void PNGAPI
328
png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
329
    png_uint_32 num_exif, png_bytep exif)
330
22
{
331
22
   png_bytep new_exif;
332
333
22
   png_debug1(1, "in %s storage function", "eXIf");
334
335
22
   if (png_ptr == NULL || info_ptr == NULL ||
336
22
       (png_ptr->mode & PNG_WROTE_eXIf) != 0)
337
0
      return;
338
339
22
   new_exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, num_exif));
340
341
22
   if (new_exif == NULL)
342
0
   {
343
0
      png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
344
0
      return;
345
0
   }
346
347
22
   memcpy(new_exif, exif, (size_t)num_exif);
348
349
22
   png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0);
350
351
22
   info_ptr->num_exif = num_exif;
352
22
   info_ptr->exif = new_exif;
353
22
   info_ptr->free_me |= PNG_FREE_EXIF;
354
22
   info_ptr->valid |= PNG_INFO_eXIf;
355
22
}
356
#endif /* eXIf */
357
358
#ifdef PNG_gAMA_SUPPORTED
359
void PNGFAPI
360
png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
361
    png_fixed_point file_gamma)
362
775
{
363
775
   png_debug1(1, "in %s storage function", "gAMA");
364
365
775
   if (png_ptr == NULL || info_ptr == NULL)
366
0
      return;
367
368
775
   info_ptr->gamma = file_gamma;
369
775
   info_ptr->valid |= PNG_INFO_gAMA;
370
775
}
371
372
#  ifdef PNG_FLOATING_POINT_SUPPORTED
373
void PNGAPI
374
png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
375
0
{
376
0
   png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
377
0
       "png_set_gAMA"));
378
0
}
379
#  endif
380
#endif
381
382
#ifdef PNG_hIST_SUPPORTED
383
void PNGAPI
384
png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
385
    png_const_uint_16p hist)
386
1
{
387
1
   int i;
388
389
1
   png_debug1(1, "in %s storage function", "hIST");
390
391
1
   if (png_ptr == NULL || info_ptr == NULL)
392
0
      return;
393
394
1
   if (info_ptr->num_palette == 0 || info_ptr->num_palette
395
0
       > PNG_MAX_PALETTE_LENGTH)
396
1
   {
397
1
      png_warning(png_ptr,
398
1
          "Invalid palette size, hIST allocation skipped");
399
400
1
      return;
401
1
   }
402
403
0
   png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
404
405
   /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
406
    * version 1.2.1
407
    */
408
0
   info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,
409
0
       PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));
410
411
0
   if (info_ptr->hist == NULL)
412
0
   {
413
0
      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
414
0
      return;
415
0
   }
416
417
0
   for (i = 0; i < info_ptr->num_palette; i++)
418
0
      info_ptr->hist[i] = hist[i];
419
420
0
   info_ptr->free_me |= PNG_FREE_HIST;
421
0
   info_ptr->valid |= PNG_INFO_hIST;
422
0
}
423
#endif
424
425
void PNGAPI
426
png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
427
    png_uint_32 width, png_uint_32 height, int bit_depth,
428
    int color_type, int interlace_type, int compression_type,
429
    int filter_type)
430
2.20k
{
431
2.20k
   png_debug1(1, "in %s storage function", "IHDR");
432
433
2.20k
   if (png_ptr == NULL || info_ptr == NULL)
434
0
      return;
435
436
2.20k
   info_ptr->width = width;
437
2.20k
   info_ptr->height = height;
438
2.20k
   info_ptr->bit_depth = (png_byte)bit_depth;
439
2.20k
   info_ptr->color_type = (png_byte)color_type;
440
2.20k
   info_ptr->compression_type = (png_byte)compression_type;
441
2.20k
   info_ptr->filter_type = (png_byte)filter_type;
442
2.20k
   info_ptr->interlace_type = (png_byte)interlace_type;
443
444
2.20k
   png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
445
2.20k
       info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
446
2.20k
       info_ptr->compression_type, info_ptr->filter_type);
447
448
2.20k
   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
449
451
      info_ptr->channels = 1;
450
451
1.75k
   else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
452
729
      info_ptr->channels = 3;
453
454
1.02k
   else
455
1.02k
      info_ptr->channels = 1;
456
457
2.20k
   if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
458
566
      info_ptr->channels++;
459
460
2.20k
   info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
461
462
2.20k
   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
463
2.20k
}
464
465
#ifdef PNG_oFFs_SUPPORTED
466
void PNGAPI
467
png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,
468
    png_int_32 offset_x, png_int_32 offset_y, int unit_type)
469
171
{
470
171
   png_debug1(1, "in %s storage function", "oFFs");
471
472
171
   if (png_ptr == NULL || info_ptr == NULL)
473
0
      return;
474
475
171
   info_ptr->x_offset = offset_x;
476
171
   info_ptr->y_offset = offset_y;
477
171
   info_ptr->offset_unit_type = (png_byte)unit_type;
478
171
   info_ptr->valid |= PNG_INFO_oFFs;
479
171
}
480
#endif
481
482
#ifdef PNG_pCAL_SUPPORTED
483
void PNGAPI
484
png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
485
    png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
486
    int nparams, png_const_charp units, png_charpp params)
487
117
{
488
117
   size_t length;
489
117
   int i;
490
491
117
   png_debug1(1, "in %s storage function", "pCAL");
492
493
117
   if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
494
117
       || (nparams > 0 && params == NULL))
495
0
      return;
496
497
117
   length = strlen(purpose) + 1;
498
117
   png_debug1(3, "allocating purpose for info (%lu bytes)",
499
117
       (unsigned long)length);
500
501
   /* TODO: validate format of calibration name and unit name */
502
503
   /* Check that the type matches the specification. */
504
117
   if (type < 0 || type > 3)
505
8
   {
506
8
      png_chunk_report(png_ptr, "Invalid pCAL equation type",
507
8
            PNG_CHUNK_WRITE_ERROR);
508
8
      return;
509
8
   }
510
511
109
   if (nparams < 0 || nparams > 255)
512
0
   {
513
0
      png_chunk_report(png_ptr, "Invalid pCAL parameter count",
514
0
            PNG_CHUNK_WRITE_ERROR);
515
0
      return;
516
0
   }
517
518
   /* Validate params[nparams] */
519
259
   for (i=0; i<nparams; ++i)
520
196
   {
521
196
      if (params[i] == NULL ||
522
196
          !png_check_fp_string(params[i], strlen(params[i])))
523
46
      {
524
46
         png_chunk_report(png_ptr, "Invalid format for pCAL parameter",
525
46
               PNG_CHUNK_WRITE_ERROR);
526
46
         return;
527
46
      }
528
196
   }
529
530
63
   info_ptr->pcal_purpose = png_voidcast(png_charp,
531
63
       png_malloc_warn(png_ptr, length));
532
533
63
   if (info_ptr->pcal_purpose == NULL)
534
0
   {
535
0
      png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose",
536
0
            PNG_CHUNK_WRITE_ERROR);
537
0
      return;
538
0
   }
539
540
63
   memcpy(info_ptr->pcal_purpose, purpose, length);
541
542
63
   info_ptr->free_me |= PNG_FREE_PCAL;
543
544
63
   png_debug(3, "storing X0, X1, type, and nparams in info");
545
63
   info_ptr->pcal_X0 = X0;
546
63
   info_ptr->pcal_X1 = X1;
547
63
   info_ptr->pcal_type = (png_byte)type;
548
63
   info_ptr->pcal_nparams = (png_byte)nparams;
549
550
63
   length = strlen(units) + 1;
551
63
   png_debug1(3, "allocating units for info (%lu bytes)",
552
63
       (unsigned long)length);
553
554
63
   info_ptr->pcal_units = png_voidcast(png_charp,
555
63
       png_malloc_warn(png_ptr, length));
556
557
63
   if (info_ptr->pcal_units == NULL)
558
0
   {
559
0
      png_warning(png_ptr, "Insufficient memory for pCAL units");
560
0
      return;
561
0
   }
562
563
63
   memcpy(info_ptr->pcal_units, units, length);
564
565
63
   info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
566
63
       (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
567
568
63
   if (info_ptr->pcal_params == NULL)
569
0
   {
570
0
      png_warning(png_ptr, "Insufficient memory for pCAL params");
571
0
      return;
572
0
   }
573
574
63
   memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
575
63
       (sizeof (png_charp)));
576
577
189
   for (i = 0; i < nparams; i++)
578
126
   {
579
126
      length = strlen(params[i]) + 1;
580
126
      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
581
126
          (unsigned long)length);
582
583
126
      info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
584
585
126
      if (info_ptr->pcal_params[i] == NULL)
586
0
      {
587
0
         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
588
0
         return;
589
0
      }
590
591
126
      memcpy(info_ptr->pcal_params[i], params[i], length);
592
126
   }
593
594
63
   info_ptr->valid |= PNG_INFO_pCAL;
595
63
}
596
#endif
597
598
#ifdef PNG_sCAL_SUPPORTED
599
void PNGAPI
600
png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
601
    int unit, png_const_charp swidth, png_const_charp sheight)
602
84
{
603
84
   size_t lengthw = 0, lengthh = 0;
604
605
84
   png_debug1(1, "in %s storage function", "sCAL");
606
607
84
   if (png_ptr == NULL || info_ptr == NULL)
608
0
      return;
609
610
   /* Double check the unit (should never get here with an invalid
611
    * unit unless this is an API call.)
612
    */
613
84
   if (unit != 1 && unit != 2)
614
0
      png_error(png_ptr, "Invalid sCAL unit");
615
616
84
   if (swidth == NULL || (lengthw = strlen(swidth)) == 0 ||
617
84
       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
618
0
      png_error(png_ptr, "Invalid sCAL width");
619
620
84
   if (sheight == NULL || (lengthh = strlen(sheight)) == 0 ||
621
84
       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
622
0
      png_error(png_ptr, "Invalid sCAL height");
623
624
84
   info_ptr->scal_unit = (png_byte)unit;
625
626
84
   ++lengthw;
627
628
84
   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
629
630
84
   info_ptr->scal_s_width = png_voidcast(png_charp,
631
84
       png_malloc_warn(png_ptr, lengthw));
632
633
84
   if (info_ptr->scal_s_width == NULL)
634
0
   {
635
0
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
636
637
0
      return;
638
0
   }
639
640
84
   memcpy(info_ptr->scal_s_width, swidth, lengthw);
641
642
84
   ++lengthh;
643
644
84
   png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
645
646
84
   info_ptr->scal_s_height = png_voidcast(png_charp,
647
84
       png_malloc_warn(png_ptr, lengthh));
648
649
84
   if (info_ptr->scal_s_height == NULL)
650
0
   {
651
0
      png_free(png_ptr, info_ptr->scal_s_width);
652
0
      info_ptr->scal_s_width = NULL;
653
654
0
      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
655
0
      return;
656
0
   }
657
658
84
   memcpy(info_ptr->scal_s_height, sheight, lengthh);
659
660
84
   info_ptr->free_me |= PNG_FREE_SCAL;
661
84
   info_ptr->valid |= PNG_INFO_sCAL;
662
84
}
663
664
#  ifdef PNG_FLOATING_POINT_SUPPORTED
665
void PNGAPI
666
png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
667
    double width, double height)
668
0
{
669
0
   png_debug1(1, "in %s storage function", "sCAL");
670
671
   /* Check the arguments. */
672
0
   if (width <= 0)
673
0
      png_warning(png_ptr, "Invalid sCAL width ignored");
674
675
0
   else if (height <= 0)
676
0
      png_warning(png_ptr, "Invalid sCAL height ignored");
677
678
0
   else
679
0
   {
680
      /* Convert 'width' and 'height' to ASCII. */
681
0
      char swidth[PNG_sCAL_MAX_DIGITS+1];
682
0
      char sheight[PNG_sCAL_MAX_DIGITS+1];
683
684
0
      png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
685
0
          PNG_sCAL_PRECISION);
686
0
      png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
687
0
          PNG_sCAL_PRECISION);
688
689
0
      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
690
0
   }
691
0
}
692
#  endif
693
694
#  ifdef PNG_FIXED_POINT_SUPPORTED
695
void PNGAPI
696
png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
697
    png_fixed_point width, png_fixed_point height)
698
0
{
699
0
   png_debug1(1, "in %s storage function", "sCAL");
700
701
   /* Check the arguments. */
702
0
   if (width <= 0)
703
0
      png_warning(png_ptr, "Invalid sCAL width ignored");
704
705
0
   else if (height <= 0)
706
0
      png_warning(png_ptr, "Invalid sCAL height ignored");
707
708
0
   else
709
0
   {
710
      /* Convert 'width' and 'height' to ASCII. */
711
0
      char swidth[PNG_sCAL_MAX_DIGITS+1];
712
0
      char sheight[PNG_sCAL_MAX_DIGITS+1];
713
714
0
      png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width);
715
0
      png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height);
716
717
0
      png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
718
0
   }
719
0
}
720
#  endif
721
#endif
722
723
#ifdef PNG_pHYs_SUPPORTED
724
void PNGAPI
725
png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,
726
    png_uint_32 res_x, png_uint_32 res_y, int unit_type)
727
58
{
728
58
   png_debug1(1, "in %s storage function", "pHYs");
729
730
58
   if (png_ptr == NULL || info_ptr == NULL)
731
0
      return;
732
733
58
   info_ptr->x_pixels_per_unit = res_x;
734
58
   info_ptr->y_pixels_per_unit = res_y;
735
58
   info_ptr->phys_unit_type = (png_byte)unit_type;
736
58
   info_ptr->valid |= PNG_INFO_pHYs;
737
58
}
738
#endif
739
740
void PNGAPI
741
png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
742
    png_const_colorp palette, int num_palette)
743
370
{
744
745
370
   png_uint_32 max_palette_length;
746
747
370
   png_debug1(1, "in %s storage function", "PLTE");
748
749
370
   if (png_ptr == NULL || info_ptr == NULL)
750
0
      return;
751
752
370
   max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
753
360
      (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
754
755
370
   if (num_palette < 0 || num_palette > (int) max_palette_length)
756
0
   {
757
0
      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
758
0
         png_error(png_ptr, "Invalid palette length");
759
760
0
      else
761
0
      {
762
0
         png_warning(png_ptr, "Invalid palette length");
763
764
0
         return;
765
0
      }
766
0
   }
767
768
370
   if ((num_palette > 0 && palette == NULL) ||
769
370
      (num_palette == 0
770
370
#        ifdef PNG_MNG_FEATURES_SUPPORTED
771
370
            && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
772
370
#        endif
773
370
      ))
774
1
   {
775
1
      png_error(png_ptr, "Invalid palette");
776
1
   }
777
778
   /* It may not actually be necessary to set png_ptr->palette here;
779
    * we do it for backward compatibility with the way the png_handle_tRNS
780
    * function used to do the allocation.
781
    *
782
    * 1.6.0: the above statement appears to be incorrect; something has to set
783
    * the palette inside png_struct on read.
784
    */
785
369
   png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
786
787
   /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
788
    * of num_palette entries, in case of an invalid PNG file or incorrect
789
    * call to png_set_PLTE() with too-large sample values.
790
    */
791
369
   png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
792
369
       PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
793
794
369
   if (num_palette > 0)
795
369
      memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
796
369
          (sizeof (png_color)));
797
798
369
   info_ptr->palette = png_ptr->palette;
799
369
   info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
800
369
   info_ptr->free_me |= PNG_FREE_PLTE;
801
369
   info_ptr->valid |= PNG_INFO_PLTE;
802
369
}
803
804
#ifdef PNG_sBIT_SUPPORTED
805
void PNGAPI
806
png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
807
    png_const_color_8p sig_bit)
808
187
{
809
187
   png_debug1(1, "in %s storage function", "sBIT");
810
811
187
   if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL)
812
0
      return;
813
814
187
   info_ptr->sig_bit = *sig_bit;
815
187
   info_ptr->valid |= PNG_INFO_sBIT;
816
187
}
817
#endif
818
819
#ifdef PNG_sRGB_SUPPORTED
820
void PNGAPI
821
png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
822
226
{
823
226
   png_debug1(1, "in %s storage function", "sRGB");
824
825
226
   if (png_ptr == NULL || info_ptr == NULL)
826
0
      return;
827
828
226
   info_ptr->rendering_intent = srgb_intent;
829
226
   info_ptr->valid |= PNG_INFO_sRGB;
830
226
}
831
832
void PNGAPI
833
png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
834
    int srgb_intent)
835
0
{
836
0
   png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
837
838
0
   if (png_ptr == NULL || info_ptr == NULL)
839
0
      return;
840
841
0
   png_set_sRGB(png_ptr, info_ptr, srgb_intent);
842
843
0
#  ifdef PNG_gAMA_SUPPORTED
844
0
      png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
845
0
#  endif /* gAMA */
846
847
0
#  ifdef PNG_cHRM_SUPPORTED
848
0
      png_set_cHRM_fixed(png_ptr, info_ptr,
849
         /* color      x       y */
850
0
         /* white */ 31270, 32900,
851
0
         /* red   */ 64000, 33000,
852
0
         /* green */ 30000, 60000,
853
0
         /* blue  */ 15000,  6000);
854
0
#  endif /* cHRM */
855
0
}
856
#endif /* sRGB */
857
858
859
#ifdef PNG_iCCP_SUPPORTED
860
void PNGAPI
861
png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
862
    png_const_charp name, int compression_type,
863
    png_const_bytep profile, png_uint_32 proflen)
864
0
{
865
0
   png_charp new_iccp_name;
866
0
   png_bytep new_iccp_profile;
867
0
   size_t length;
868
869
0
   png_debug1(1, "in %s storage function", "iCCP");
870
871
0
   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
872
0
      return;
873
874
0
   if (compression_type != PNG_COMPRESSION_TYPE_BASE)
875
0
      png_app_error(png_ptr, "Invalid iCCP compression method");
876
877
0
   length = strlen(name)+1;
878
0
   new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
879
880
0
   if (new_iccp_name == NULL)
881
0
   {
882
0
      png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
883
884
0
      return;
885
0
   }
886
887
0
   memcpy(new_iccp_name, name, length);
888
0
   new_iccp_profile = png_voidcast(png_bytep,
889
0
       png_malloc_warn(png_ptr, proflen));
890
891
0
   if (new_iccp_profile == NULL)
892
0
   {
893
0
      png_free(png_ptr, new_iccp_name);
894
0
      png_benign_error(png_ptr,
895
0
          "Insufficient memory to process iCCP profile");
896
897
0
      return;
898
0
   }
899
900
0
   memcpy(new_iccp_profile, profile, proflen);
901
902
0
   png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
903
904
0
   info_ptr->iccp_proflen = proflen;
905
0
   info_ptr->iccp_name = new_iccp_name;
906
0
   info_ptr->iccp_profile = new_iccp_profile;
907
0
   info_ptr->free_me |= PNG_FREE_ICCP;
908
0
   info_ptr->valid |= PNG_INFO_iCCP;
909
0
}
910
#endif
911
912
#ifdef PNG_TEXT_SUPPORTED
913
void PNGAPI
914
png_set_text(png_const_structrp png_ptr, png_inforp info_ptr,
915
    png_const_textp text_ptr, int num_text)
916
0
{
917
0
   int ret;
918
0
   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
919
920
0
   if (ret != 0)
921
0
      png_error(png_ptr, "Insufficient memory to store text");
922
0
}
923
924
int /* PRIVATE */
925
png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
926
    png_const_textp text_ptr, int num_text)
927
5.39k
{
928
5.39k
   int i;
929
930
5.39k
   png_debug1(1, "in text storage function, chunk typeid = 0x%lx",
931
5.39k
      png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name);
932
933
5.39k
   if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
934
0
      return 0;
935
936
   /* Make sure we have enough space in the "text" array in info_struct
937
    * to hold all of the incoming text_ptr objects.  This compare can't overflow
938
    * because max_text >= num_text (anyway, subtract of two positive integers
939
    * can't overflow in any case.)
940
    */
941
5.39k
   if (num_text > info_ptr->max_text - info_ptr->num_text)
942
1.26k
   {
943
1.26k
      int old_num_text = info_ptr->num_text;
944
1.26k
      int max_text;
945
1.26k
      png_textp new_text = NULL;
946
947
      /* Calculate an appropriate max_text, checking for overflow. */
948
1.26k
      max_text = old_num_text;
949
1.26k
      if (num_text <= INT_MAX - max_text)
950
1.26k
      {
951
1.26k
         max_text += num_text;
952
953
         /* Round up to a multiple of 8 */
954
1.26k
         if (max_text < INT_MAX-8)
955
1.26k
            max_text = (max_text + 8) & ~0x7;
956
957
0
         else
958
0
            max_text = INT_MAX;
959
960
         /* Now allocate a new array and copy the old members in; this does all
961
          * the overflow checks.
962
          */
963
1.26k
         new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
964
1.26k
             info_ptr->text, old_num_text, max_text-old_num_text,
965
1.26k
             sizeof *new_text));
966
1.26k
      }
967
968
1.26k
      if (new_text == NULL)
969
0
      {
970
0
         png_chunk_report(png_ptr, "too many text chunks",
971
0
             PNG_CHUNK_WRITE_ERROR);
972
973
0
         return 1;
974
0
      }
975
976
1.26k
      png_free(png_ptr, info_ptr->text);
977
978
1.26k
      info_ptr->text = new_text;
979
1.26k
      info_ptr->free_me |= PNG_FREE_TEXT;
980
1.26k
      info_ptr->max_text = max_text;
981
      /* num_text is adjusted below as the entries are copied in */
982
983
1.26k
      png_debug1(3, "allocated %d entries for info_ptr->text", max_text);
984
1.26k
   }
985
986
10.7k
   for (i = 0; i < num_text; i++)
987
5.39k
   {
988
5.39k
      size_t text_length, key_len;
989
5.39k
      size_t lang_len, lang_key_len;
990
5.39k
      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
991
992
5.39k
      if (text_ptr[i].key == NULL)
993
0
          continue;
994
995
5.39k
      if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
996
5.39k
          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
997
0
      {
998
0
         png_chunk_report(png_ptr, "text compression mode is out of range",
999
0
             PNG_CHUNK_WRITE_ERROR);
1000
0
         continue;
1001
0
      }
1002
1003
5.39k
      key_len = strlen(text_ptr[i].key);
1004
1005
5.39k
      if (text_ptr[i].compression <= 0)
1006
4.76k
      {
1007
4.76k
         lang_len = 0;
1008
4.76k
         lang_key_len = 0;
1009
4.76k
      }
1010
1011
633
      else
1012
633
#  ifdef PNG_iTXt_SUPPORTED
1013
633
      {
1014
         /* Set iTXt data */
1015
1016
633
         if (text_ptr[i].lang != NULL)
1017
633
            lang_len = strlen(text_ptr[i].lang);
1018
1019
0
         else
1020
0
            lang_len = 0;
1021
1022
633
         if (text_ptr[i].lang_key != NULL)
1023
633
            lang_key_len = strlen(text_ptr[i].lang_key);
1024
1025
0
         else
1026
0
            lang_key_len = 0;
1027
633
      }
1028
#  else /* iTXt */
1029
      {
1030
         png_chunk_report(png_ptr, "iTXt chunk not supported",
1031
             PNG_CHUNK_WRITE_ERROR);
1032
         continue;
1033
      }
1034
#  endif
1035
1036
5.39k
      if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
1037
705
      {
1038
705
         text_length = 0;
1039
705
#  ifdef PNG_iTXt_SUPPORTED
1040
705
         if (text_ptr[i].compression > 0)
1041
58
            textp->compression = PNG_ITXT_COMPRESSION_NONE;
1042
1043
647
         else
1044
647
#  endif
1045
647
            textp->compression = PNG_TEXT_COMPRESSION_NONE;
1046
705
      }
1047
1048
4.69k
      else
1049
4.69k
      {
1050
4.69k
         text_length = strlen(text_ptr[i].text);
1051
4.69k
         textp->compression = text_ptr[i].compression;
1052
4.69k
      }
1053
1054
5.39k
      textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr,
1055
5.39k
          key_len + text_length + lang_len + lang_key_len + 4));
1056
1057
5.39k
      if (textp->key == NULL)
1058
0
      {
1059
0
         png_chunk_report(png_ptr, "text chunk: out of memory",
1060
0
             PNG_CHUNK_WRITE_ERROR);
1061
1062
0
         return 1;
1063
0
      }
1064
1065
5.39k
      png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
1066
5.39k
          (unsigned long)(png_uint_32)
1067
5.39k
          (key_len + lang_len + lang_key_len + text_length + 4),
1068
5.39k
          textp->key);
1069
1070
5.39k
      memcpy(textp->key, text_ptr[i].key, key_len);
1071
5.39k
      *(textp->key + key_len) = '\0';
1072
1073
5.39k
      if (text_ptr[i].compression > 0)
1074
633
      {
1075
633
         textp->lang = textp->key + key_len + 1;
1076
633
         memcpy(textp->lang, text_ptr[i].lang, lang_len);
1077
633
         *(textp->lang + lang_len) = '\0';
1078
633
         textp->lang_key = textp->lang + lang_len + 1;
1079
633
         memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
1080
633
         *(textp->lang_key + lang_key_len) = '\0';
1081
633
         textp->text = textp->lang_key + lang_key_len + 1;
1082
633
      }
1083
1084
4.76k
      else
1085
4.76k
      {
1086
4.76k
         textp->lang=NULL;
1087
4.76k
         textp->lang_key=NULL;
1088
4.76k
         textp->text = textp->key + key_len + 1;
1089
4.76k
      }
1090
1091
5.39k
      if (text_length != 0)
1092
4.69k
         memcpy(textp->text, text_ptr[i].text, text_length);
1093
1094
5.39k
      *(textp->text + text_length) = '\0';
1095
1096
5.39k
#  ifdef PNG_iTXt_SUPPORTED
1097
5.39k
      if (textp->compression > 0)
1098
633
      {
1099
633
         textp->text_length = 0;
1100
633
         textp->itxt_length = text_length;
1101
633
      }
1102
1103
4.76k
      else
1104
4.76k
#  endif
1105
4.76k
      {
1106
4.76k
         textp->text_length = text_length;
1107
4.76k
         textp->itxt_length = 0;
1108
4.76k
      }
1109
1110
5.39k
      info_ptr->num_text++;
1111
5.39k
      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
1112
5.39k
   }
1113
1114
5.39k
   return 0;
1115
5.39k
}
1116
#endif
1117
1118
#ifdef PNG_tIME_SUPPORTED
1119
void PNGAPI
1120
png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
1121
    png_const_timep mod_time)
1122
68
{
1123
68
   png_debug1(1, "in %s storage function", "tIME");
1124
1125
68
   if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||
1126
68
       (png_ptr->mode & PNG_WROTE_tIME) != 0)
1127
0
      return;
1128
1129
68
   if (mod_time->month == 0   || mod_time->month > 12  ||
1130
68
       mod_time->day   == 0   || mod_time->day   > 31  ||
1131
68
       mod_time->hour  > 23   || mod_time->minute > 59 ||
1132
68
       mod_time->second > 60)
1133
7
   {
1134
7
      png_warning(png_ptr, "Ignoring invalid time value");
1135
1136
7
      return;
1137
7
   }
1138
1139
61
   info_ptr->mod_time = *mod_time;
1140
61
   info_ptr->valid |= PNG_INFO_tIME;
1141
61
}
1142
#endif
1143
1144
#ifdef PNG_tRNS_SUPPORTED
1145
void PNGAPI
1146
png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
1147
    png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
1148
597
{
1149
597
   png_debug1(1, "in %s storage function", "tRNS");
1150
1151
597
   if (png_ptr == NULL || info_ptr == NULL)
1152
1153
0
      return;
1154
1155
597
   if (trans_alpha != NULL)
1156
597
   {
1157
       /* It may not actually be necessary to set png_ptr->trans_alpha here;
1158
        * we do it for backward compatibility with the way the png_handle_tRNS
1159
        * function used to do the allocation.
1160
        *
1161
        * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively
1162
        * relies on png_set_tRNS storing the information in png_struct
1163
        * (otherwise it won't be there for the code in pngrtran.c).
1164
        */
1165
1166
597
       png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
1167
1168
597
       if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
1169
597
       {
1170
         /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
1171
597
          info_ptr->trans_alpha = png_voidcast(png_bytep,
1172
597
              png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
1173
597
          memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
1174
1175
597
          info_ptr->free_me |= PNG_FREE_TRNS;
1176
597
          info_ptr->valid |= PNG_INFO_tRNS;
1177
597
       }
1178
597
       png_ptr->trans_alpha = info_ptr->trans_alpha;
1179
597
   }
1180
1181
597
   if (trans_color != NULL)
1182
597
   {
1183
597
#ifdef PNG_WARNINGS_SUPPORTED
1184
597
      if (info_ptr->bit_depth < 16)
1185
489
      {
1186
489
         int sample_max = (1 << info_ptr->bit_depth) - 1;
1187
1188
489
         if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
1189
489
             trans_color->gray > sample_max) ||
1190
489
             (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
1191
480
             (trans_color->red > sample_max ||
1192
69
             trans_color->green > sample_max ||
1193
69
             trans_color->blue > sample_max)))
1194
23
            png_warning(png_ptr,
1195
23
                "tRNS chunk has out-of-range samples for bit_depth");
1196
489
      }
1197
597
#endif
1198
1199
597
      info_ptr->trans_color = *trans_color;
1200
1201
597
      if (num_trans == 0)
1202
0
         num_trans = 1;
1203
597
   }
1204
1205
597
   info_ptr->num_trans = (png_uint_16)num_trans;
1206
1207
597
   if (num_trans != 0)
1208
597
   {
1209
597
      info_ptr->free_me |= PNG_FREE_TRNS;
1210
597
      info_ptr->valid |= PNG_INFO_tRNS;
1211
597
   }
1212
597
}
1213
#endif
1214
1215
#ifdef PNG_sPLT_SUPPORTED
1216
void PNGAPI
1217
png_set_sPLT(png_const_structrp png_ptr,
1218
    png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)
1219
/*
1220
 *  entries        - array of png_sPLT_t structures
1221
 *                   to be added to the list of palettes
1222
 *                   in the info structure.
1223
 *
1224
 *  nentries       - number of palette structures to be
1225
 *                   added.
1226
 */
1227
401
{
1228
401
   png_sPLT_tp np;
1229
1230
401
   png_debug1(1, "in %s storage function", "sPLT");
1231
1232
401
   if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
1233
0
      return;
1234
1235
   /* Use the internal realloc function, which checks for all the possible
1236
    * overflows.  Notice that the parameters are (int) and (size_t)
1237
    */
1238
401
   np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
1239
401
       info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
1240
401
       sizeof *np));
1241
1242
401
   if (np == NULL)
1243
0
   {
1244
      /* Out of memory or too many chunks */
1245
0
      png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
1246
0
      return;
1247
0
   }
1248
1249
401
   png_free(png_ptr, info_ptr->splt_palettes);
1250
1251
401
   info_ptr->splt_palettes = np;
1252
401
   info_ptr->free_me |= PNG_FREE_SPLT;
1253
1254
401
   np += info_ptr->splt_palettes_num;
1255
1256
401
   do
1257
401
   {
1258
401
      size_t length;
1259
1260
      /* Skip invalid input entries */
1261
401
      if (entries->name == NULL || entries->entries == NULL)
1262
0
      {
1263
         /* png_handle_sPLT doesn't do this, so this is an app error */
1264
0
         png_app_error(png_ptr, "png_set_sPLT: invalid sPLT");
1265
         /* Just skip the invalid entry */
1266
0
         continue;
1267
0
      }
1268
1269
401
      np->depth = entries->depth;
1270
1271
      /* In the event of out-of-memory just return - there's no point keeping
1272
       * on trying to add sPLT chunks.
1273
       */
1274
401
      length = strlen(entries->name) + 1;
1275
401
      np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
1276
1277
401
      if (np->name == NULL)
1278
0
         break;
1279
1280
401
      memcpy(np->name, entries->name, length);
1281
1282
      /* IMPORTANT: we have memory now that won't get freed if something else
1283
       * goes wrong; this code must free it.  png_malloc_array produces no
1284
       * warnings; use a png_chunk_report (below) if there is an error.
1285
       */
1286
401
      np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
1287
401
          entries->nentries, sizeof (png_sPLT_entry)));
1288
1289
401
      if (np->entries == NULL)
1290
0
      {
1291
0
         png_free(png_ptr, np->name);
1292
0
         np->name = NULL;
1293
0
         break;
1294
0
      }
1295
1296
401
      np->nentries = entries->nentries;
1297
      /* This multiply can't overflow because png_malloc_array has already
1298
       * checked it when doing the allocation.
1299
       */
1300
401
      memcpy(np->entries, entries->entries,
1301
401
          (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
1302
1303
      /* Note that 'continue' skips the advance of the out pointer and out
1304
       * count, so an invalid entry is not added.
1305
       */
1306
401
      info_ptr->valid |= PNG_INFO_sPLT;
1307
401
      ++(info_ptr->splt_palettes_num);
1308
401
      ++np;
1309
401
      ++entries;
1310
401
   }
1311
401
   while (--nentries);
1312
1313
401
   if (nentries > 0)
1314
0
      png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
1315
401
}
1316
#endif /* sPLT */
1317
1318
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
1319
static png_byte
1320
check_location(png_const_structrp png_ptr, int location)
1321
0
{
1322
0
   location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
1323
1324
   /* New in 1.6.0; copy the location and check it.  This is an API
1325
    * change; previously the app had to use the
1326
    * png_set_unknown_chunk_location API below for each chunk.
1327
    */
1328
0
   if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1329
0
   {
1330
      /* Write struct, so unknown chunks come from the app */
1331
0
      png_app_warning(png_ptr,
1332
0
          "png_set_unknown_chunks now expects a valid location");
1333
      /* Use the old behavior */
1334
0
      location = (png_byte)(png_ptr->mode &
1335
0
          (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
1336
0
   }
1337
1338
   /* This need not be an internal error - if the app calls
1339
    * png_set_unknown_chunks on a read pointer it must get the location right.
1340
    */
1341
0
   if (location == 0)
1342
0
      png_error(png_ptr, "invalid location in png_set_unknown_chunks");
1343
1344
   /* Now reduce the location to the top-most set bit by removing each least
1345
    * significant bit in turn.
1346
    */
1347
0
   while (location != (location & -location))
1348
0
      location &= ~(location & -location);
1349
1350
   /* The cast is safe because 'location' is a bit mask and only the low four
1351
    * bits are significant.
1352
    */
1353
0
   return (png_byte)location;
1354
0
}
1355
1356
void PNGAPI
1357
png_set_unknown_chunks(png_const_structrp png_ptr,
1358
    png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
1359
0
{
1360
0
   png_unknown_chunkp np;
1361
1362
0
   if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
1363
0
       unknowns == NULL)
1364
0
      return;
1365
1366
   /* Check for the failure cases where support has been disabled at compile
1367
    * time.  This code is hardly ever compiled - it's here because
1368
    * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this
1369
    * code) but may be meaningless if the read or write handling of unknown
1370
    * chunks is not compiled in.
1371
    */
1372
#  if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
1373
      defined(PNG_READ_SUPPORTED)
1374
      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1375
      {
1376
         png_app_error(png_ptr, "no unknown chunk support on read");
1377
1378
         return;
1379
      }
1380
#  endif
1381
#  if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
1382
      defined(PNG_WRITE_SUPPORTED)
1383
      if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1384
      {
1385
         png_app_error(png_ptr, "no unknown chunk support on write");
1386
1387
         return;
1388
      }
1389
#  endif
1390
1391
   /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that
1392
    * unknown critical chunks could be lost with just a warning resulting in
1393
    * undefined behavior.  Now png_chunk_report is used to provide behavior
1394
    * appropriate to read or write.
1395
    */
1396
0
   np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
1397
0
       info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
1398
0
       sizeof *np));
1399
1400
0
   if (np == NULL)
1401
0
   {
1402
0
      png_chunk_report(png_ptr, "too many unknown chunks",
1403
0
          PNG_CHUNK_WRITE_ERROR);
1404
0
      return;
1405
0
   }
1406
1407
0
   png_free(png_ptr, info_ptr->unknown_chunks);
1408
1409
0
   info_ptr->unknown_chunks = np; /* safe because it is initialized */
1410
0
   info_ptr->free_me |= PNG_FREE_UNKN;
1411
1412
0
   np += info_ptr->unknown_chunks_num;
1413
1414
   /* Increment unknown_chunks_num each time round the loop to protect the
1415
    * just-allocated chunk data.
1416
    */
1417
0
   for (; num_unknowns > 0; --num_unknowns, ++unknowns)
1418
0
   {
1419
0
      memcpy(np->name, unknowns->name, (sizeof np->name));
1420
0
      np->name[(sizeof np->name)-1] = '\0';
1421
0
      np->location = check_location(png_ptr, unknowns->location);
1422
1423
0
      if (unknowns->size == 0)
1424
0
      {
1425
0
         np->data = NULL;
1426
0
         np->size = 0;
1427
0
      }
1428
1429
0
      else
1430
0
      {
1431
0
         np->data = png_voidcast(png_bytep,
1432
0
             png_malloc_base(png_ptr, unknowns->size));
1433
1434
0
         if (np->data == NULL)
1435
0
         {
1436
0
            png_chunk_report(png_ptr, "unknown chunk: out of memory",
1437
0
                PNG_CHUNK_WRITE_ERROR);
1438
            /* But just skip storing the unknown chunk */
1439
0
            continue;
1440
0
         }
1441
1442
0
         memcpy(np->data, unknowns->data, unknowns->size);
1443
0
         np->size = unknowns->size;
1444
0
      }
1445
1446
      /* These increments are skipped on out-of-memory for the data - the
1447
       * unknown chunk entry gets overwritten if the png_chunk_report returns.
1448
       * This is correct in the read case (the chunk is just dropped.)
1449
       */
1450
0
      ++np;
1451
0
      ++(info_ptr->unknown_chunks_num);
1452
0
   }
1453
0
}
1454
1455
void PNGAPI
1456
png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
1457
    int chunk, int location)
1458
0
{
1459
   /* This API is pretty pointless in 1.6.0 because the location can be set
1460
    * before the call to png_set_unknown_chunks.
1461
    *
1462
    * TODO: add a png_app_warning in 1.7
1463
    */
1464
0
   if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&
1465
0
      chunk < info_ptr->unknown_chunks_num)
1466
0
   {
1467
0
      if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
1468
0
      {
1469
0
         png_app_error(png_ptr, "invalid unknown chunk location");
1470
         /* Fake out the pre 1.6.0 behavior: */
1471
0
         if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */
1472
0
            location = PNG_AFTER_IDAT;
1473
1474
0
         else
1475
0
            location = PNG_HAVE_IHDR; /* also undocumented */
1476
0
      }
1477
1478
0
      info_ptr->unknown_chunks[chunk].location =
1479
0
         check_location(png_ptr, location);
1480
0
   }
1481
0
}
1482
#endif /* STORE_UNKNOWN_CHUNKS */
1483
1484
#ifdef PNG_MNG_FEATURES_SUPPORTED
1485
png_uint_32 PNGAPI
1486
png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features)
1487
0
{
1488
0
   png_debug(1, "in png_permit_mng_features");
1489
1490
0
   if (png_ptr == NULL)
1491
0
      return 0;
1492
1493
0
   png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;
1494
1495
0
   return png_ptr->mng_features_permitted;
1496
0
}
1497
#endif
1498
1499
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1500
static unsigned int
1501
add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
1502
11.7k
{
1503
11.7k
   unsigned int i;
1504
1505
   /* Utility function: update the 'keep' state of a chunk if it is already in
1506
    * the list, otherwise add it to the list.
1507
    */
1508
119k
   for (i=0; i<count; ++i, list += 5)
1509
110k
   {
1510
110k
      if (memcmp(list, add, 4) == 0)
1511
2.93k
      {
1512
2.93k
         list[4] = (png_byte)keep;
1513
1514
2.93k
         return count;
1515
2.93k
      }
1516
110k
   }
1517
1518
8.79k
   if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
1519
8.79k
   {
1520
8.79k
      ++count;
1521
8.79k
      memcpy(list, add, 4);
1522
8.79k
      list[4] = (png_byte)keep;
1523
8.79k
   }
1524
1525
8.79k
   return count;
1526
11.7k
}
1527
1528
void PNGAPI
1529
png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
1530
    png_const_bytep chunk_list, int num_chunks_in)
1531
838
{
1532
838
   png_bytep new_list;
1533
838
   unsigned int num_chunks, old_num_chunks;
1534
1535
838
   if (png_ptr == NULL)
1536
0
      return;
1537
1538
838
   if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)
1539
0
   {
1540
0
      png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
1541
1542
0
      return;
1543
0
   }
1544
1545
838
   if (num_chunks_in <= 0)
1546
419
   {
1547
419
      png_ptr->unknown_default = keep;
1548
1549
      /* '0' means just set the flags, so stop here */
1550
419
      if (num_chunks_in == 0)
1551
0
        return;
1552
419
   }
1553
1554
838
   if (num_chunks_in < 0)
1555
419
   {
1556
      /* Ignore all unknown chunks and all chunks recognized by
1557
       * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
1558
       */
1559
419
      static const png_byte chunks_to_ignore[] = {
1560
419
         98,  75,  71,  68, '\0',  /* bKGD */
1561
419
         99,  72,  82,  77, '\0',  /* cHRM */
1562
419
         99,  73,  67,  80, '\0',  /* cICP */
1563
419
         99,  76,  76,  73, '\0',  /* cLLI */
1564
419
        101,  88,  73, 102, '\0',  /* eXIf */
1565
419
        103,  65,  77,  65, '\0',  /* gAMA */
1566
419
        104,  73,  83,  84, '\0',  /* hIST */
1567
419
        105,  67,  67,  80, '\0',  /* iCCP */
1568
419
        105,  84,  88, 116, '\0',  /* iTXt */
1569
419
        109,  68,  67,  86, '\0',  /* mDCV */
1570
419
        111,  70,  70, 115, '\0',  /* oFFs */
1571
419
        112,  67,  65,  76, '\0',  /* pCAL */
1572
419
        112,  72,  89, 115, '\0',  /* pHYs */
1573
419
        115,  66,  73,  84, '\0',  /* sBIT */
1574
419
        115,  67,  65,  76, '\0',  /* sCAL */
1575
419
        115,  80,  76,  84, '\0',  /* sPLT */
1576
419
        115,  84,  69,  82, '\0',  /* sTER */
1577
419
        115,  82,  71,  66, '\0',  /* sRGB */
1578
419
        116,  69,  88, 116, '\0',  /* tEXt */
1579
419
        116,  73,  77,  69, '\0',  /* tIME */
1580
419
        122,  84,  88, 116, '\0'   /* zTXt */
1581
419
      };
1582
1583
419
      chunk_list = chunks_to_ignore;
1584
419
      num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U;
1585
419
   }
1586
1587
419
   else /* num_chunks_in > 0 */
1588
419
   {
1589
419
      if (chunk_list == NULL)
1590
0
      {
1591
         /* Prior to 1.6.0 this was silently ignored, now it is an app_error
1592
          * which can be switched off.
1593
          */
1594
0
         png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
1595
1596
0
         return;
1597
0
      }
1598
1599
419
      num_chunks = (unsigned int)num_chunks_in;
1600
419
   }
1601
1602
838
   old_num_chunks = png_ptr->num_chunk_list;
1603
838
   if (png_ptr->chunk_list == NULL)
1604
419
      old_num_chunks = 0;
1605
1606
   /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.
1607
    */
1608
838
   if (num_chunks + old_num_chunks > UINT_MAX/5)
1609
0
   {
1610
0
      png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
1611
1612
0
      return;
1613
0
   }
1614
1615
   /* If these chunks are being reset to the default then no more memory is
1616
    * required because add_one_chunk above doesn't extend the list if the 'keep'
1617
    * parameter is the default.
1618
    */
1619
838
   if (keep != 0)
1620
419
   {
1621
419
      new_list = png_voidcast(png_bytep, png_malloc(png_ptr,
1622
419
          5 * (num_chunks + old_num_chunks)));
1623
1624
419
      if (old_num_chunks > 0)
1625
0
         memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
1626
419
   }
1627
1628
419
   else if (old_num_chunks > 0)
1629
419
      new_list = png_ptr->chunk_list;
1630
1631
0
   else
1632
0
      new_list = NULL;
1633
1634
   /* Add the new chunks together with each one's handling code.  If the chunk
1635
    * already exists the code is updated, otherwise the chunk is added to the
1636
    * end.  (In libpng 1.6.0 order no longer matters because this code enforces
1637
    * the earlier convention that the last setting is the one that is used.)
1638
    */
1639
838
   if (new_list != NULL)
1640
838
   {
1641
838
      png_const_bytep inlist;
1642
838
      png_bytep outlist;
1643
838
      unsigned int i;
1644
1645
12.5k
      for (i=0; i<num_chunks; ++i)
1646
11.7k
      {
1647
11.7k
         old_num_chunks = add_one_chunk(new_list, old_num_chunks,
1648
11.7k
             chunk_list+5*i, keep);
1649
11.7k
      }
1650
1651
      /* Now remove any spurious 'default' entries. */
1652
838
      num_chunks = 0;
1653
18.4k
      for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5)
1654
17.5k
      {
1655
17.5k
         if (inlist[4])
1656
14.6k
         {
1657
14.6k
            if (outlist != inlist)
1658
5.86k
               memcpy(outlist, inlist, 5);
1659
14.6k
            outlist += 5;
1660
14.6k
            ++num_chunks;
1661
14.6k
         }
1662
17.5k
      }
1663
1664
      /* This means the application has removed all the specialized handling. */
1665
838
      if (num_chunks == 0)
1666
0
      {
1667
0
         if (png_ptr->chunk_list != new_list)
1668
0
            png_free(png_ptr, new_list);
1669
1670
0
         new_list = NULL;
1671
0
      }
1672
838
   }
1673
1674
0
   else
1675
0
      num_chunks = 0;
1676
1677
838
   png_ptr->num_chunk_list = num_chunks;
1678
1679
838
   if (png_ptr->chunk_list != new_list)
1680
419
   {
1681
419
      if (png_ptr->chunk_list != NULL)
1682
0
         png_free(png_ptr, png_ptr->chunk_list);
1683
1684
419
      png_ptr->chunk_list = new_list;
1685
419
   }
1686
838
}
1687
#endif
1688
1689
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1690
void PNGAPI
1691
png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr,
1692
    png_user_chunk_ptr read_user_chunk_fn)
1693
0
{
1694
0
   png_debug(1, "in png_set_read_user_chunk_fn");
1695
1696
0
   if (png_ptr == NULL)
1697
0
      return;
1698
1699
0
   png_ptr->read_user_chunk_fn = read_user_chunk_fn;
1700
0
   png_ptr->user_chunk_ptr = user_chunk_ptr;
1701
0
}
1702
#endif
1703
1704
#ifdef PNG_INFO_IMAGE_SUPPORTED
1705
void PNGAPI
1706
png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
1707
    png_bytepp row_pointers)
1708
0
{
1709
0
   png_debug(1, "in png_set_rows");
1710
1711
0
   if (png_ptr == NULL || info_ptr == NULL)
1712
0
      return;
1713
1714
0
   if (info_ptr->row_pointers != NULL &&
1715
0
       (info_ptr->row_pointers != row_pointers))
1716
0
      png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1717
1718
0
   info_ptr->row_pointers = row_pointers;
1719
1720
0
   if (row_pointers != NULL)
1721
0
      info_ptr->valid |= PNG_INFO_IDAT;
1722
0
}
1723
#endif
1724
1725
void PNGAPI
1726
png_set_compression_buffer_size(png_structrp png_ptr, size_t size)
1727
0
{
1728
0
   png_debug(1, "in png_set_compression_buffer_size");
1729
1730
0
   if (png_ptr == NULL)
1731
0
      return;
1732
1733
0
   if (size == 0 || size > PNG_UINT_31_MAX)
1734
0
      png_error(png_ptr, "invalid compression buffer size");
1735
1736
0
#  ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1737
0
   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1738
0
   {
1739
0
      png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
1740
0
      return;
1741
0
   }
1742
0
#  endif
1743
1744
#  ifdef PNG_WRITE_SUPPORTED
1745
   if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1746
   {
1747
      if (png_ptr->zowner != 0)
1748
      {
1749
         png_warning(png_ptr,
1750
             "Compression buffer size cannot be changed because it is in use");
1751
1752
         return;
1753
      }
1754
1755
#ifndef __COVERITY__
1756
      /* Some compilers complain that this is always false.  However, it
1757
       * can be true when integer overflow happens.
1758
       */
1759
      if (size > ZLIB_IO_MAX)
1760
      {
1761
         png_warning(png_ptr,
1762
             "Compression buffer size limited to system maximum");
1763
         size = ZLIB_IO_MAX; /* must fit */
1764
      }
1765
#endif
1766
1767
      if (size < 6)
1768
      {
1769
         /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
1770
          * if this is permitted.
1771
          */
1772
         png_warning(png_ptr,
1773
             "Compression buffer size cannot be reduced below 6");
1774
1775
         return;
1776
      }
1777
1778
      if (png_ptr->zbuffer_size != size)
1779
      {
1780
         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
1781
         png_ptr->zbuffer_size = (uInt)size;
1782
      }
1783
   }
1784
#  endif
1785
0
}
1786
1787
void PNGAPI
1788
png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
1789
0
{
1790
0
   if (png_ptr != NULL && info_ptr != NULL)
1791
0
      info_ptr->valid &= (unsigned int)(~mask);
1792
0
}
1793
1794
1795
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
1796
/* This function was added to libpng 1.2.6 */
1797
void PNGAPI
1798
png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
1799
    png_uint_32 user_height_max)
1800
0
{
1801
0
   png_debug(1, "in png_set_user_limits");
1802
1803
   /* Images with dimensions larger than these limits will be
1804
    * rejected by png_set_IHDR().  To accept any PNG datastream
1805
    * regardless of dimensions, set both limits to 0x7fffffff.
1806
    */
1807
0
   if (png_ptr == NULL)
1808
0
      return;
1809
1810
0
   png_ptr->user_width_max = user_width_max;
1811
0
   png_ptr->user_height_max = user_height_max;
1812
0
}
1813
1814
/* This function was added to libpng 1.4.0 */
1815
void PNGAPI
1816
png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
1817
0
{
1818
0
   png_debug(1, "in png_set_chunk_cache_max");
1819
1820
0
   if (png_ptr != NULL)
1821
0
      png_ptr->user_chunk_cache_max = user_chunk_cache_max;
1822
0
}
1823
1824
/* This function was added to libpng 1.4.1 */
1825
void PNGAPI
1826
png_set_chunk_malloc_max(png_structrp png_ptr,
1827
    png_alloc_size_t user_chunk_malloc_max)
1828
0
{
1829
0
   png_debug(1, "in png_set_chunk_malloc_max");
1830
1831
   /* pngstruct::user_chunk_malloc_max is initialized to a non-zero value in
1832
    * png.c.  This API supports '0' for unlimited, make sure the correct
1833
    * (unlimited) value is set here to avoid a need to check for 0 everywhere
1834
    * the parameter is used.
1835
    */
1836
0
   if (png_ptr != NULL)
1837
0
   {
1838
0
      if (user_chunk_malloc_max == 0U) /* unlimited */
1839
0
      {
1840
#        ifdef PNG_MAX_MALLOC_64K
1841
            png_ptr->user_chunk_malloc_max = 65536U;
1842
#        else
1843
0
            png_ptr->user_chunk_malloc_max = PNG_SIZE_MAX;
1844
0
#        endif
1845
0
      }
1846
0
      else
1847
0
         png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1848
0
   }
1849
0
}
1850
#endif /* ?SET_USER_LIMITS */
1851
1852
1853
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
1854
void PNGAPI
1855
png_set_benign_errors(png_structrp png_ptr, int allowed)
1856
425
{
1857
425
   png_debug(1, "in png_set_benign_errors");
1858
1859
   /* If allowed is 1, png_benign_error() is treated as a warning.
1860
    *
1861
    * If allowed is 0, png_benign_error() is treated as an error (which
1862
    * is the default behavior if png_set_benign_errors() is not called).
1863
    */
1864
1865
425
   if (allowed != 0)
1866
425
      png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |
1867
425
         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;
1868
1869
0
   else
1870
0
      png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |
1871
0
         PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
1872
425
}
1873
#endif /* BENIGN_ERRORS */
1874
1875
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
1876
   /* Whether to report invalid palette index; added at libng-1.5.10.
1877
    * It is possible for an indexed (color-type==3) PNG file to contain
1878
    * pixels with invalid (out-of-range) indexes if the PLTE chunk has
1879
    * fewer entries than the image's bit-depth would allow. We recover
1880
    * from this gracefully by filling any incomplete palette with zeros
1881
    * (opaque black).  By default, when this occurs libpng will issue
1882
    * a benign error.  This API can be used to override that behavior.
1883
    */
1884
void PNGAPI
1885
png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
1886
0
{
1887
0
   png_debug(1, "in png_set_check_for_invalid_index");
1888
1889
0
   if (allowed > 0)
1890
0
      png_ptr->num_palette_max = 0;
1891
1892
0
   else
1893
0
      png_ptr->num_palette_max = -1;
1894
0
}
1895
#endif
1896
1897
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \
1898
    defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
1899
/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
1900
 * and if invalid, correct the keyword rather than discarding the entire
1901
 * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
1902
 * length, forbids leading or trailing whitespace, multiple internal spaces,
1903
 * and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
1904
 *
1905
 * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
1906
 * trailing '\0').  If this routine returns 0 then there was no keyword, or a
1907
 * valid one could not be generated, and the caller must png_error.
1908
 */
1909
png_uint_32 /* PRIVATE */
1910
png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
1911
0
{
1912
0
#ifdef PNG_WARNINGS_SUPPORTED
1913
0
   png_const_charp orig_key = key;
1914
0
#endif
1915
0
   png_uint_32 key_len = 0;
1916
0
   int bad_character = 0;
1917
0
   int space = 1;
1918
1919
0
   png_debug(1, "in png_check_keyword");
1920
1921
0
   if (key == NULL)
1922
0
   {
1923
0
      *new_key = 0;
1924
0
      return 0;
1925
0
   }
1926
1927
0
   while (*key && key_len < 79)
1928
0
   {
1929
0
      png_byte ch = (png_byte)*key++;
1930
1931
0
      if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
1932
0
      {
1933
0
         *new_key++ = ch; ++key_len; space = 0;
1934
0
      }
1935
1936
0
      else if (space == 0)
1937
0
      {
1938
         /* A space or an invalid character when one wasn't seen immediately
1939
          * before; output just a space.
1940
          */
1941
0
         *new_key++ = 32; ++key_len; space = 1;
1942
1943
         /* If the character was not a space then it is invalid. */
1944
0
         if (ch != 32)
1945
0
            bad_character = ch;
1946
0
      }
1947
1948
0
      else if (bad_character == 0)
1949
0
         bad_character = ch; /* just skip it, record the first error */
1950
0
   }
1951
1952
0
   if (key_len > 0 && space != 0) /* trailing space */
1953
0
   {
1954
0
      --key_len; --new_key;
1955
0
      if (bad_character == 0)
1956
0
         bad_character = 32;
1957
0
   }
1958
1959
   /* Terminate the keyword */
1960
0
   *new_key = 0;
1961
1962
0
   if (key_len == 0)
1963
0
      return 0;
1964
1965
0
#ifdef PNG_WARNINGS_SUPPORTED
1966
   /* Try to only output one warning per keyword: */
1967
0
   if (*key != 0) /* keyword too long */
1968
0
      png_warning(png_ptr, "keyword truncated");
1969
1970
0
   else if (bad_character != 0)
1971
0
   {
1972
0
      PNG_WARNING_PARAMETERS(p)
1973
1974
0
      png_warning_parameter(p, 1, orig_key);
1975
0
      png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
1976
1977
0
      png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
1978
0
   }
1979
#else /* !WARNINGS */
1980
   PNG_UNUSED(png_ptr)
1981
#endif /* !WARNINGS */
1982
1983
0
   return key_len;
1984
0
}
1985
#endif /* TEXT || pCAL || iCCP || sPLT */
1986
#endif /* READ || WRITE */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngstruct.h.html b/part1/report/w_corpus/src/libpng/pngstruct.h.html new file mode 100644 index 0000000..8fb00fe --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngstruct.h.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngstruct.h
Line
Count
Source
1
/* pngstruct.h - internal structures for libpng
2
 *
3
 * Copyright (c) 2018-2025 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 */
12
13
#ifndef PNGPRIV_H
14
#  error This file must not be included by applications; please include <png.h>
15
#endif
16
17
#ifndef PNGSTRUCT_H
18
#define PNGSTRUCT_H
19
/* zlib.h defines the structure z_stream, an instance of which is included
20
 * in this structure and is required for decompressing the LZ compressed
21
 * data in PNG files.
22
 */
23
#ifndef ZLIB_CONST
24
   /* We must ensure that zlib uses 'const' in declarations. */
25
#  define ZLIB_CONST
26
#endif
27
#include "zlib.h"
28
#ifdef const
29
   /* zlib.h sometimes #defines const to nothing, undo this. */
30
#  undef const
31
#endif
32
33
/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
34
 * with older builds.
35
 */
36
#if ZLIB_VERNUM < 0x1260
37
#  define PNGZ_MSG_CAST(s) png_constcast(char*,s)
38
#  define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)
39
#else
40
1.36k
#  define PNGZ_MSG_CAST(s) (s)
41
1.76k
#  define PNGZ_INPUT_CAST(b) (b)
42
#endif
43
44
/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
45
 * can handle at once.  This type need be no larger than 16 bits (so maximum of
46
 * 65535), this define allows us to discover how big it is, but limited by the
47
 * maximum for size_t.  The value can be overridden in a library build
48
 * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
49
 * lower value (e.g. 255 works).  A lower value may help memory usage (slightly)
50
 * and may even improve performance on some systems (and degrade it on others.)
51
 */
52
#ifndef ZLIB_IO_MAX
53
123k
#  define ZLIB_IO_MAX ((uInt)-1)
54
#endif
55
56
#ifdef PNG_WRITE_SUPPORTED
57
/* The type of a compression buffer list used by the write code. */
58
typedef struct png_compression_buffer
59
{
60
   struct png_compression_buffer *next;
61
   png_byte                       output[1]; /* actually zbuf_size */
62
} png_compression_buffer, *png_compression_bufferp;
63
64
#define PNG_COMPRESSION_BUFFER_SIZE(pp)\
65
   (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)
66
#endif
67
68
/* Colorspace support; structures used in png_struct, png_info and in internal
69
 * functions to hold and communicate information about the color space.
70
 */
71
/* The chromaticities of the red, green and blue colorants and the chromaticity
72
 * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
73
 */
74
typedef struct png_xy
75
{
76
   png_fixed_point redx, redy;
77
   png_fixed_point greenx, greeny;
78
   png_fixed_point bluex, bluey;
79
   png_fixed_point whitex, whitey;
80
} png_xy;
81
82
/* The same data as above but encoded as CIE XYZ values.  When this data comes
83
 * from chromaticities the sum of the Y values is assumed to be 1.0
84
 */
85
typedef struct png_XYZ
86
{
87
   png_fixed_point red_X, red_Y, red_Z;
88
   png_fixed_point green_X, green_Y, green_Z;
89
   png_fixed_point blue_X, blue_Y, blue_Z;
90
} png_XYZ;
91
92
/* Chunk index values as an enum, PNG_INDEX_unknown is also a count of the
93
 * number of chunks.
94
 */
95
#define PNG_CHUNK(cHNK, i) PNG_INDEX_ ## cHNK = (i),
96
typedef enum
97
{
98
   PNG_KNOWN_CHUNKS
99
   PNG_INDEX_unknown
100
} png_index;
101
#undef PNG_CHUNK
102
103
/* Chunk flag values.  These are (png_uint_32 values) with exactly one bit set
104
 * and can be combined into a flag set with bitwise 'or'.
105
 *
106
 * TODO: C23: convert these macros to C23 inlines (which are static).
107
 */
108
37.0k
#define png_chunk_flag_from_index(i) (0x80000000U >> (31 - (i)))
109
   /* The flag coresponding to the given png_index enum value.  This is defined
110
    * for png_unknown as well (until it reaches the value 32) but this should
111
    * not be relied on.
112
    */
113
114
#define png_file_has_chunk(png_ptr, i)\
115
25.1k
   (((png_ptr)->chunks & png_chunk_flag_from_index(i)) != 0)
116
   /* The chunk has been recorded in png_struct */
117
118
#define png_file_add_chunk(pnt_ptr, i)\
119
12.4k
   ((void)((png_ptr)->chunks |= png_chunk_flag_from_index(i)))
120
   /* Record the chunk in the png_struct */
121
122
struct png_struct_def
123
{
124
#ifdef PNG_SETJMP_SUPPORTED
125
   jmp_buf jmp_buf_local;     /* New name in 1.6.0 for jmp_buf in png_struct */
126
   png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
127
   jmp_buf *jmp_buf_ptr;      /* passed to longjmp_fn */
128
   size_t jmp_buf_size;       /* size of the above, if allocated */
129
#endif
130
   png_error_ptr error_fn;    /* function for printing errors and aborting */
131
#ifdef PNG_WARNINGS_SUPPORTED
132
   png_error_ptr warning_fn;  /* function for printing warnings */
133
#endif
134
   png_voidp error_ptr;       /* user supplied struct for error functions */
135
   png_rw_ptr write_data_fn;  /* function for writing output data */
136
   png_rw_ptr read_data_fn;   /* function for reading input data */
137
   png_voidp io_ptr;          /* ptr to application struct for I/O functions */
138
139
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
140
   png_user_transform_ptr read_user_transform_fn; /* user read transform */
141
#endif
142
143
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
144
   png_user_transform_ptr write_user_transform_fn; /* user write transform */
145
#endif
146
147
/* These were added in libpng-1.0.2 */
148
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
149
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
150
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
151
   png_voidp user_transform_ptr; /* user supplied struct for user transform */
152
   png_byte user_transform_depth;    /* bit depth of user transformed pixels */
153
   png_byte user_transform_channels; /* channels in user transformed pixels */
154
#endif
155
#endif
156
157
   png_uint_32 mode;          /* tells us where we are in the PNG file */
158
   png_uint_32 flags;         /* flags indicating various things to libpng */
159
   png_uint_32 transformations; /* which transformations to perform */
160
161
   png_uint_32 zowner;        /* ID (chunk type) of zstream owner, 0 if none */
162
   z_stream    zstream;       /* decompression structure */
163
164
#ifdef PNG_WRITE_SUPPORTED
165
   png_compression_bufferp zbuffer_list; /* Created on demand during write */
166
   uInt                    zbuffer_size; /* size of the actual buffer */
167
168
   int zlib_level;            /* holds zlib compression level */
169
   int zlib_method;           /* holds zlib compression method */
170
   int zlib_window_bits;      /* holds zlib compression window bits */
171
   int zlib_mem_level;        /* holds zlib compression memory level */
172
   int zlib_strategy;         /* holds zlib compression strategy */
173
#endif
174
/* Added at libpng 1.5.4 */
175
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
176
   int zlib_text_level;            /* holds zlib compression level */
177
   int zlib_text_method;           /* holds zlib compression method */
178
   int zlib_text_window_bits;      /* holds zlib compression window bits */
179
   int zlib_text_mem_level;        /* holds zlib compression memory level */
180
   int zlib_text_strategy;         /* holds zlib compression strategy */
181
#endif
182
/* End of material added at libpng 1.5.4 */
183
/* Added at libpng 1.6.0 */
184
#ifdef PNG_WRITE_SUPPORTED
185
   int zlib_set_level;        /* Actual values set into the zstream on write */
186
   int zlib_set_method;
187
   int zlib_set_window_bits;
188
   int zlib_set_mem_level;
189
   int zlib_set_strategy;
190
#endif
191
192
   png_uint_32 chunks; /* PNG_CF_ for every chunk read or (NYI) written */
193
#  define png_has_chunk(png_ptr, cHNK)\
194
1.81k
      png_file_has_chunk(png_ptr, PNG_INDEX_ ## cHNK)
195
      /* Convenience accessor - use this to check for a known chunk by name */
196
197
   png_uint_32 width;         /* width of image in pixels */
198
   png_uint_32 height;        /* height of image in pixels */
199
   png_uint_32 num_rows;      /* number of rows in current pass */
200
   png_uint_32 usr_width;     /* width of row at start of write */
201
   size_t rowbytes;           /* size of row in bytes */
202
   png_uint_32 iwidth;        /* width of current interlaced row in pixels */
203
   png_uint_32 row_number;    /* current row in interlace pass */
204
   png_uint_32 chunk_name;    /* PNG_CHUNK() id of current chunk */
205
   png_bytep prev_row;        /* buffer to save previous (unfiltered) row.
206
                               * While reading this is a pointer into
207
                               * big_prev_row; while writing it is separately
208
                               * allocated if needed.
209
                               */
210
   png_bytep row_buf;         /* buffer to save current (unfiltered) row.
211
                               * While reading, this is a pointer into
212
                               * big_row_buf; while writing it is separately
213
                               * allocated.
214
                               */
215
#ifdef PNG_WRITE_FILTER_SUPPORTED
216
   png_bytep try_row;    /* buffer to save trial row when filtering */
217
   png_bytep tst_row;    /* buffer to save best trial row when filtering */
218
#endif
219
   size_t info_rowbytes;      /* Added in 1.5.4: cache of updated row bytes */
220
221
   png_uint_32 idat_size;     /* current IDAT size for read */
222
   png_uint_32 crc;           /* current chunk CRC value */
223
   png_colorp palette;        /* palette from the input file */
224
   png_uint_16 num_palette;   /* number of color entries in palette */
225
226
/* Added at libpng-1.5.10 */
227
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
228
   int num_palette_max;       /* maximum palette index found in IDAT */
229
#endif
230
231
   png_uint_16 num_trans;     /* number of transparency values */
232
   png_byte compression;      /* file compression type (always 0) */
233
   png_byte filter;           /* file filter type (always 0) */
234
   png_byte interlaced;       /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
235
   png_byte pass;             /* current interlace pass (0 - 6) */
236
   png_byte do_filter;        /* row filter flags (see PNG_FILTER_ in png.h ) */
237
   png_byte color_type;       /* color type of file */
238
   png_byte bit_depth;        /* bit depth of file */
239
   png_byte usr_bit_depth;    /* bit depth of users row: write only */
240
   png_byte pixel_depth;      /* number of bits per pixel */
241
   png_byte channels;         /* number of channels in file */
242
#ifdef PNG_WRITE_SUPPORTED
243
   png_byte usr_channels;     /* channels at start of write: write only */
244
#endif
245
   png_byte sig_bytes;        /* magic bytes read/written from start of file */
246
   png_byte maximum_pixel_depth;
247
                              /* pixel depth used for the row buffers */
248
   png_byte transformed_pixel_depth;
249
                              /* pixel depth after read/write transforms */
250
#if ZLIB_VERNUM >= 0x1240
251
   png_byte zstream_start;    /* at start of an input zlib stream */
252
#endif /* Zlib >= 1.2.4 */
253
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
254
   png_uint_16 filler;           /* filler bytes for pixel expansion */
255
#endif
256
257
#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
258
   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
259
   png_byte background_gamma_type;
260
   png_fixed_point background_gamma;
261
   png_color_16 background;   /* background color in screen gamma space */
262
#ifdef PNG_READ_GAMMA_SUPPORTED
263
   png_color_16 background_1; /* background normalized to gamma 1.0 */
264
#endif
265
#endif /* bKGD */
266
267
#ifdef PNG_WRITE_FLUSH_SUPPORTED
268
   png_flush_ptr output_flush_fn; /* Function for flushing output */
269
   png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
270
   png_uint_32 flush_rows;    /* number of rows written since last flush */
271
#endif
272
273
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
274
   png_xy          chromaticities; /* From mDVC, cICP, [iCCP], sRGB or cHRM */
275
#endif
276
277
#ifdef PNG_READ_GAMMA_SUPPORTED
278
   int gamma_shift;      /* number of "insignificant" bits in 16-bit gamma */
279
   png_fixed_point screen_gamma; /* screen gamma value (display exponent) */
280
   png_fixed_point file_gamma;   /* file gamma value (encoding exponent) */
281
   png_fixed_point chunk_gamma;  /* from cICP, iCCP, sRGB or gAMA */
282
   png_fixed_point default_gamma;/* from png_set_alpha_mode */
283
284
   png_bytep gamma_table;     /* gamma table for 8-bit depth files */
285
   png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
286
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
287
   defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
288
   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
289
   png_bytep gamma_from_1;    /* converts from 1.0 to screen */
290
   png_bytep gamma_to_1;      /* converts from file to 1.0 */
291
   png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
292
   png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
293
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
294
#endif /* READ_GAMMA */
295
296
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
297
   png_color_8 sig_bit;       /* significant bits in each available channel */
298
#endif
299
300
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
301
   png_color_8 shift;         /* shift for significant bit transformation */
302
#endif
303
304
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
305
 || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
306
   png_bytep trans_alpha;           /* alpha values for paletted files */
307
   png_color_16 trans_color;  /* transparent color for non-paletted files */
308
#endif
309
310
   png_read_status_ptr read_row_fn;   /* called after each row is decoded */
311
   png_write_status_ptr write_row_fn; /* called after each row is encoded */
312
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
313
   png_progressive_info_ptr info_fn; /* called after header data fully read */
314
   png_progressive_row_ptr row_fn;   /* called after a prog. row is decoded */
315
   png_progressive_end_ptr end_fn;   /* called after image is complete */
316
   png_bytep save_buffer_ptr;        /* current location in save_buffer */
317
   png_bytep save_buffer;            /* buffer for previously read data */
318
   png_bytep current_buffer_ptr;     /* current location in current_buffer */
319
   png_bytep current_buffer;         /* buffer for recently used data */
320
   png_uint_32 push_length;          /* size of current input chunk */
321
   png_uint_32 skip_length;          /* bytes to skip in input data */
322
   size_t save_buffer_size;          /* amount of data now in save_buffer */
323
   size_t save_buffer_max;           /* total size of save_buffer */
324
   size_t buffer_size;               /* total amount of available input data */
325
   size_t current_buffer_size;       /* amount of data now in current_buffer */
326
   int process_mode;                 /* what push library is currently doing */
327
   int cur_palette;                  /* current push library palette index */
328
#endif /* PROGRESSIVE_READ */
329
330
#ifdef PNG_READ_QUANTIZE_SUPPORTED
331
   png_bytep palette_lookup; /* lookup table for quantizing */
332
   png_bytep quantize_index; /* index translation for palette files */
333
#endif
334
335
/* Options */
336
#ifdef PNG_SET_OPTION_SUPPORTED
337
   png_uint_32 options;           /* On/off state (up to 16 options) */
338
#endif
339
340
#if PNG_LIBPNG_VER < 10700
341
/* To do: remove this from libpng-1.7 */
342
#ifdef PNG_TIME_RFC1123_SUPPORTED
343
   char time_buffer[29]; /* String to hold RFC 1123 time text */
344
#endif /* TIME_RFC1123 */
345
#endif /* LIBPNG_VER < 10700 */
346
347
/* New members added in libpng-1.0.6 */
348
349
   png_uint_32 free_me;    /* flags items libpng is responsible for freeing */
350
351
#ifdef PNG_USER_CHUNKS_SUPPORTED
352
   png_voidp user_chunk_ptr;
353
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
354
   png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
355
#endif /* READ_USER_CHUNKS */
356
#endif /* USER_CHUNKS */
357
358
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
359
   int          unknown_default; /* As PNG_HANDLE_* */
360
   unsigned int num_chunk_list;  /* Number of entries in the list */
361
   png_bytep    chunk_list;      /* List of png_byte[5]; the textual chunk name
362
                                  * followed by a PNG_HANDLE_* byte */
363
#endif
364
365
/* New members added in libpng-1.0.3 */
366
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
367
   png_byte rgb_to_gray_status;
368
   /* Added in libpng 1.5.5 to record setting of coefficients: */
369
   png_byte rgb_to_gray_coefficients_set;
370
   /* These were changed from png_byte in libpng-1.0.6 */
371
   png_uint_16 rgb_to_gray_red_coeff;
372
   png_uint_16 rgb_to_gray_green_coeff;
373
   /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
374
#endif
375
376
/* New member added in libpng-1.6.36 */
377
#if defined(PNG_READ_EXPAND_SUPPORTED) && \
378
    defined(PNG_ARM_NEON_IMPLEMENTATION)
379
   png_bytep riffled_palette; /* buffer for accelerated palette expansion */
380
#endif
381
382
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
383
#if defined(PNG_MNG_FEATURES_SUPPORTED)
384
/* Changed from png_byte to png_uint_32 at version 1.2.0 */
385
   png_uint_32 mng_features_permitted;
386
#endif
387
388
/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
389
#ifdef PNG_MNG_FEATURES_SUPPORTED
390
   png_byte filter_type;
391
#endif
392
393
/* New members added in libpng-1.2.0 */
394
395
/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
396
#ifdef PNG_USER_MEM_SUPPORTED
397
   png_voidp mem_ptr;             /* user supplied struct for mem functions */
398
   png_malloc_ptr malloc_fn;      /* function for allocating memory */
399
   png_free_ptr free_fn;          /* function for freeing memory */
400
#endif
401
402
/* New member added in libpng-1.0.13 and 1.2.0 */
403
   png_bytep big_row_buf;         /* buffer to save current (unfiltered) row */
404
405
#ifdef PNG_READ_QUANTIZE_SUPPORTED
406
/* The following three members were added at version 1.0.14 and 1.2.4 */
407
   png_bytep quantize_sort;          /* working sort array */
408
   png_bytep index_to_palette;       /* where the original index currently is
409
                                        in the palette */
410
   png_bytep palette_to_index;       /* which original index points to this
411
                                         palette color */
412
#endif
413
414
/* New members added in libpng-1.0.16 and 1.2.6 */
415
   png_byte compression_type;
416
417
#ifdef PNG_USER_LIMITS_SUPPORTED
418
   png_uint_32 user_width_max;
419
   png_uint_32 user_height_max;
420
421
   /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
422
    * chunks that can be stored (0 means unlimited).
423
    */
424
   png_uint_32 user_chunk_cache_max;
425
426
   /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
427
    * can occupy when decompressed.  0 means unlimited.
428
    */
429
   png_alloc_size_t user_chunk_malloc_max;
430
#endif
431
432
/* New member added in libpng-1.0.25 and 1.2.17 */
433
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
434
   /* Temporary storage for unknown chunk that the library doesn't recognize,
435
    * used while reading the chunk.
436
    */
437
   png_unknown_chunk unknown_chunk;
438
#endif
439
440
/* New member added in libpng-1.2.26 */
441
   size_t old_big_row_buf_size;
442
443
#ifdef PNG_READ_SUPPORTED
444
/* New member added in libpng-1.2.30 */
445
  png_bytep        read_buffer;      /* buffer for reading chunk data */
446
  png_alloc_size_t read_buffer_size; /* current size of the buffer */
447
#endif
448
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
449
  uInt             IDAT_read_size;   /* limit on read buffer size for IDAT */
450
#endif
451
452
#ifdef PNG_IO_STATE_SUPPORTED
453
/* New member added in libpng-1.4.0 */
454
   png_uint_32 io_state;
455
#endif
456
457
/* New member added in libpng-1.5.6 */
458
   png_bytep big_prev_row;
459
460
/* New member added in libpng-1.5.7 */
461
   void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
462
      png_bytep row, png_const_bytep prev_row);
463
};
464
#endif /* PNGSTRUCT_H */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/pngtrans.c.html b/part1/report/w_corpus/src/libpng/pngtrans.c.html new file mode 100644 index 0000000..a72f5ee --- /dev/null +++ b/part1/report/w_corpus/src/libpng/pngtrans.c.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2025-05-14 15:03

/src/libpng/pngtrans.c
Line
Count
Source (jump to first uncovered line)
1
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
2
 *
3
 * Copyright (c) 2018-2024 Cosmin Truta
4
 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
5
 * Copyright (c) 1996-1997 Andreas Dilger
6
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 */
12
13
#include "pngpriv.h"
14
15
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
16
17
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
18
/* Turn on BGR-to-RGB mapping */
19
void PNGAPI
20
png_set_bgr(png_structrp png_ptr)
21
0
{
22
0
   png_debug(1, "in png_set_bgr");
23
24
0
   if (png_ptr == NULL)
25
0
      return;
26
27
0
   png_ptr->transformations |= PNG_BGR;
28
0
}
29
#endif
30
31
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
32
/* Turn on 16-bit byte swapping */
33
void PNGAPI
34
png_set_swap(png_structrp png_ptr)
35
0
{
36
0
   png_debug(1, "in png_set_swap");
37
38
0
   if (png_ptr == NULL)
39
0
      return;
40
41
0
   if (png_ptr->bit_depth == 16)
42
0
      png_ptr->transformations |= PNG_SWAP_BYTES;
43
0
}
44
#endif
45
46
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
47
/* Turn on pixel packing */
48
void PNGAPI
49
png_set_packing(png_structrp png_ptr)
50
969
{
51
969
   png_debug(1, "in png_set_packing");
52
53
969
   if (png_ptr == NULL)
54
0
      return;
55
56
969
   if (png_ptr->bit_depth < 8)
57
452
   {
58
452
      png_ptr->transformations |= PNG_PACK;
59
#     ifdef PNG_WRITE_SUPPORTED
60
         png_ptr->usr_bit_depth = 8;
61
#     endif
62
452
   }
63
969
}
64
#endif
65
66
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
67
/* Turn on packed pixel swapping */
68
void PNGAPI
69
png_set_packswap(png_structrp png_ptr)
70
0
{
71
0
   png_debug(1, "in png_set_packswap");
72
73
0
   if (png_ptr == NULL)
74
0
      return;
75
76
0
   if (png_ptr->bit_depth < 8)
77
0
      png_ptr->transformations |= PNG_PACKSWAP;
78
0
}
79
#endif
80
81
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
82
void PNGAPI
83
png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
84
0
{
85
0
   png_debug(1, "in png_set_shift");
86
87
0
   if (png_ptr == NULL)
88
0
      return;
89
90
0
   png_ptr->transformations |= PNG_SHIFT;
91
0
   png_ptr->shift = *true_bits;
92
0
}
93
#endif
94
95
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
96
    defined(PNG_WRITE_INTERLACING_SUPPORTED)
97
int PNGAPI
98
png_set_interlace_handling(png_structrp png_ptr)
99
1.38k
{
100
1.38k
   png_debug(1, "in png_set_interlace handling");
101
102
1.38k
   if (png_ptr != 0 && png_ptr->interlaced != 0)
103
407
   {
104
407
      png_ptr->transformations |= PNG_INTERLACE;
105
407
      return 7;
106
407
   }
107
108
981
   return 1;
109
1.38k
}
110
#endif
111
112
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
113
/* Add a filler byte on read, or remove a filler or alpha byte on write.
114
 * The filler type has changed in v0.95 to allow future 2-byte fillers
115
 * for 48-bit input data, as well as to avoid problems with some compilers
116
 * that don't like bytes as parameters.
117
 */
118
void PNGAPI
119
png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
120
179
{
121
179
   png_debug(1, "in png_set_filler");
122
123
179
   if (png_ptr == NULL)
124
0
      return;
125
126
   /* In libpng 1.6 it is possible to determine whether this is a read or write
127
    * operation and therefore to do more checking here for a valid call.
128
    */
129
179
   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
130
179
   {
131
179
#     ifdef PNG_READ_FILLER_SUPPORTED
132
         /* On read png_set_filler is always valid, regardless of the base PNG
133
          * format, because other transformations can give a format where the
134
          * filler code can execute (basically an 8 or 16-bit component RGB or G
135
          * format.)
136
          *
137
          * NOTE: usr_channels is not used by the read code!  (This has led to
138
          * confusion in the past.)  The filler is only used in the read code.
139
          */
140
179
         png_ptr->filler = (png_uint_16)filler;
141
#     else
142
         png_app_error(png_ptr, "png_set_filler not supported on read");
143
         PNG_UNUSED(filler) /* not used in the write case */
144
         return;
145
#     endif
146
179
   }
147
148
0
   else /* write */
149
0
   {
150
#     ifdef PNG_WRITE_FILLER_SUPPORTED
151
         /* On write the usr_channels parameter must be set correctly at the
152
          * start to record the number of channels in the app-supplied data.
153
          */
154
         switch (png_ptr->color_type)
155
         {
156
            case PNG_COLOR_TYPE_RGB:
157
               png_ptr->usr_channels = 4;
158
               break;
159
160
            case PNG_COLOR_TYPE_GRAY:
161
               if (png_ptr->bit_depth >= 8)
162
               {
163
                  png_ptr->usr_channels = 2;
164
                  break;
165
               }
166
167
               else
168
               {
169
                  /* There simply isn't any code in libpng to strip out bits
170
                   * from bytes when the components are less than a byte in
171
                   * size!
172
                   */
173
                  png_app_error(png_ptr,
174
                      "png_set_filler is invalid for"
175
                      " low bit depth gray output");
176
                  return;
177
               }
178
179
            default:
180
               png_app_error(png_ptr,
181
                   "png_set_filler: inappropriate color type");
182
               return;
183
         }
184
#     else
185
0
         png_app_error(png_ptr, "png_set_filler not supported on write");
186
0
         return;
187
0
#     endif
188
0
   }
189
190
   /* Here on success - libpng supports the operation, set the transformation
191
    * and the flag to say where the filler channel is.
192
    */
193
179
   png_ptr->transformations |= PNG_FILLER;
194
195
179
   if (filler_loc == PNG_FILLER_AFTER)
196
179
      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
197
198
0
   else
199
0
      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
200
179
}
201
202
/* Added to libpng-1.2.7 */
203
void PNGAPI
204
png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
205
179
{
206
179
   png_debug(1, "in png_set_add_alpha");
207
208
179
   if (png_ptr == NULL)
209
0
      return;
210
211
179
   png_set_filler(png_ptr, filler, filler_loc);
212
   /* The above may fail to do anything. */
213
179
   if ((png_ptr->transformations & PNG_FILLER) != 0)
214
179
      png_ptr->transformations |= PNG_ADD_ALPHA;
215
179
}
216
217
#endif
218
219
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
220
    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
221
void PNGAPI
222
png_set_swap_alpha(png_structrp png_ptr)
223
0
{
224
0
   png_debug(1, "in png_set_swap_alpha");
225
226
0
   if (png_ptr == NULL)
227
0
      return;
228
229
0
   png_ptr->transformations |= PNG_SWAP_ALPHA;
230
0
}
231
#endif
232
233
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
234
    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
235
void PNGAPI
236
png_set_invert_alpha(png_structrp png_ptr)
237
0
{
238
0
   png_debug(1, "in png_set_invert_alpha");
239
240
0
   if (png_ptr == NULL)
241
0
      return;
242
243
0
   png_ptr->transformations |= PNG_INVERT_ALPHA;
244
0
}
245
#endif
246
247
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
248
void PNGAPI
249
png_set_invert_mono(png_structrp png_ptr)
250
0
{
251
0
   png_debug(1, "in png_set_invert_mono");
252
253
0
   if (png_ptr == NULL)
254
0
      return;
255
256
0
   png_ptr->transformations |= PNG_INVERT_MONO;
257
0
}
258
259
/* Invert monochrome grayscale data */
260
void /* PRIVATE */
261
png_do_invert(png_row_infop row_info, png_bytep row)
262
0
{
263
0
   png_debug(1, "in png_do_invert");
264
265
  /* This test removed from libpng version 1.0.13 and 1.2.0:
266
   *   if (row_info->bit_depth == 1 &&
267
   */
268
0
   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
269
0
   {
270
0
      png_bytep rp = row;
271
0
      size_t i;
272
0
      size_t istop = row_info->rowbytes;
273
274
0
      for (i = 0; i < istop; i++)
275
0
      {
276
0
         *rp = (png_byte)(~(*rp));
277
0
         rp++;
278
0
      }
279
0
   }
280
281
0
   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
282
0
      row_info->bit_depth == 8)
283
0
   {
284
0
      png_bytep rp = row;
285
0
      size_t i;
286
0
      size_t istop = row_info->rowbytes;
287
288
0
      for (i = 0; i < istop; i += 2)
289
0
      {
290
0
         *rp = (png_byte)(~(*rp));
291
0
         rp += 2;
292
0
      }
293
0
   }
294
295
0
#ifdef PNG_16BIT_SUPPORTED
296
0
   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
297
0
      row_info->bit_depth == 16)
298
0
   {
299
0
      png_bytep rp = row;
300
0
      size_t i;
301
0
      size_t istop = row_info->rowbytes;
302
303
0
      for (i = 0; i < istop; i += 4)
304
0
      {
305
0
         *rp = (png_byte)(~(*rp));
306
0
         *(rp + 1) = (png_byte)(~(*(rp + 1)));
307
0
         rp += 4;
308
0
      }
309
0
   }
310
0
#endif
311
0
}
312
#endif
313
314
#ifdef PNG_16BIT_SUPPORTED
315
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
316
/* Swaps byte order on 16-bit depth images */
317
void /* PRIVATE */
318
png_do_swap(png_row_infop row_info, png_bytep row)
319
0
{
320
0
   png_debug(1, "in png_do_swap");
321
322
0
   if (row_info->bit_depth == 16)
323
0
   {
324
0
      png_bytep rp = row;
325
0
      png_uint_32 i;
326
0
      png_uint_32 istop= row_info->width * row_info->channels;
327
328
0
      for (i = 0; i < istop; i++, rp += 2)
329
0
      {
330
#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
331
         /* Feature added to libpng-1.6.11 for testing purposes, not
332
          * enabled by default.
333
          */
334
         *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
335
#else
336
0
         png_byte t = *rp;
337
0
         *rp = *(rp + 1);
338
0
         *(rp + 1) = t;
339
0
#endif
340
0
      }
341
0
   }
342
0
}
343
#endif
344
#endif
345
346
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
347
static const png_byte onebppswaptable[256] = {
348
   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
349
   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
350
   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
351
   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
352
   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
353
   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
354
   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
355
   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
356
   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
357
   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
358
   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
359
   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
360
   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
361
   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
362
   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
363
   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
364
   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
365
   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
366
   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
367
   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
368
   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
369
   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
370
   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
371
   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
372
   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
373
   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
374
   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
375
   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
376
   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
377
   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
378
   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
379
   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
380
};
381
382
static const png_byte twobppswaptable[256] = {
383
   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
384
   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
385
   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
386
   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
387
   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
388
   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
389
   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
390
   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
391
   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
392
   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
393
   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
394
   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
395
   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
396
   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
397
   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
398
   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
399
   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
400
   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
401
   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
402
   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
403
   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
404
   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
405
   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
406
   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
407
   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
408
   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
409
   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
410
   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
411
   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
412
   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
413
   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
414
   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
415
};
416
417
static const png_byte fourbppswaptable[256] = {
418
   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
419
   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
420
   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
421
   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
422
   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
423
   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
424
   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
425
   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
426
   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
427
   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
428
   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
429
   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
430
   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
431
   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
432
   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
433
   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
434
   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
435
   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
436
   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
437
   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
438
   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
439
   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
440
   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
441
   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
442
   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
443
   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
444
   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
445
   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
446
   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
447
   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
448
   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
449
   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
450
};
451
452
/* Swaps pixel packing order within bytes */
453
void /* PRIVATE */
454
png_do_packswap(png_row_infop row_info, png_bytep row)
455
0
{
456
0
   png_debug(1, "in png_do_packswap");
457
458
0
   if (row_info->bit_depth < 8)
459
0
   {
460
0
      png_bytep rp;
461
0
      png_const_bytep end, table;
462
463
0
      end = row + row_info->rowbytes;
464
465
0
      if (row_info->bit_depth == 1)
466
0
         table = onebppswaptable;
467
468
0
      else if (row_info->bit_depth == 2)
469
0
         table = twobppswaptable;
470
471
0
      else if (row_info->bit_depth == 4)
472
0
         table = fourbppswaptable;
473
474
0
      else
475
0
         return;
476
477
0
      for (rp = row; rp < end; rp++)
478
0
         *rp = table[*rp];
479
0
   }
480
0
}
481
#endif /* PACKSWAP || WRITE_PACKSWAP */
482
483
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
484
    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
485
/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
486
 * somewhat weird combination of flags to determine what to do.  All the calls
487
 * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
488
 * correct arguments.
489
 *
490
 * The routine isn't general - the channel must be the channel at the start or
491
 * end (not in the middle) of each pixel.
492
 */
493
void /* PRIVATE */
494
png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
495
0
{
496
0
   png_bytep sp = row; /* source pointer */
497
0
   png_bytep dp = row; /* destination pointer */
498
0
   png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
499
500
0
   png_debug(1, "in png_do_strip_channel");
501
502
   /* At the start sp will point to the first byte to copy and dp to where
503
    * it is copied to.  ep always points just beyond the end of the row, so
504
    * the loop simply copies (channels-1) channels until sp reaches ep.
505
    *
506
    * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
507
    *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
508
    */
509
510
   /* GA, GX, XG cases */
511
0
   if (row_info->channels == 2)
512
0
   {
513
0
      if (row_info->bit_depth == 8)
514
0
      {
515
0
         if (at_start != 0) /* Skip initial filler */
516
0
            ++sp;
517
0
         else          /* Skip initial channel and, for sp, the filler */
518
0
         {
519
0
            sp += 2; ++dp;
520
0
         }
521
522
         /* For a 1 pixel wide image there is nothing to do */
523
0
         while (sp < ep)
524
0
         {
525
0
            *dp++ = *sp; sp += 2;
526
0
         }
527
528
0
         row_info->pixel_depth = 8;
529
0
      }
530
531
0
      else if (row_info->bit_depth == 16)
532
0
      {
533
0
         if (at_start != 0) /* Skip initial filler */
534
0
            sp += 2;
535
0
         else          /* Skip initial channel and, for sp, the filler */
536
0
         {
537
0
            sp += 4; dp += 2;
538
0
         }
539
540
0
         while (sp < ep)
541
0
         {
542
0
            *dp++ = *sp++; *dp++ = *sp; sp += 3;
543
0
         }
544
545
0
         row_info->pixel_depth = 16;
546
0
      }
547
548
0
      else
549
0
         return; /* bad bit depth */
550
551
0
      row_info->channels = 1;
552
553
      /* Finally fix the color type if it records an alpha channel */
554
0
      if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
555
0
         row_info->color_type = PNG_COLOR_TYPE_GRAY;
556
0
   }
557
558
   /* RGBA, RGBX, XRGB cases */
559
0
   else if (row_info->channels == 4)
560
0
   {
561
0
      if (row_info->bit_depth == 8)
562
0
      {
563
0
         if (at_start != 0) /* Skip initial filler */
564
0
            ++sp;
565
0
         else          /* Skip initial channels and, for sp, the filler */
566
0
         {
567
0
            sp += 4; dp += 3;
568
0
         }
569
570
         /* Note that the loop adds 3 to dp and 4 to sp each time. */
571
0
         while (sp < ep)
572
0
         {
573
0
            *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
574
0
         }
575
576
0
         row_info->pixel_depth = 24;
577
0
      }
578
579
0
      else if (row_info->bit_depth == 16)
580
0
      {
581
0
         if (at_start != 0) /* Skip initial filler */
582
0
            sp += 2;
583
0
         else          /* Skip initial channels and, for sp, the filler */
584
0
         {
585
0
            sp += 8; dp += 6;
586
0
         }
587
588
0
         while (sp < ep)
589
0
         {
590
            /* Copy 6 bytes, skip 2 */
591
0
            *dp++ = *sp++; *dp++ = *sp++;
592
0
            *dp++ = *sp++; *dp++ = *sp++;
593
0
            *dp++ = *sp++; *dp++ = *sp; sp += 3;
594
0
         }
595
596
0
         row_info->pixel_depth = 48;
597
0
      }
598
599
0
      else
600
0
         return; /* bad bit depth */
601
602
0
      row_info->channels = 3;
603
604
      /* Finally fix the color type if it records an alpha channel */
605
0
      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
606
0
         row_info->color_type = PNG_COLOR_TYPE_RGB;
607
0
   }
608
609
0
   else
610
0
      return; /* The filler channel has gone already */
611
612
   /* Fix the rowbytes value. */
613
0
   row_info->rowbytes = (size_t)(dp-row);
614
0
}
615
#endif
616
617
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
618
/* Swaps red and blue bytes within a pixel */
619
void /* PRIVATE */
620
png_do_bgr(png_row_infop row_info, png_bytep row)
621
0
{
622
0
   png_debug(1, "in png_do_bgr");
623
624
0
   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
625
0
   {
626
0
      png_uint_32 row_width = row_info->width;
627
0
      if (row_info->bit_depth == 8)
628
0
      {
629
0
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
630
0
         {
631
0
            png_bytep rp;
632
0
            png_uint_32 i;
633
634
0
            for (i = 0, rp = row; i < row_width; i++, rp += 3)
635
0
            {
636
0
               png_byte save = *rp;
637
0
               *rp = *(rp + 2);
638
0
               *(rp + 2) = save;
639
0
            }
640
0
         }
641
642
0
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
643
0
         {
644
0
            png_bytep rp;
645
0
            png_uint_32 i;
646
647
0
            for (i = 0, rp = row; i < row_width; i++, rp += 4)
648
0
            {
649
0
               png_byte save = *rp;
650
0
               *rp = *(rp + 2);
651
0
               *(rp + 2) = save;
652
0
            }
653
0
         }
654
0
      }
655
656
0
#ifdef PNG_16BIT_SUPPORTED
657
0
      else if (row_info->bit_depth == 16)
658
0
      {
659
0
         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
660
0
         {
661
0
            png_bytep rp;
662
0
            png_uint_32 i;
663
664
0
            for (i = 0, rp = row; i < row_width; i++, rp += 6)
665
0
            {
666
0
               png_byte save = *rp;
667
0
               *rp = *(rp + 4);
668
0
               *(rp + 4) = save;
669
0
               save = *(rp + 1);
670
0
               *(rp + 1) = *(rp + 5);
671
0
               *(rp + 5) = save;
672
0
            }
673
0
         }
674
675
0
         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
676
0
         {
677
0
            png_bytep rp;
678
0
            png_uint_32 i;
679
680
0
            for (i = 0, rp = row; i < row_width; i++, rp += 8)
681
0
            {
682
0
               png_byte save = *rp;
683
0
               *rp = *(rp + 4);
684
0
               *(rp + 4) = save;
685
0
               save = *(rp + 1);
686
0
               *(rp + 1) = *(rp + 5);
687
0
               *(rp + 5) = save;
688
0
            }
689
0
         }
690
0
      }
691
0
#endif
692
0
   }
693
0
}
694
#endif /* READ_BGR || WRITE_BGR */
695
696
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
697
    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
698
/* Added at libpng-1.5.10 */
699
void /* PRIVATE */
700
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
701
0
{
702
0
   png_debug(1, "in png_do_check_palette_indexes");
703
704
0
   if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
705
0
      png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
706
0
   {
707
      /* Calculations moved outside switch in an attempt to stop different
708
       * compiler warnings.  'padding' is in *bits* within the last byte, it is
709
       * an 'int' because pixel_depth becomes an 'int' in the expression below,
710
       * and this calculation is used because it avoids warnings that other
711
       * forms produced on either GCC or MSVC.
712
       */
713
0
      int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
714
0
      png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
715
716
0
      switch (row_info->bit_depth)
717
0
      {
718
0
         case 1:
719
0
         {
720
            /* in this case, all bytes must be 0 so we don't need
721
             * to unpack the pixels except for the rightmost one.
722
             */
723
0
            for (; rp > png_ptr->row_buf; rp--)
724
0
            {
725
0
              if ((*rp >> padding) != 0)
726
0
                 png_ptr->num_palette_max = 1;
727
0
              padding = 0;
728
0
            }
729
730
0
            break;
731
0
         }
732
733
0
         case 2:
734
0
         {
735
0
            for (; rp > png_ptr->row_buf; rp--)
736
0
            {
737
0
              int i = ((*rp >> padding) & 0x03);
738
739
0
              if (i > png_ptr->num_palette_max)
740
0
                 png_ptr->num_palette_max = i;
741
742
0
              i = (((*rp >> padding) >> 2) & 0x03);
743
744
0
              if (i > png_ptr->num_palette_max)
745
0
                 png_ptr->num_palette_max = i;
746
747
0
              i = (((*rp >> padding) >> 4) & 0x03);
748
749
0
              if (i > png_ptr->num_palette_max)
750
0
                 png_ptr->num_palette_max = i;
751
752
0
              i = (((*rp >> padding) >> 6) & 0x03);
753
754
0
              if (i > png_ptr->num_palette_max)
755
0
                 png_ptr->num_palette_max = i;
756
757
0
              padding = 0;
758
0
            }
759
760
0
            break;
761
0
         }
762
763
0
         case 4:
764
0
         {
765
0
            for (; rp > png_ptr->row_buf; rp--)
766
0
            {
767
0
              int i = ((*rp >> padding) & 0x0f);
768
769
0
              if (i > png_ptr->num_palette_max)
770
0
                 png_ptr->num_palette_max = i;
771
772
0
              i = (((*rp >> padding) >> 4) & 0x0f);
773
774
0
              if (i > png_ptr->num_palette_max)
775
0
                 png_ptr->num_palette_max = i;
776
777
0
              padding = 0;
778
0
            }
779
780
0
            break;
781
0
         }
782
783
0
         case 8:
784
0
         {
785
0
            for (; rp > png_ptr->row_buf; rp--)
786
0
            {
787
0
               if (*rp > png_ptr->num_palette_max)
788
0
                  png_ptr->num_palette_max = (int) *rp;
789
0
            }
790
791
0
            break;
792
0
         }
793
794
0
         default:
795
0
            break;
796
0
      }
797
0
   }
798
0
}
799
#endif /* CHECK_FOR_INVALID_INDEX */
800
801
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
802
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
803
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
804
void PNGAPI
805
png_set_user_transform_info(png_structrp png_ptr, png_voidp
806
   user_transform_ptr, int user_transform_depth, int user_transform_channels)
807
0
{
808
0
   png_debug(1, "in png_set_user_transform_info");
809
810
0
   if (png_ptr == NULL)
811
0
      return;
812
813
0
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
814
0
   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
815
0
      (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
816
0
   {
817
0
      png_app_error(png_ptr,
818
0
          "info change after png_start_read_image or png_read_update_info");
819
0
      return;
820
0
   }
821
0
#endif
822
823
0
   png_ptr->user_transform_ptr = user_transform_ptr;
824
0
   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
825
0
   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
826
0
}
827
#endif
828
829
/* This function returns a pointer to the user_transform_ptr associated with
830
 * the user transform functions.  The application should free any memory
831
 * associated with this pointer before png_write_destroy and png_read_destroy
832
 * are called.
833
 */
834
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
835
png_voidp PNGAPI
836
png_get_user_transform_ptr(png_const_structrp png_ptr)
837
0
{
838
0
   if (png_ptr == NULL)
839
0
      return NULL;
840
841
0
   return png_ptr->user_transform_ptr;
842
0
}
843
#endif
844
845
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
846
png_uint_32 PNGAPI
847
png_get_current_row_number(png_const_structrp png_ptr)
848
0
{
849
   /* See the comments in png.h - this is the sub-image row when reading an
850
    * interlaced image.
851
    */
852
0
   if (png_ptr != NULL)
853
0
      return png_ptr->row_number;
854
855
0
   return PNG_UINT_32_MAX; /* help the app not to fail silently */
856
0
}
857
858
png_byte PNGAPI
859
png_get_current_pass_number(png_const_structrp png_ptr)
860
0
{
861
0
   if (png_ptr != NULL)
862
0
      return png_ptr->pass;
863
0
   return 8; /* invalid */
864
0
}
865
#endif /* USER_TRANSFORM_INFO */
866
#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
867
#endif /* READ || WRITE */
\ No newline at end of file diff --git a/part1/report/w_corpus/src/libpng/report.html b/part1/report/w_corpus/src/libpng/report.html new file mode 100644 index 0000000..221d2cc --- /dev/null +++ b/part1/report/w_corpus/src/libpng/report.html @@ -0,0 +1,286 @@ + + + + + + + + + + +

Coverage Report

+

+ View results by: + Directories + | Files +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Path + Line Coverage + + Function Coverage + + Region Coverage +
+
contrib/
+
+
 87.93% (102/116)
+
+
100.00% (5/5)
+
+
 59.33% (124/209)
+
+
png.c
+
+
 42.74% (727/1701)
+
+
 57.58% (38/66)
+
+
 42.13% (610/1448)
+
+
pngerror.c
+
+
 55.26% (210/380)
+
+
 70.37% (19/27)
+
+
 51.13% (158/309)
+
+
pngget.c
+
+
  3.50% (26/742)
+
+
  2.78% (2/72)
+
+
  3.00% (26/866)
+
+
pngmem.c
+
+
 79.28% (88/111)
+
+
 84.62% (11/13)
+
+
 75.96% (79/104)
+
+
pngread.c
+
+
 28.36% (638/2250)
+
+
 47.37% (18/38)
+
+
 27.80% (609/2191)
+
+
pngrio.c
+
+
 78.57% (11/14)
+
+
100.00% (2/2)
+
+
 70.00% (7/10)
+
+
pngrtran.c
+
+
 30.17% (1025/3397)
+
+
 52.08% (25/48)
+
+
 32.38% (694/2143)
+
+
pngrutil.c
+
+
 73.31% (1912/2608)
+
+
 93.22% (55/59)
+
+
 29.12% (1953/6707)
+
+
pngset.c
+
+
 53.03% (587/1107)
+
+
 48.98% (24/49)
+
+
 54.13% (511/944)
+
+
pngtrans.c
+
+
  8.67% (36/415)
+
+
 19.05% (4/21)
+
+
 12.01% (37/308)
+
+
Totals
+
+
 41.76% (5362/12841)
+
+
 50.75% (203/400)
+
+
 31.55% (4808/15239)
+
+ +
+ + \ No newline at end of file diff --git a/part1/report/w_corpus/src/report.html b/part1/report/w_corpus/src/report.html new file mode 100644 index 0000000..8c450d0 --- /dev/null +++ b/part1/report/w_corpus/src/report.html @@ -0,0 +1,146 @@ + + + + + + + + + + +

Coverage Report

+

+ View results by: + Directories + | Files +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Path + Line Coverage + + Function Coverage + + Region Coverage +
+
libpng/
+
+
 41.76% (5362/12841)
+
+
 50.75% (203/400)
+
+
 31.55% (4808/15239)
+
+
Totals
+
+
 41.76% (5362/12841)
+
+
 50.75% (203/400)
+
+
 31.55% (4808/15239)
+
+ +
+ + \ No newline at end of file diff --git a/part1/report/w_corpus/summary.json b/part1/report/w_corpus/summary.json new file mode 100644 index 0000000..7b8eb0b --- /dev/null +++ b/part1/report/w_corpus/summary.json @@ -0,0 +1 @@ +{"data":[{"files":[{"filename":"/src/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc","summary":{"branches":{"count":92,"covered":40,"notcovered":52,"percent":43.478260869565219},"functions":{"count":5,"covered":5,"percent":100},"instantiations":{"count":5,"covered":5,"percent":100},"lines":{"count":116,"covered":102,"percent":87.931034482758619},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":209,"covered":124,"notcovered":85,"percent":59.330143540669852}}},{"filename":"/src/libpng/png.c","summary":{"branches":{"count":872,"covered":320,"notcovered":552,"percent":36.697247706422019},"functions":{"count":66,"covered":38,"percent":57.575757575757578},"instantiations":{"count":66,"covered":38,"percent":57.575757575757578},"lines":{"count":1701,"covered":727,"percent":42.739564961787188},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":1448,"covered":610,"notcovered":838,"percent":42.127071823204417}}},{"filename":"/src/libpng/png.h","summary":{"branches":{"count":0,"covered":0,"notcovered":0,"percent":0},"functions":{"count":0,"covered":0,"percent":0},"instantiations":{"count":0,"covered":0,"percent":0},"lines":{"count":0,"covered":0,"percent":0},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":0,"covered":0,"notcovered":0,"percent":0}}},{"filename":"/src/libpng/pngdebug.h","summary":{"branches":{"count":0,"covered":0,"notcovered":0,"percent":0},"functions":{"count":0,"covered":0,"percent":0},"instantiations":{"count":0,"covered":0,"percent":0},"lines":{"count":0,"covered":0,"percent":0},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":0,"covered":0,"notcovered":0,"percent":0}}},{"filename":"/src/libpng/pngerror.c","summary":{"branches":{"count":184,"covered":73,"notcovered":111,"percent":39.673913043478258},"functions":{"count":27,"covered":19,"percent":70.370370370370367},"instantiations":{"count":27,"covered":19,"percent":70.370370370370367},"lines":{"count":380,"covered":210,"percent":55.26315789473685},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":309,"covered":158,"notcovered":151,"percent":51.132686084142399}}},{"filename":"/src/libpng/pngget.c","summary":{"branches":{"count":566,"covered":11,"notcovered":555,"percent":1.9434628975265018},"functions":{"count":72,"covered":2,"percent":2.7777777777777777},"instantiations":{"count":72,"covered":2,"percent":2.7777777777777777},"lines":{"count":742,"covered":26,"percent":3.5040431266846364},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":866,"covered":26,"notcovered":840,"percent":3.0023094688221708}}},{"filename":"/src/libpng/pnglibconf.h","summary":{"branches":{"count":0,"covered":0,"notcovered":0,"percent":0},"functions":{"count":0,"covered":0,"percent":0},"instantiations":{"count":0,"covered":0,"percent":0},"lines":{"count":0,"covered":0,"percent":0},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":0,"covered":0,"notcovered":0,"percent":0}}},{"filename":"/src/libpng/pngmem.c","summary":{"branches":{"count":58,"covered":33,"notcovered":25,"percent":56.896551724137936},"functions":{"count":13,"covered":11,"percent":84.615384615384613},"instantiations":{"count":13,"covered":11,"percent":84.615384615384613},"lines":{"count":111,"covered":88,"percent":79.27927927927928},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":104,"covered":79,"notcovered":25,"percent":75.961538461538453}}},{"filename":"/src/libpng/pngprefix.h","summary":{"branches":{"count":0,"covered":0,"notcovered":0,"percent":0},"functions":{"count":0,"covered":0,"percent":0},"instantiations":{"count":0,"covered":0,"percent":0},"lines":{"count":0,"covered":0,"percent":0},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":0,"covered":0,"notcovered":0,"percent":0}}},{"filename":"/src/libpng/pngpriv.h","summary":{"branches":{"count":0,"covered":0,"notcovered":0,"percent":0},"functions":{"count":0,"covered":0,"percent":0},"instantiations":{"count":0,"covered":0,"percent":0},"lines":{"count":0,"covered":0,"percent":0},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":0,"covered":0,"notcovered":0,"percent":0}}},{"filename":"/src/libpng/pngread.c","summary":{"branches":{"count":1066,"covered":241,"notcovered":825,"percent":22.607879924953096},"functions":{"count":38,"covered":18,"percent":47.368421052631575},"instantiations":{"count":38,"covered":18,"percent":47.368421052631575},"lines":{"count":2250,"covered":638,"percent":28.355555555555554},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":2191,"covered":609,"notcovered":1582,"percent":27.795527156549522}}},{"filename":"/src/libpng/pngrio.c","summary":{"branches":{"count":4,"covered":2,"notcovered":2,"percent":50},"functions":{"count":2,"covered":2,"percent":100},"instantiations":{"count":2,"covered":2,"percent":100},"lines":{"count":14,"covered":11,"percent":78.571428571428569},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":10,"covered":7,"notcovered":3,"percent":70}}},{"filename":"/src/libpng/pngrtran.c","summary":{"branches":{"count":1274,"covered":338,"notcovered":936,"percent":26.530612244897959},"functions":{"count":48,"covered":25,"percent":52.083333333333336},"instantiations":{"count":48,"covered":25,"percent":52.083333333333336},"lines":{"count":3397,"covered":1025,"percent":30.173682661171625},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":2143,"covered":694,"notcovered":1449,"percent":32.384507699486704}}},{"filename":"/src/libpng/pngrutil.c","summary":{"branches":{"count":1062,"covered":773,"notcovered":289,"percent":72.787193973634658},"functions":{"count":59,"covered":55,"percent":93.220338983050837},"instantiations":{"count":59,"covered":55,"percent":93.220338983050837},"lines":{"count":2608,"covered":1912,"percent":73.312883435582819},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":6707,"covered":1953,"notcovered":4754,"percent":29.118831072014313}}},{"filename":"/src/libpng/pngset.c","summary":{"branches":{"count":482,"covered":219,"notcovered":263,"percent":45.435684647302907},"functions":{"count":49,"covered":24,"percent":48.979591836734691},"instantiations":{"count":49,"covered":24,"percent":48.979591836734691},"lines":{"count":1107,"covered":587,"percent":53.026196928635947},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":944,"covered":511,"notcovered":433,"percent":54.131355932203384}}},{"filename":"/src/libpng/pngstruct.h","summary":{"branches":{"count":0,"covered":0,"notcovered":0,"percent":0},"functions":{"count":0,"covered":0,"percent":0},"instantiations":{"count":0,"covered":0,"percent":0},"lines":{"count":0,"covered":0,"percent":0},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":0,"covered":0,"notcovered":0,"percent":0}}},{"filename":"/src/libpng/pngtrans.c","summary":{"branches":{"count":170,"covered":11,"notcovered":159,"percent":6.4705882352941186},"functions":{"count":21,"covered":4,"percent":19.047619047619047},"instantiations":{"count":21,"covered":4,"percent":19.047619047619047},"lines":{"count":415,"covered":36,"percent":8.6746987951807224},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":308,"covered":37,"notcovered":271,"percent":12.012987012987013}}}],"totals":{"branches":{"count":5830,"covered":2061,"notcovered":3769,"percent":35.351629502572898},"functions":{"count":400,"covered":203,"percent":50.749999999999993},"instantiations":{"count":400,"covered":203,"percent":50.749999999999993},"lines":{"count":12841,"covered":5362,"percent":41.756872517716687},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":15239,"covered":4808,"notcovered":10431,"percent":31.550626681540784}}}],"type":"llvm.coverage.json.export","version":"2.0.1"} \ No newline at end of file diff --git a/part1/run.w_corpus.sh b/part1/run.w_corpus.sh index acb2279..2152aee 100755 --- a/part1/run.w_corpus.sh +++ b/part1/run.w_corpus.sh @@ -11,4 +11,4 @@ python3 infra/helper.py build_fuzzers --clean libpng mkdir -p build/out/corpus python3 infra/helper.py run_fuzzer libpng libpng_read_fuzzer --corpus-dir build/out/corpus python3 infra/helper.py build_fuzzers --sanitizer coverage libpng -python3 infra/helper.py coverage libpng --corpus-dir build/out/corpus --fuzz-target libpng_read_fuzzer +python3 infra/helper.py coverage libpng --corpus-dir build/out/corpus --fuzz-target libpng_read_fuzzer --no-serve diff --git a/part1/run.w_o_corpus.sh b/part1/run.w_o_corpus.sh index d20690f..039ce7b 100755 --- a/part1/run.w_o_corpus.sh +++ b/part1/run.w_o_corpus.sh @@ -12,4 +12,4 @@ python3 infra/helper.py build_fuzzers --clean libpng mkdir -p build/out/corpus python3 infra/helper.py run_fuzzer libpng libpng_read_fuzzer --corpus-dir build/out/corpus python3 infra/helper.py build_fuzzers --sanitizer coverage libpng -python3 infra/helper.py coverage libpng --corpus-dir build/out/corpus --fuzz-target libpng_read_fuzzer +python3 infra/helper.py coverage libpng --corpus-dir build/out/corpus --fuzz-target libpng_read_fuzzer --no-serve diff --git a/part3/improve1/oss-fuzz.diff b/part3/improve1/oss-fuzz.diff new file mode 100644 index 0000000..9812193 --- /dev/null +++ b/part3/improve1/oss-fuzz.diff @@ -0,0 +1,26 @@ +diff --git a/infra/helper.py b/infra/helper.py +index edf073458..a595dbfbb 100755 +--- a/infra/helper.py ++++ b/infra/helper.py +@@ -1448,6 +1448,8 @@ def run_fuzzer(args): + '%s:/out' % args.project.out, + '-t', + BASE_RUNNER_IMAGE, ++ 'timeout', ++ '14400', + 'run_fuzzer', + args.fuzzer_name, + ] + args.fuzzer_args) +diff --git a/projects/libpng/Dockerfile b/projects/libpng/Dockerfile +index 6f281cd55..3017d4404 100644 +--- a/projects/libpng/Dockerfile ++++ b/projects/libpng/Dockerfile +@@ -19,6 +19,7 @@ RUN apt-get update && \ + apt-get install -y make autoconf automake libtool zlib1g-dev + + RUN git clone --depth 1 https://github.com/madler/zlib.git +-RUN git clone --depth 1 https://github.com/pnggroup/libpng.git ++RUN git clone --depth 1 --branch BRANCH_TO_CHECKOUT https://github.com/SekoiaTree/libpng.git ++#FUZZ_SEED_DISABLE RUN sed -i 's/libpng_read_fuzzer_seed_corpus\.zip/libpng_read_fuzzer_seed_corpus.zip.disabled/g' $SRC/build.sh + RUN cp libpng/contrib/oss-fuzz/build.sh $SRC + WORKDIR libpng diff --git a/part3/improve1/project.diff b/part3/improve1/project.diff new file mode 100644 index 0000000..f03dcd3 --- /dev/null +++ b/part3/improve1/project.diff @@ -0,0 +1,21 @@ +diff --git a/contrib/oss-fuzz/libpng_read_fuzzer.cc b/contrib/oss-fuzz/libpng_read_fuzzer.cc +index 96ed42c8c..bfb5d9d3d 100644 +--- a/contrib/oss-fuzz/libpng_read_fuzzer.cc ++++ b/contrib/oss-fuzz/libpng_read_fuzzer.cc +@@ -216,15 +216,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + + image.format = PNG_FORMAT_RGBA; + std::vector buffer(PNG_IMAGE_SIZE(image)); +- +- // Background color (white): +- png_color background = {255, 255, 255}; +- +- // Colormap (empty, but needs to have enough space for 256 entries (each of 4 uint16_t)): +- // Allocated in the stack, so no need to free it. +- png_uint_16 colormap[256*4] = {}; +- +- png_image_finish_read(&image, &background, buffer.data(), 0, colormap); ++ png_image_finish_read(&image, NULL, buffer.data(), 0, NULL); + #endif + + return 0; diff --git a/part3/improve1/run.improve1.sh b/part3/improve1/run.improve1.sh index 9952d23..4894048 100755 --- a/part3/improve1/run.improve1.sh +++ b/part3/improve1/run.improve1.sh @@ -11,4 +11,4 @@ python3 infra/helper.py build_fuzzers --clean libpng mkdir -p build/out/corpus python3 infra/helper.py run_fuzzer libpng libpng_read_fuzzer --corpus-dir build/out/corpus python3 infra/helper.py build_fuzzers --sanitizer coverage libpng -python3 infra/helper.py coverage libpng --corpus-dir build/out/corpus --fuzz-target libpng_read_fuzzer +python3 infra/helper.py coverage libpng --corpus-dir build/out/corpus --fuzz-target libpng_read_fuzzer --no-serve