Coverage Report

Created: 2026-10-28 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjpeg-turbo.main/src/rdpng.c
Line
Count
Source
1
/*
2
 * rdpng.c
3
 *
4
 * This file was part of the Independent JPEG Group's software:
5
 * Copyright (C) 1991-1997, Thomas G. Lane.
6
 * libjpeg-turbo Modifications:
7
 * Copyright (C) 2015-2017, 2020-2026, D. R. Commander.
8
 * For conditions of distribution and use, see the accompanying README.ijg
9
 * file.
10
 *
11
 * This file contains routines to read input images in 8-bit-per-channel or
12
 * 16-bit-per-channel PNG format.  libspng is required to compile this
13
 * software.
14
 */
15
16
#ifdef _MSC_VER
17
#define _CRT_SECURE_NO_DEPRECATE
18
#endif
19
20
#include "cmyk.h"
21
#include "cdjpeg.h"             /* Common decls for cjpeg/djpeg applications */
22
#include "spng/spng.h"
23
24
#if defined(PNG_SUPPORTED) && \
25
    (BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED))
26
27
28
static int alpha_index[JPEG_NUMCS] = {
29
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1
30
};
31
32
33
88.3k
#define TRY_SPNG(f) { \
34
88.3k
  int __spng_error = (f); \
35
88.3k
  if (__spng_error) \
36
88.3k
    ERREXITS(cinfo, JERR_PNG_LIBSPNG, spng_strerror(__spng_error)); \
37
88.3k
}
38
39
40
/* Private version of data source object */
41
42
typedef struct {
43
  struct cjpeg_source_struct pub; /* public fields */
44
45
  spng_ctx *ctx;
46
  uint8_t png_bit_depth, png_color_type;
47
  int png_alpha;
48
  struct spng_plte colormap;    /* PNG colormap */
49
50
  /* Usually these two pointers point to the same place: */
51
  unsigned char *iobuffer;      /* libspng's I/O buffer */
52
  _JSAMPROW pixrow;             /* compressor input buffer */
53
  size_t buffer_width;          /* width of I/O buffer */
54
  _JSAMPLE *rescale;            /* PNG bit depth => data precision remapping
55
                                   array, or NULL */
56
} png_source_struct;
57
58
typedef png_source_struct *png_source_ptr;
59
60
61
/*
62
 * Read one row of pixels.
63
 *
64
 * We provide several different versions depending on input file format.
65
 * In all cases, input is scaled to cinfo->data_precision.
66
 *
67
 * get_raw_row() is used when the pixel format is JCS_EXT_RGB/JCS_RGB or
68
 * JCS_GRAYSCALE, cinfo->data_precision is 8 or 16, and the PNG file doesn't
69
 * have an alpha channel.  Thus, we can read the pixels directly from the PNG
70
 * file.
71
 */
72
73
METHODDEF(JDIMENSION)
74
get_raw_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
75
662k
{
76
662k
  png_source_ptr source = (png_source_ptr)sinfo;
77
662k
  int spng_error;
78
79
662k
  spng_error = spng_decode_row(source->ctx, source->iobuffer,
80
662k
                               source->buffer_width);
81
662k
  if (spng_error && spng_error != SPNG_EOI)
82
4.66k
    ERREXITS(cinfo, JERR_PNG_LIBSPNG, spng_strerror(spng_error)); \
83
662k
  return 1;
84
662k
}
Unexecuted instantiation: rdpng-8.c:get_raw_row
Unexecuted instantiation: rdpng-12.c:get_raw_row
rdpng-16.c:get_raw_row
Line
Count
Source
75
662k
{
76
662k
  png_source_ptr source = (png_source_ptr)sinfo;
77
662k
  int spng_error;
78
79
662k
  spng_error = spng_decode_row(source->ctx, source->iobuffer,
80
662k
                               source->buffer_width);
81
662k
  if (spng_error && spng_error != SPNG_EOI)
82
4.66k
    ERREXITS(cinfo, JERR_PNG_LIBSPNG, spng_strerror(spng_error)); \
83
662k
  return 1;
84
662k
}
85
86
87
365k
#define GRAY_RGB_READ_LOOP(read_op, alpha_set_op, pointer_op) { \
88
36.2M
  for (col = cinfo->image_width; col > 0; col--) { \
89
35.9M
    ptr[rindex] = ptr[gindex] = ptr[bindex] = read_op; \
90
35.9M
    alpha_set_op \
91
35.9M
    ptr += ps; \
92
35.9M
    pointer_op \
93
35.9M
  } \
94
365k
}
95
96
97
METHODDEF(JDIMENSION)
98
get_gray_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
99
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel
100
 * grayscale or grayscale + alpha PNG files.
101
 */
102
34.6k
{
103
34.6k
  png_source_ptr source = (png_source_ptr)sinfo;
104
34.6k
  register _JSAMPROW ptr;
105
34.6k
  register _JSAMPLE *rescale = source->rescale;
106
34.6k
  JDIMENSION col;
107
108
34.6k
  get_raw_row(cinfo, sinfo);
109
34.6k
  ptr = source->pub._buffer[0];
110
#if BITS_IN_JSAMPLE != 12
111
34.6k
  if (source->png_bit_depth == cinfo->data_precision) {
112
10.2k
    _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
113
78.5k
    for (col = cinfo->image_width; col > 0; col--) {
114
68.3k
      *ptr++ = *bufferptr++;
115
68.3k
      bufferptr += source->png_alpha;
116
68.3k
    }
117
10.2k
  } else
118
24.4k
#endif
119
24.4k
  if (source->png_bit_depth == 16) {
120
0
    register unsigned short *bufferptr = (unsigned short *)source->iobuffer;
121
0
    for (col = cinfo->image_width; col > 0; col--) {
122
0
      *ptr++ = rescale[*bufferptr++];
123
0
      bufferptr += source->png_alpha;
124
0
    }
125
24.4k
  } else {
126
24.4k
    register unsigned char *bufferptr = source->iobuffer;
127
5.48M
    for (col = cinfo->image_width; col > 0; col--) {
128
5.45M
      *ptr++ = rescale[*bufferptr++];
129
5.45M
      bufferptr += source->png_alpha;
130
5.45M
    }
131
24.4k
  }
132
34.6k
  return 1;
133
34.6k
}
Unexecuted instantiation: rdpng-8.c:get_gray_row
Unexecuted instantiation: rdpng-12.c:get_gray_row
rdpng-16.c:get_gray_row
Line
Count
Source
102
34.6k
{
103
34.6k
  png_source_ptr source = (png_source_ptr)sinfo;
104
34.6k
  register _JSAMPROW ptr;
105
34.6k
  register _JSAMPLE *rescale = source->rescale;
106
34.6k
  JDIMENSION col;
107
108
34.6k
  get_raw_row(cinfo, sinfo);
109
34.6k
  ptr = source->pub._buffer[0];
110
34.6k
#if BITS_IN_JSAMPLE != 12
111
34.6k
  if (source->png_bit_depth == cinfo->data_precision) {
112
10.2k
    _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
113
78.5k
    for (col = cinfo->image_width; col > 0; col--) {
114
68.3k
      *ptr++ = *bufferptr++;
115
68.3k
      bufferptr += source->png_alpha;
116
68.3k
    }
117
10.2k
  } else
118
24.4k
#endif
119
24.4k
  if (source->png_bit_depth == 16) {
120
0
    register unsigned short *bufferptr = (unsigned short *)source->iobuffer;
121
0
    for (col = cinfo->image_width; col > 0; col--) {
122
0
      *ptr++ = rescale[*bufferptr++];
123
0
      bufferptr += source->png_alpha;
124
0
    }
125
24.4k
  } else {
126
24.4k
    register unsigned char *bufferptr = source->iobuffer;
127
5.48M
    for (col = cinfo->image_width; col > 0; col--) {
128
5.45M
      *ptr++ = rescale[*bufferptr++];
129
5.45M
      bufferptr += source->png_alpha;
130
5.45M
    }
131
24.4k
  }
132
34.6k
  return 1;
133
34.6k
}
134
135
136
METHODDEF(JDIMENSION)
137
get_gray_rgb_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
138
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel
139
 * grayscale or grayscale + alpha PNG files and converting to extended RGB.
140
 */
141
365k
{
142
365k
  png_source_ptr source = (png_source_ptr)sinfo;
143
365k
  register _JSAMPROW ptr;
144
365k
  register _JSAMPLE *rescale = source->rescale;
145
365k
  JDIMENSION col;
146
365k
  register int rindex = rgb_red[cinfo->in_color_space];
147
365k
  register int gindex = rgb_green[cinfo->in_color_space];
148
365k
  register int bindex = rgb_blue[cinfo->in_color_space];
149
365k
  register int aindex = alpha_index[cinfo->in_color_space];
150
365k
  register int ps = rgb_pixelsize[cinfo->in_color_space];
151
152
365k
  get_raw_row(cinfo, sinfo);
153
365k
  ptr = source->pub._buffer[0];
154
#if BITS_IN_JSAMPLE != 12
155
365k
  if (source->png_bit_depth == cinfo->data_precision) {
156
97.2k
    _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
157
97.2k
    if (aindex >= 0)
158
0
      GRAY_RGB_READ_LOOP(*bufferptr++, ptr[aindex] = _MAXJSAMPLE;,
159
97.2k
                         bufferptr += source->png_alpha;)
160
97.2k
    else
161
97.2k
      GRAY_RGB_READ_LOOP(*bufferptr++, {}, bufferptr += source->png_alpha;)
162
97.2k
  } else
163
268k
#endif
164
268k
  if (source->png_bit_depth == 16) {
165
145k
    register unsigned short *bufferptr = (unsigned short *)source->iobuffer;
166
145k
    if (aindex >= 0)
167
48.6k
      GRAY_RGB_READ_LOOP(rescale[*bufferptr++],
168
145k
                         ptr[aindex] = (1 << cinfo->data_precision) - 1;,
169
145k
                         bufferptr += source->png_alpha;)
170
97.2k
    else
171
97.2k
      GRAY_RGB_READ_LOOP(rescale[*bufferptr++], {},
172
145k
                         bufferptr += source->png_alpha;)
173
145k
  } else {
174
122k
    register unsigned char *bufferptr = source->iobuffer;
175
122k
    if (aindex >= 0)
176
24.2k
      GRAY_RGB_READ_LOOP(rescale[*bufferptr++],
177
122k
                         ptr[aindex] = (1 << cinfo->data_precision) - 1;,
178
122k
                         bufferptr += source->png_alpha;)
179
98.3k
    else
180
98.3k
      GRAY_RGB_READ_LOOP(rescale[*bufferptr++], {},
181
122k
                         bufferptr += source->png_alpha;)
182
122k
  }
183
365k
  return 1;
184
365k
}
Unexecuted instantiation: rdpng-8.c:get_gray_rgb_row
Unexecuted instantiation: rdpng-12.c:get_gray_rgb_row
rdpng-16.c:get_gray_rgb_row
Line
Count
Source
141
365k
{
142
365k
  png_source_ptr source = (png_source_ptr)sinfo;
143
365k
  register _JSAMPROW ptr;
144
365k
  register _JSAMPLE *rescale = source->rescale;
145
365k
  JDIMENSION col;
146
365k
  register int rindex = rgb_red[cinfo->in_color_space];
147
365k
  register int gindex = rgb_green[cinfo->in_color_space];
148
365k
  register int bindex = rgb_blue[cinfo->in_color_space];
149
365k
  register int aindex = alpha_index[cinfo->in_color_space];
150
365k
  register int ps = rgb_pixelsize[cinfo->in_color_space];
151
152
365k
  get_raw_row(cinfo, sinfo);
153
365k
  ptr = source->pub._buffer[0];
154
365k
#if BITS_IN_JSAMPLE != 12
155
365k
  if (source->png_bit_depth == cinfo->data_precision) {
156
97.2k
    _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
157
97.2k
    if (aindex >= 0)
158
0
      GRAY_RGB_READ_LOOP(*bufferptr++, ptr[aindex] = _MAXJSAMPLE;,
159
97.2k
                         bufferptr += source->png_alpha;)
160
97.2k
    else
161
97.2k
      GRAY_RGB_READ_LOOP(*bufferptr++, {}, bufferptr += source->png_alpha;)
162
97.2k
  } else
163
268k
#endif
164
268k
  if (source->png_bit_depth == 16) {
165
145k
    register unsigned short *bufferptr = (unsigned short *)source->iobuffer;
166
145k
    if (aindex >= 0)
167
48.6k
      GRAY_RGB_READ_LOOP(rescale[*bufferptr++],
168
145k
                         ptr[aindex] = (1 << cinfo->data_precision) - 1;,
169
145k
                         bufferptr += source->png_alpha;)
170
97.2k
    else
171
97.2k
      GRAY_RGB_READ_LOOP(rescale[*bufferptr++], {},
172
145k
                         bufferptr += source->png_alpha;)
173
145k
  } else {
174
122k
    register unsigned char *bufferptr = source->iobuffer;
175
122k
    if (aindex >= 0)
176
24.2k
      GRAY_RGB_READ_LOOP(rescale[*bufferptr++],
177
122k
                         ptr[aindex] = (1 << cinfo->data_precision) - 1;,
178
122k
                         bufferptr += source->png_alpha;)
179
98.3k
    else
180
98.3k
      GRAY_RGB_READ_LOOP(rescale[*bufferptr++], {},
181
122k
                         bufferptr += source->png_alpha;)
182
122k
  }
183
365k
  return 1;
184
365k
}
185
186
187
METHODDEF(JDIMENSION)
188
get_gray_cmyk_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
189
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel
190
 * grayscale or grayscale + alpha PNG files and converting to CMYK.
191
 */
192
73.1k
{
193
73.1k
  png_source_ptr source = (png_source_ptr)sinfo;
194
73.1k
  register _JSAMPROW ptr;
195
73.1k
  register _JSAMPLE *rescale = source->rescale;
196
73.1k
  JDIMENSION col;
197
198
73.1k
  get_raw_row(cinfo, sinfo);
199
73.1k
  ptr = source->pub._buffer[0];
200
#if BITS_IN_JSAMPLE != 12
201
73.1k
  if (source->png_bit_depth == cinfo->data_precision) {
202
48.6k
    register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
203
1.77M
    for (col = cinfo->image_width; col > 0; col--) {
204
1.72M
      _JSAMPLE gray = *bufferptr++;
205
1.72M
      bufferptr += source->png_alpha;
206
1.72M
      rgb_to_cmyk(_MAXJSAMPLE, gray, gray, gray, ptr, ptr + 1, ptr + 2,
207
1.72M
                  ptr + 3);
208
1.72M
      ptr += 4;
209
1.72M
    }
210
48.6k
  } else
211
24.5k
#endif
212
24.5k
  if (source->png_bit_depth == 16) {
213
0
    unsigned short *bufferptr = (unsigned short *)source->iobuffer;
214
0
    for (col = cinfo->image_width; col > 0; col--) {
215
0
      _JSAMPLE gray = rescale[*bufferptr++];
216
0
      bufferptr += source->png_alpha;
217
0
      rgb_to_cmyk((1 << cinfo->data_precision) - 1, gray, gray, gray, ptr,
218
0
                  ptr + 1, ptr + 2, ptr + 3);
219
0
      ptr += 4;
220
0
    }
221
24.5k
  } else {
222
24.5k
    register unsigned char *bufferptr = source->iobuffer;
223
5.48M
    for (col = cinfo->image_width; col > 0; col--) {
224
5.45M
      _JSAMPLE gray = rescale[*bufferptr++];
225
5.45M
      bufferptr += source->png_alpha;
226
5.45M
      rgb_to_cmyk((1 << cinfo->data_precision) - 1, gray, gray, gray, ptr,
227
5.45M
                  ptr + 1, ptr + 2, ptr + 3);
228
5.45M
      ptr += 4;
229
5.45M
    }
230
24.5k
  }
231
73.1k
  return 1;
232
73.1k
}
Unexecuted instantiation: rdpng-8.c:get_gray_cmyk_row
Unexecuted instantiation: rdpng-12.c:get_gray_cmyk_row
rdpng-16.c:get_gray_cmyk_row
Line
Count
Source
192
73.1k
{
193
73.1k
  png_source_ptr source = (png_source_ptr)sinfo;
194
73.1k
  register _JSAMPROW ptr;
195
73.1k
  register _JSAMPLE *rescale = source->rescale;
196
73.1k
  JDIMENSION col;
197
198
73.1k
  get_raw_row(cinfo, sinfo);
199
73.1k
  ptr = source->pub._buffer[0];
200
73.1k
#if BITS_IN_JSAMPLE != 12
201
73.1k
  if (source->png_bit_depth == cinfo->data_precision) {
202
48.6k
    register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
203
1.77M
    for (col = cinfo->image_width; col > 0; col--) {
204
1.72M
      _JSAMPLE gray = *bufferptr++;
205
1.72M
      bufferptr += source->png_alpha;
206
1.72M
      rgb_to_cmyk(_MAXJSAMPLE, gray, gray, gray, ptr, ptr + 1, ptr + 2,
207
1.72M
                  ptr + 3);
208
1.72M
      ptr += 4;
209
1.72M
    }
210
48.6k
  } else
211
24.5k
#endif
212
24.5k
  if (source->png_bit_depth == 16) {
213
0
    unsigned short *bufferptr = (unsigned short *)source->iobuffer;
214
0
    for (col = cinfo->image_width; col > 0; col--) {
215
0
      _JSAMPLE gray = rescale[*bufferptr++];
216
0
      bufferptr += source->png_alpha;
217
0
      rgb_to_cmyk((1 << cinfo->data_precision) - 1, gray, gray, gray, ptr,
218
0
                  ptr + 1, ptr + 2, ptr + 3);
219
0
      ptr += 4;
220
0
    }
221
24.5k
  } else {
222
24.5k
    register unsigned char *bufferptr = source->iobuffer;
223
5.48M
    for (col = cinfo->image_width; col > 0; col--) {
224
5.45M
      _JSAMPLE gray = rescale[*bufferptr++];
225
5.45M
      bufferptr += source->png_alpha;
226
5.45M
      rgb_to_cmyk((1 << cinfo->data_precision) - 1, gray, gray, gray, ptr,
227
5.45M
                  ptr + 1, ptr + 2, ptr + 3);
228
5.45M
      ptr += 4;
229
5.45M
    }
230
24.5k
  }
231
73.1k
  return 1;
232
73.1k
}
233
234
235
118k
#define RGB_READ_LOOP(read_op, alpha_set_op, pointer_op) { \
236
54.2M
  for (col = cinfo->image_width; col > 0; col--) { \
237
54.1M
    ptr[rindex] = read_op; \
238
54.1M
    ptr[gindex] = read_op; \
239
54.1M
    ptr[bindex] = read_op; \
240
54.1M
    alpha_set_op \
241
54.1M
    pointer_op \
242
54.1M
    ptr += ps; \
243
54.1M
  } \
244
118k
}
245
246
247
METHODDEF(JDIMENSION)
248
get_rgb_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
249
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel
250
 * truecolor or truecolor + alpha PNG files and converting to extended RGB.
251
 */
252
118k
{
253
118k
  png_source_ptr source = (png_source_ptr)sinfo;
254
118k
  register _JSAMPROW ptr;
255
118k
  register _JSAMPLE *rescale = source->rescale;
256
118k
  JDIMENSION col;
257
118k
  register int rindex = rgb_red[cinfo->in_color_space];
258
118k
  register int gindex = rgb_green[cinfo->in_color_space];
259
118k
  register int bindex = rgb_blue[cinfo->in_color_space];
260
118k
  register int aindex = alpha_index[cinfo->in_color_space];
261
118k
  register int ps = rgb_pixelsize[cinfo->in_color_space];
262
263
118k
  get_raw_row(cinfo, sinfo);
264
118k
  ptr = source->pub._buffer[0];
265
#if BITS_IN_JSAMPLE != 12
266
118k
  if (source->png_bit_depth == cinfo->data_precision) {
267
9.97k
    register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
268
9.97k
    if (aindex >= 0)
269
0
      RGB_READ_LOOP(*bufferptr++, ptr[aindex] = _MAXJSAMPLE;,
270
9.97k
                    bufferptr += source->png_alpha;)
271
9.97k
    else
272
9.97k
      RGB_READ_LOOP(*bufferptr++, {}, bufferptr += source->png_alpha;)
273
9.97k
  } else
274
108k
#endif
275
108k
  if (source->png_bit_depth == 16) {
276
19.6k
    unsigned short *bufferptr = (unsigned short *)source->iobuffer;
277
19.6k
    if (aindex >= 0)
278
6.56k
      RGB_READ_LOOP(rescale[*bufferptr++],
279
19.6k
                    ptr[aindex] = (1 << cinfo->data_precision) - 1;,
280
19.6k
                    bufferptr += source->png_alpha;)
281
13.1k
    else
282
13.1k
      RGB_READ_LOOP(rescale[*bufferptr++], {},
283
19.6k
                    bufferptr += source->png_alpha;)
284
88.4k
  } else {
285
88.4k
    register unsigned char *bufferptr = source->iobuffer;
286
88.4k
    if (aindex >= 0)
287
17.3k
      RGB_READ_LOOP(rescale[*bufferptr++],
288
88.4k
                    ptr[aindex] = (1 << cinfo->data_precision) - 1;,
289
88.4k
                    bufferptr += source->png_alpha;)
290
71.1k
    else
291
71.1k
      RGB_READ_LOOP(rescale[*bufferptr++], {},
292
88.4k
                    bufferptr += source->png_alpha;)
293
88.4k
  }
294
118k
  return 1;
295
118k
}
Unexecuted instantiation: rdpng-8.c:get_rgb_row
Unexecuted instantiation: rdpng-12.c:get_rgb_row
rdpng-16.c:get_rgb_row
Line
Count
Source
252
118k
{
253
118k
  png_source_ptr source = (png_source_ptr)sinfo;
254
118k
  register _JSAMPROW ptr;
255
118k
  register _JSAMPLE *rescale = source->rescale;
256
118k
  JDIMENSION col;
257
118k
  register int rindex = rgb_red[cinfo->in_color_space];
258
118k
  register int gindex = rgb_green[cinfo->in_color_space];
259
118k
  register int bindex = rgb_blue[cinfo->in_color_space];
260
118k
  register int aindex = alpha_index[cinfo->in_color_space];
261
118k
  register int ps = rgb_pixelsize[cinfo->in_color_space];
262
263
118k
  get_raw_row(cinfo, sinfo);
264
118k
  ptr = source->pub._buffer[0];
265
118k
#if BITS_IN_JSAMPLE != 12
266
118k
  if (source->png_bit_depth == cinfo->data_precision) {
267
9.97k
    register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
268
9.97k
    if (aindex >= 0)
269
0
      RGB_READ_LOOP(*bufferptr++, ptr[aindex] = _MAXJSAMPLE;,
270
9.97k
                    bufferptr += source->png_alpha;)
271
9.97k
    else
272
9.97k
      RGB_READ_LOOP(*bufferptr++, {}, bufferptr += source->png_alpha;)
273
9.97k
  } else
274
108k
#endif
275
108k
  if (source->png_bit_depth == 16) {
276
19.6k
    unsigned short *bufferptr = (unsigned short *)source->iobuffer;
277
19.6k
    if (aindex >= 0)
278
6.56k
      RGB_READ_LOOP(rescale[*bufferptr++],
279
19.6k
                    ptr[aindex] = (1 << cinfo->data_precision) - 1;,
280
19.6k
                    bufferptr += source->png_alpha;)
281
13.1k
    else
282
13.1k
      RGB_READ_LOOP(rescale[*bufferptr++], {},
283
19.6k
                    bufferptr += source->png_alpha;)
284
88.4k
  } else {
285
88.4k
    register unsigned char *bufferptr = source->iobuffer;
286
88.4k
    if (aindex >= 0)
287
17.3k
      RGB_READ_LOOP(rescale[*bufferptr++],
288
88.4k
                    ptr[aindex] = (1 << cinfo->data_precision) - 1;,
289
88.4k
                    bufferptr += source->png_alpha;)
290
71.1k
    else
291
71.1k
      RGB_READ_LOOP(rescale[*bufferptr++], {},
292
88.4k
                    bufferptr += source->png_alpha;)
293
88.4k
  }
294
118k
  return 1;
295
118k
}
296
297
298
METHODDEF(JDIMENSION)
299
get_rgb_cmyk_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
300
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel
301
 * truecolor or truecolor + alpha PNG files and converting to CMYK.
302
 */
303
24.2k
{
304
24.2k
  png_source_ptr source = (png_source_ptr)sinfo;
305
24.2k
  register _JSAMPROW ptr;
306
24.2k
  register _JSAMPLE *rescale = source->rescale;
307
24.2k
  JDIMENSION col;
308
309
24.2k
  get_raw_row(cinfo, sinfo);
310
24.2k
  ptr = source->pub._buffer[0];
311
#if BITS_IN_JSAMPLE != 12
312
24.2k
  if (source->png_bit_depth == cinfo->data_precision) {
313
6.56k
    register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
314
7.00M
    for (col = cinfo->image_width; col > 0; col--) {
315
6.99M
      _JSAMPLE r = *bufferptr++;
316
6.99M
      _JSAMPLE g = *bufferptr++;
317
6.99M
      _JSAMPLE b = *bufferptr++;
318
6.99M
      bufferptr += source->png_alpha;
319
6.99M
      rgb_to_cmyk(_MAXJSAMPLE, r, g, b, ptr, ptr + 1, ptr + 2, ptr + 3);
320
6.99M
      ptr += 4;
321
6.99M
    }
322
6.56k
  } else
323
17.7k
#endif
324
17.7k
  if (source->png_bit_depth == 16) {
325
0
    unsigned short *bufferptr = (unsigned short *)source->iobuffer;
326
0
    for (col = cinfo->image_width; col > 0; col--) {
327
0
      _JSAMPLE r = rescale[*bufferptr++];
328
0
      _JSAMPLE g = rescale[*bufferptr++];
329
0
      _JSAMPLE b = rescale[*bufferptr++];
330
0
      bufferptr += source->png_alpha;
331
0
      rgb_to_cmyk((1 << cinfo->data_precision) - 1, r, g, b, ptr, ptr + 1,
332
0
                  ptr + 2, ptr + 3);
333
0
      ptr += 4;
334
0
    }
335
17.7k
  } else {
336
17.7k
    register unsigned char *bufferptr = source->iobuffer;
337
3.90M
    for (col = cinfo->image_width; col > 0; col--) {
338
3.88M
      _JSAMPLE r = rescale[*bufferptr++];
339
3.88M
      _JSAMPLE g = rescale[*bufferptr++];
340
3.88M
      _JSAMPLE b = rescale[*bufferptr++];
341
3.88M
      bufferptr += source->png_alpha;
342
3.88M
      rgb_to_cmyk((1 << cinfo->data_precision) - 1, r, g, b, ptr, ptr + 1,
343
3.88M
                  ptr + 2, ptr + 3);
344
3.88M
      ptr += 4;
345
3.88M
    }
346
17.7k
  }
347
24.2k
  return 1;
348
24.2k
}
Unexecuted instantiation: rdpng-8.c:get_rgb_cmyk_row
Unexecuted instantiation: rdpng-12.c:get_rgb_cmyk_row
rdpng-16.c:get_rgb_cmyk_row
Line
Count
Source
303
24.2k
{
304
24.2k
  png_source_ptr source = (png_source_ptr)sinfo;
305
24.2k
  register _JSAMPROW ptr;
306
24.2k
  register _JSAMPLE *rescale = source->rescale;
307
24.2k
  JDIMENSION col;
308
309
24.2k
  get_raw_row(cinfo, sinfo);
310
24.2k
  ptr = source->pub._buffer[0];
311
24.2k
#if BITS_IN_JSAMPLE != 12
312
24.2k
  if (source->png_bit_depth == cinfo->data_precision) {
313
6.56k
    register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
314
7.00M
    for (col = cinfo->image_width; col > 0; col--) {
315
6.99M
      _JSAMPLE r = *bufferptr++;
316
6.99M
      _JSAMPLE g = *bufferptr++;
317
6.99M
      _JSAMPLE b = *bufferptr++;
318
6.99M
      bufferptr += source->png_alpha;
319
6.99M
      rgb_to_cmyk(_MAXJSAMPLE, r, g, b, ptr, ptr + 1, ptr + 2, ptr + 3);
320
6.99M
      ptr += 4;
321
6.99M
    }
322
6.56k
  } else
323
17.7k
#endif
324
17.7k
  if (source->png_bit_depth == 16) {
325
0
    unsigned short *bufferptr = (unsigned short *)source->iobuffer;
326
0
    for (col = cinfo->image_width; col > 0; col--) {
327
0
      _JSAMPLE r = rescale[*bufferptr++];
328
0
      _JSAMPLE g = rescale[*bufferptr++];
329
0
      _JSAMPLE b = rescale[*bufferptr++];
330
0
      bufferptr += source->png_alpha;
331
0
      rgb_to_cmyk((1 << cinfo->data_precision) - 1, r, g, b, ptr, ptr + 1,
332
0
                  ptr + 2, ptr + 3);
333
0
      ptr += 4;
334
0
    }
335
17.7k
  } else {
336
17.7k
    register unsigned char *bufferptr = source->iobuffer;
337
3.90M
    for (col = cinfo->image_width; col > 0; col--) {
338
3.88M
      _JSAMPLE r = rescale[*bufferptr++];
339
3.88M
      _JSAMPLE g = rescale[*bufferptr++];
340
3.88M
      _JSAMPLE b = rescale[*bufferptr++];
341
3.88M
      bufferptr += source->png_alpha;
342
3.88M
      rgb_to_cmyk((1 << cinfo->data_precision) - 1, r, g, b, ptr, ptr + 1,
343
3.88M
                  ptr + 2, ptr + 3);
344
3.88M
      ptr += 4;
345
3.88M
    }
346
17.7k
  }
347
24.2k
  return 1;
348
24.2k
}
349
350
351
METHODDEF(JDIMENSION)
352
get_indexed_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
353
4.27k
{
354
/* This version is for reading 8-bit-per-channel indexed-color PNG files and
355
 * converting to extended RGB or CMYK.
356
 */
357
4.27k
  png_source_ptr source = (png_source_ptr)sinfo;
358
4.27k
  register _JSAMPROW ptr;
359
4.27k
  register JSAMPLE *bufferptr = (JSAMPLE *)source->iobuffer;
360
4.27k
  register _JSAMPLE *rescale = source->rescale;
361
4.27k
  JDIMENSION col;
362
363
4.27k
  get_raw_row(cinfo, sinfo);
364
4.27k
  ptr = source->pub._buffer[0];
365
#if BITS_IN_JSAMPLE == 8
366
0
  if (source->png_bit_depth == cinfo->data_precision) {
367
0
    if (cinfo->in_color_space == JCS_GRAYSCALE) {
368
0
      for (col = cinfo->image_width; col > 0; col--) {
369
0
        JSAMPLE index = *bufferptr++;
370
371
0
        if (index >= source->colormap.n_entries)
372
0
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
373
0
        *ptr++ = source->colormap.entries[index].red;
374
0
      }
375
0
    } else if (cinfo->in_color_space == JCS_CMYK) {
376
0
      for (col = cinfo->image_width; col > 0; col--) {
377
0
        JSAMPLE index = *bufferptr++;
378
379
0
        if (index >= source->colormap.n_entries)
380
0
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
381
0
        rgb_to_cmyk(_MAXJSAMPLE, source->colormap.entries[index].red,
382
0
                    source->colormap.entries[index].green,
383
0
                    source->colormap.entries[index].blue, ptr, ptr + 1,
384
0
                    ptr + 2, ptr + 3);
385
0
        ptr += 4;
386
0
      }
387
0
    } else {
388
0
      register int rindex = rgb_red[cinfo->in_color_space];
389
0
      register int gindex = rgb_green[cinfo->in_color_space];
390
0
      register int bindex = rgb_blue[cinfo->in_color_space];
391
0
      register int aindex = alpha_index[cinfo->in_color_space];
392
0
      register int ps = rgb_pixelsize[cinfo->in_color_space];
393
394
0
      for (col = cinfo->image_width; col > 0; col--) {
395
0
        JSAMPLE index = *bufferptr++;
396
397
0
        if (index >= source->colormap.n_entries)
398
0
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
399
0
        ptr[rindex] = source->colormap.entries[index].red;
400
0
        ptr[gindex] = source->colormap.entries[index].green;
401
0
        ptr[bindex] = source->colormap.entries[index].blue;
402
0
        if (aindex >= 0)
403
0
          ptr[aindex] = _MAXJSAMPLE;
404
0
        ptr += ps;
405
0
      }
406
0
    }
407
0
  } else
408
0
#endif
409
0
  {
410
4.27k
    if (cinfo->in_color_space == JCS_GRAYSCALE) {
411
253
      for (col = cinfo->image_width; col > 0; col--) {
412
223
        JSAMPLE index = *bufferptr++;
413
414
223
        if (index >= source->colormap.n_entries)
415
4
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
416
223
        *ptr++ = rescale[source->colormap.entries[index].red];
417
223
      }
418
4.24k
    } else if (cinfo->in_color_space == JCS_CMYK) {
419
64.8k
      for (col = cinfo->image_width; col > 0; col--) {
420
64.1k
        JSAMPLE index = *bufferptr++;
421
422
64.1k
        if (index >= source->colormap.n_entries)
423
28
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
424
64.1k
        rgb_to_cmyk((1 << cinfo->data_precision) - 1,
425
64.1k
                    rescale[source->colormap.entries[index].red],
426
64.1k
                    rescale[source->colormap.entries[index].green],
427
64.1k
                    rescale[source->colormap.entries[index].blue], ptr,
428
64.1k
                    ptr + 1, ptr + 2, ptr + 3);
429
64.1k
        ptr += 4;
430
64.1k
      }
431
3.55k
    } else {
432
3.55k
      register int rindex = rgb_red[cinfo->in_color_space];
433
3.55k
      register int gindex = rgb_green[cinfo->in_color_space];
434
3.55k
      register int bindex = rgb_blue[cinfo->in_color_space];
435
3.55k
      register int aindex = alpha_index[cinfo->in_color_space];
436
3.55k
      register int ps = rgb_pixelsize[cinfo->in_color_space];
437
438
324k
      for (col = cinfo->image_width; col > 0; col--) {
439
320k
        JSAMPLE index = *bufferptr++;
440
441
320k
        if (index >= source->colormap.n_entries)
442
140
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
443
320k
        ptr[rindex] = rescale[source->colormap.entries[index].red];
444
320k
        ptr[gindex] = rescale[source->colormap.entries[index].green];
445
320k
        ptr[bindex] = rescale[source->colormap.entries[index].blue];
446
320k
        if (aindex >= 0)
447
64.1k
          ptr[aindex] = (1 << cinfo->data_precision) - 1;
448
320k
        ptr += ps;
449
320k
      }
450
3.55k
    }
451
0
  }
452
4.27k
  return 1;
453
4.27k
}
Unexecuted instantiation: rdpng-8.c:get_indexed_row
Unexecuted instantiation: rdpng-12.c:get_indexed_row
rdpng-16.c:get_indexed_row
Line
Count
Source
353
4.27k
{
354
/* This version is for reading 8-bit-per-channel indexed-color PNG files and
355
 * converting to extended RGB or CMYK.
356
 */
357
4.27k
  png_source_ptr source = (png_source_ptr)sinfo;
358
4.27k
  register _JSAMPROW ptr;
359
4.27k
  register JSAMPLE *bufferptr = (JSAMPLE *)source->iobuffer;
360
4.27k
  register _JSAMPLE *rescale = source->rescale;
361
4.27k
  JDIMENSION col;
362
363
4.27k
  get_raw_row(cinfo, sinfo);
364
4.27k
  ptr = source->pub._buffer[0];
365
#if BITS_IN_JSAMPLE == 8
366
  if (source->png_bit_depth == cinfo->data_precision) {
367
    if (cinfo->in_color_space == JCS_GRAYSCALE) {
368
      for (col = cinfo->image_width; col > 0; col--) {
369
        JSAMPLE index = *bufferptr++;
370
371
        if (index >= source->colormap.n_entries)
372
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
373
        *ptr++ = source->colormap.entries[index].red;
374
      }
375
    } else if (cinfo->in_color_space == JCS_CMYK) {
376
      for (col = cinfo->image_width; col > 0; col--) {
377
        JSAMPLE index = *bufferptr++;
378
379
        if (index >= source->colormap.n_entries)
380
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
381
        rgb_to_cmyk(_MAXJSAMPLE, source->colormap.entries[index].red,
382
                    source->colormap.entries[index].green,
383
                    source->colormap.entries[index].blue, ptr, ptr + 1,
384
                    ptr + 2, ptr + 3);
385
        ptr += 4;
386
      }
387
    } else {
388
      register int rindex = rgb_red[cinfo->in_color_space];
389
      register int gindex = rgb_green[cinfo->in_color_space];
390
      register int bindex = rgb_blue[cinfo->in_color_space];
391
      register int aindex = alpha_index[cinfo->in_color_space];
392
      register int ps = rgb_pixelsize[cinfo->in_color_space];
393
394
      for (col = cinfo->image_width; col > 0; col--) {
395
        JSAMPLE index = *bufferptr++;
396
397
        if (index >= source->colormap.n_entries)
398
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
399
        ptr[rindex] = source->colormap.entries[index].red;
400
        ptr[gindex] = source->colormap.entries[index].green;
401
        ptr[bindex] = source->colormap.entries[index].blue;
402
        if (aindex >= 0)
403
          ptr[aindex] = _MAXJSAMPLE;
404
        ptr += ps;
405
      }
406
    }
407
  } else
408
#endif
409
4.27k
  {
410
4.27k
    if (cinfo->in_color_space == JCS_GRAYSCALE) {
411
253
      for (col = cinfo->image_width; col > 0; col--) {
412
223
        JSAMPLE index = *bufferptr++;
413
414
223
        if (index >= source->colormap.n_entries)
415
4
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
416
223
        *ptr++ = rescale[source->colormap.entries[index].red];
417
223
      }
418
4.24k
    } else if (cinfo->in_color_space == JCS_CMYK) {
419
64.8k
      for (col = cinfo->image_width; col > 0; col--) {
420
64.1k
        JSAMPLE index = *bufferptr++;
421
422
64.1k
        if (index >= source->colormap.n_entries)
423
28
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
424
64.1k
        rgb_to_cmyk((1 << cinfo->data_precision) - 1,
425
64.1k
                    rescale[source->colormap.entries[index].red],
426
64.1k
                    rescale[source->colormap.entries[index].green],
427
64.1k
                    rescale[source->colormap.entries[index].blue], ptr,
428
64.1k
                    ptr + 1, ptr + 2, ptr + 3);
429
64.1k
        ptr += 4;
430
64.1k
      }
431
3.55k
    } else {
432
3.55k
      register int rindex = rgb_red[cinfo->in_color_space];
433
3.55k
      register int gindex = rgb_green[cinfo->in_color_space];
434
3.55k
      register int bindex = rgb_blue[cinfo->in_color_space];
435
3.55k
      register int aindex = alpha_index[cinfo->in_color_space];
436
3.55k
      register int ps = rgb_pixelsize[cinfo->in_color_space];
437
438
324k
      for (col = cinfo->image_width; col > 0; col--) {
439
320k
        JSAMPLE index = *bufferptr++;
440
441
320k
        if (index >= source->colormap.n_entries)
442
140
          ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
443
320k
        ptr[rindex] = rescale[source->colormap.entries[index].red];
444
320k
        ptr[gindex] = rescale[source->colormap.entries[index].green];
445
320k
        ptr[bindex] = rescale[source->colormap.entries[index].blue];
446
320k
        if (aindex >= 0)
447
64.1k
          ptr[aindex] = (1 << cinfo->data_precision) - 1;
448
320k
        ptr += ps;
449
320k
      }
450
3.55k
    }
451
4.27k
  }
452
4.27k
  return 1;
453
4.27k
}
454
455
456
#ifdef ZERO_BUFFERS
457
458
static void *spng_malloc(size_t size)
459
{
460
  return calloc(1, size);
461
}
462
463
#endif
464
465
466
/*
467
 * Read the file header; return image size and component count.
468
 */
469
470
METHODDEF(void)
471
start_input_png(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
472
32.3k
{
473
32.3k
  png_source_ptr source = (png_source_ptr)sinfo;
474
32.3k
  struct spng_ihdr ihdr;
475
32.3k
  int png_components = 3;
476
32.3k
  boolean use_raw_buffer;
477
#ifdef ZERO_BUFFERS
478
  struct spng_alloc alloc;
479
480
  alloc.malloc_fn = spng_malloc;
481
  alloc.realloc_fn = realloc;
482
  alloc.calloc_fn = calloc;
483
  alloc.free_fn = free;
484
  source->ctx = spng_ctx_new2(&alloc, 0);
485
#else
486
32.3k
  source->ctx = spng_ctx_new(0);
487
32.3k
#endif
488
32.3k
  if (!source->ctx)
489
0
    ERREXITS(cinfo, JERR_PNG_LIBSPNG, "Could not create context");
490
491
32.3k
  TRY_SPNG(spng_set_png_file(source->ctx, sinfo->input_file));
492
493
32.3k
  TRY_SPNG(spng_get_ihdr(source->ctx, &ihdr));
494
495
32.3k
  if (ihdr.width > JPEG_MAX_DIMENSION || ihdr.height > JPEG_MAX_DIMENSION)
496
441
    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, JPEG_MAX_DIMENSION);
497
32.3k
  if (ihdr.bit_depth != 8 && ihdr.bit_depth != 16)
498
5.02k
    ERREXIT(cinfo, JERR_PNG_BADDEPTH);
499
32.3k
  if (sinfo->max_pixels &&
500
25.4k
      (unsigned long long)ihdr.width * ihdr.height > sinfo->max_pixels)
501
301
    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, sinfo->max_pixels);
502
503
32.3k
  cinfo->image_width = (JDIMENSION)ihdr.width;
504
32.3k
  cinfo->image_height = (JDIMENSION)ihdr.height;
505
32.3k
  source->png_bit_depth = ihdr.bit_depth;
506
32.3k
  source->png_color_type = ihdr.color_type;
507
508
  /* initialize flags to most common settings */
509
32.3k
  use_raw_buffer = FALSE;       /* do we map input buffer onto I/O buffer? */
510
511
32.3k
  switch (ihdr.color_type) {
512
1.95k
  case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
513
10.8k
  case SPNG_COLOR_TYPE_GRAYSCALE:
514
10.8k
    if (cinfo->in_color_space == JCS_UNKNOWN ||
515
10.8k
        cinfo->in_color_space == JCS_RGB)
516
0
      cinfo->in_color_space = JCS_GRAYSCALE;
517
10.8k
    TRACEMS3(cinfo, 1, JTRC_PNG_GRAYSCALE, ihdr.width, ihdr.height,
518
10.8k
             ihdr.bit_depth);
519
10.8k
    if (cinfo->in_color_space == JCS_GRAYSCALE) {
520
1.54k
      if (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE &&
521
1.26k
          cinfo->data_precision == ihdr.bit_depth) {
522
667
        source->pub.get_pixel_rows = get_raw_row;
523
667
        use_raw_buffer = TRUE;
524
667
      } else
525
881
        source->pub.get_pixel_rows = get_gray_row;
526
9.28k
    } else if (IsExtRGB(cinfo->in_color_space))
527
7.74k
      source->pub.get_pixel_rows = get_gray_rgb_row;
528
1.54k
    else if (cinfo->in_color_space == JCS_CMYK)
529
1.54k
        source->pub.get_pixel_rows = get_gray_cmyk_row;
530
0
    else
531
0
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
532
10.8k
    if (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA) {
533
1.95k
      png_components = 2;
534
1.95k
      source->png_alpha = 1;
535
8.88k
    } else {
536
8.88k
      png_components = 1;
537
8.88k
      source->png_alpha = 0;
538
8.88k
    }
539
10.8k
    break;
540
541
11.3k
  case SPNG_COLOR_TYPE_TRUECOLOR:
542
13.1k
  case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
543
13.1k
    if (cinfo->in_color_space == JCS_UNKNOWN)
544
0
      cinfo->in_color_space = JCS_EXT_RGB;
545
13.1k
    TRACEMS3(cinfo, 1, JTRC_PNG_TRUECOLOR, ihdr.width, ihdr.height,
546
13.1k
             ihdr.bit_depth);
547
13.1k
    if (ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR &&
548
11.3k
        cinfo->data_precision == ihdr.bit_depth &&
549
2.86k
#if RGB_RED == 0 && RGB_GREEN == 1 && RGB_BLUE == 2 && RGB_PIXELSIZE == 3
550
2.86k
        (cinfo->in_color_space == JCS_EXT_RGB ||
551
2.15k
         cinfo->in_color_space == JCS_RGB)) {
552
#else
553
        cinfo->in_color_space == JCS_EXT_RGB) {
554
#endif
555
717
      source->pub.get_pixel_rows = get_raw_row;
556
717
      use_raw_buffer = TRUE;
557
12.4k
    } else if (IsExtRGB(cinfo->in_color_space))
558
8.66k
      source->pub.get_pixel_rows = get_rgb_row;
559
3.75k
    else if (cinfo->in_color_space == JCS_CMYK)
560
1.87k
      source->pub.get_pixel_rows = get_rgb_cmyk_row;
561
1.87k
    else
562
1.87k
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
563
13.1k
    if (ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA) {
564
1.53k
      png_components = 4;
565
1.53k
      source->png_alpha = 1;
566
11.6k
    } else {
567
11.6k
      png_components = 3;
568
11.6k
      source->png_alpha = 0;
569
11.6k
    }
570
13.1k
    break;
571
572
1.14k
  case SPNG_COLOR_TYPE_INDEXED:
573
1.14k
  {
574
1.14k
    int i, gray = 1;
575
576
1.14k
    TRACEMS3(cinfo, 1, JTRC_PNG_INDEXED, ihdr.width, ihdr.height,
577
1.14k
             ihdr.bit_depth);
578
1.14k
    TRY_SPNG(spng_get_plte(source->ctx, &source->colormap));
579
1.14k
    if (source->png_bit_depth != 8 || source->colormap.n_entries > 256)
580
0
      ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
581
582
26.1k
    for (i = 0; i < (int)source->colormap.n_entries; i++) {
583
25.0k
      if (source->colormap.entries[i].red !=
584
25.0k
          source->colormap.entries[i].green ||
585
13.5k
          source->colormap.entries[i].green !=
586
13.5k
          source->colormap.entries[i].blue)
587
12.6k
        gray = 0;
588
25.0k
    }
589
590
1.14k
    if ((cinfo->in_color_space == JCS_UNKNOWN ||
591
518
         cinfo->in_color_space == JCS_RGB) && gray)
592
0
      cinfo->in_color_space = JCS_GRAYSCALE;
593
1.14k
    else if (cinfo->in_color_space == JCS_UNKNOWN)
594
0
      cinfo->in_color_space = JCS_EXT_RGB;
595
1.14k
    if (cinfo->in_color_space == JCS_GRAYSCALE && !gray)
596
62
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
597
598
1.14k
    source->pub.get_pixel_rows = get_indexed_row;
599
1.14k
    png_components = 1;
600
1.14k
    source->png_alpha = 0;
601
1.14k
    break;
602
11.3k
  }
603
604
0
  default:
605
0
    ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
606
32.3k
  }
607
608
22.5k
  if (IsExtRGB(cinfo->in_color_space))
609
17.4k
    cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
610
5.05k
  else if (cinfo->in_color_space == JCS_GRAYSCALE)
611
1.56k
    cinfo->input_components = 1;
612
3.49k
  else if (cinfo->in_color_space == JCS_CMYK)
613
3.49k
    cinfo->input_components = 4;
614
615
  /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */
616
22.5k
  source->buffer_width =
617
22.5k
    (size_t)ihdr.width * png_components * source->png_bit_depth / 8;
618
22.5k
  source->iobuffer = (unsigned char *)
619
22.5k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
620
22.5k
                                source->buffer_width);
621
622
  /* Create compressor input buffer. */
623
22.5k
  if (use_raw_buffer) {
624
    /* For unscaled raw-input case, we can just map it onto the I/O buffer. */
625
    /* Synthesize a _JSAMPARRAY pointer structure */
626
1.38k
    source->pixrow = (_JSAMPROW)source->iobuffer;
627
1.38k
    source->pub._buffer = &source->pixrow;
628
1.38k
    source->pub.buffer_height = 1;
629
21.1k
  } else {
630
21.1k
    unsigned int maxval = source->png_bit_depth == 16 ? 65535 : 255;
631
21.1k
    size_t val, half_maxval;
632
633
    /* Need to translate anyway, so make a separate sample buffer. */
634
21.1k
    source->pub._buffer = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
635
21.1k
      ((j_common_ptr)cinfo, JPOOL_IMAGE,
636
21.1k
       (JDIMENSION)ihdr.width * cinfo->input_components, (JDIMENSION)1);
637
21.1k
    source->pub.buffer_height = 1;
638
639
    /* Compute the rescaling array. */
640
21.1k
    source->rescale = (_JSAMPLE *)
641
21.1k
      (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
642
21.1k
                                  (maxval + 1L) * sizeof(_JSAMPLE));
643
21.1k
    memset(source->rescale, 0, (maxval + 1L) * sizeof(_JSAMPLE));
644
21.1k
    half_maxval = maxval / 2;
645
637M
    for (val = 0; val <= maxval; val++) {
646
      /* The multiplication here must be done in 32 bits to avoid overflow */
647
637M
      source->rescale[val] =
648
637M
        (_JSAMPLE)((val * ((1 << cinfo->data_precision) - 1) + half_maxval) /
649
637M
                   maxval);
650
637M
    }
651
21.1k
  }
652
653
22.5k
  TRY_SPNG(spng_decode_image(source->ctx, NULL, 0, SPNG_FMT_PNG,
654
22.5k
                             SPNG_DECODE_PROGRESSIVE));
655
22.5k
}
Unexecuted instantiation: rdpng-8.c:start_input_png
Unexecuted instantiation: rdpng-12.c:start_input_png
rdpng-16.c:start_input_png
Line
Count
Source
472
32.3k
{
473
32.3k
  png_source_ptr source = (png_source_ptr)sinfo;
474
32.3k
  struct spng_ihdr ihdr;
475
32.3k
  int png_components = 3;
476
32.3k
  boolean use_raw_buffer;
477
#ifdef ZERO_BUFFERS
478
  struct spng_alloc alloc;
479
480
  alloc.malloc_fn = spng_malloc;
481
  alloc.realloc_fn = realloc;
482
  alloc.calloc_fn = calloc;
483
  alloc.free_fn = free;
484
  source->ctx = spng_ctx_new2(&alloc, 0);
485
#else
486
32.3k
  source->ctx = spng_ctx_new(0);
487
32.3k
#endif
488
32.3k
  if (!source->ctx)
489
0
    ERREXITS(cinfo, JERR_PNG_LIBSPNG, "Could not create context");
490
491
32.3k
  TRY_SPNG(spng_set_png_file(source->ctx, sinfo->input_file));
492
493
32.3k
  TRY_SPNG(spng_get_ihdr(source->ctx, &ihdr));
494
495
32.3k
  if (ihdr.width > JPEG_MAX_DIMENSION || ihdr.height > JPEG_MAX_DIMENSION)
496
441
    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, JPEG_MAX_DIMENSION);
497
32.3k
  if (ihdr.bit_depth != 8 && ihdr.bit_depth != 16)
498
5.02k
    ERREXIT(cinfo, JERR_PNG_BADDEPTH);
499
32.3k
  if (sinfo->max_pixels &&
500
25.4k
      (unsigned long long)ihdr.width * ihdr.height > sinfo->max_pixels)
501
301
    ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, sinfo->max_pixels);
502
503
32.3k
  cinfo->image_width = (JDIMENSION)ihdr.width;
504
32.3k
  cinfo->image_height = (JDIMENSION)ihdr.height;
505
32.3k
  source->png_bit_depth = ihdr.bit_depth;
506
32.3k
  source->png_color_type = ihdr.color_type;
507
508
  /* initialize flags to most common settings */
509
32.3k
  use_raw_buffer = FALSE;       /* do we map input buffer onto I/O buffer? */
510
511
32.3k
  switch (ihdr.color_type) {
512
1.95k
  case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
513
10.8k
  case SPNG_COLOR_TYPE_GRAYSCALE:
514
10.8k
    if (cinfo->in_color_space == JCS_UNKNOWN ||
515
10.8k
        cinfo->in_color_space == JCS_RGB)
516
0
      cinfo->in_color_space = JCS_GRAYSCALE;
517
10.8k
    TRACEMS3(cinfo, 1, JTRC_PNG_GRAYSCALE, ihdr.width, ihdr.height,
518
10.8k
             ihdr.bit_depth);
519
10.8k
    if (cinfo->in_color_space == JCS_GRAYSCALE) {
520
1.54k
      if (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE &&
521
1.26k
          cinfo->data_precision == ihdr.bit_depth) {
522
667
        source->pub.get_pixel_rows = get_raw_row;
523
667
        use_raw_buffer = TRUE;
524
667
      } else
525
881
        source->pub.get_pixel_rows = get_gray_row;
526
9.28k
    } else if (IsExtRGB(cinfo->in_color_space))
527
7.74k
      source->pub.get_pixel_rows = get_gray_rgb_row;
528
1.54k
    else if (cinfo->in_color_space == JCS_CMYK)
529
1.54k
        source->pub.get_pixel_rows = get_gray_cmyk_row;
530
0
    else
531
0
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
532
10.8k
    if (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA) {
533
1.95k
      png_components = 2;
534
1.95k
      source->png_alpha = 1;
535
8.88k
    } else {
536
8.88k
      png_components = 1;
537
8.88k
      source->png_alpha = 0;
538
8.88k
    }
539
10.8k
    break;
540
541
11.3k
  case SPNG_COLOR_TYPE_TRUECOLOR:
542
13.1k
  case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
543
13.1k
    if (cinfo->in_color_space == JCS_UNKNOWN)
544
0
      cinfo->in_color_space = JCS_EXT_RGB;
545
13.1k
    TRACEMS3(cinfo, 1, JTRC_PNG_TRUECOLOR, ihdr.width, ihdr.height,
546
13.1k
             ihdr.bit_depth);
547
13.1k
    if (ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR &&
548
11.3k
        cinfo->data_precision == ihdr.bit_depth &&
549
2.86k
#if RGB_RED == 0 && RGB_GREEN == 1 && RGB_BLUE == 2 && RGB_PIXELSIZE == 3
550
2.86k
        (cinfo->in_color_space == JCS_EXT_RGB ||
551
2.15k
         cinfo->in_color_space == JCS_RGB)) {
552
#else
553
        cinfo->in_color_space == JCS_EXT_RGB) {
554
#endif
555
717
      source->pub.get_pixel_rows = get_raw_row;
556
717
      use_raw_buffer = TRUE;
557
12.4k
    } else if (IsExtRGB(cinfo->in_color_space))
558
8.66k
      source->pub.get_pixel_rows = get_rgb_row;
559
3.75k
    else if (cinfo->in_color_space == JCS_CMYK)
560
1.87k
      source->pub.get_pixel_rows = get_rgb_cmyk_row;
561
1.87k
    else
562
1.87k
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
563
13.1k
    if (ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA) {
564
1.53k
      png_components = 4;
565
1.53k
      source->png_alpha = 1;
566
11.6k
    } else {
567
11.6k
      png_components = 3;
568
11.6k
      source->png_alpha = 0;
569
11.6k
    }
570
13.1k
    break;
571
572
1.14k
  case SPNG_COLOR_TYPE_INDEXED:
573
1.14k
  {
574
1.14k
    int i, gray = 1;
575
576
1.14k
    TRACEMS3(cinfo, 1, JTRC_PNG_INDEXED, ihdr.width, ihdr.height,
577
1.14k
             ihdr.bit_depth);
578
1.14k
    TRY_SPNG(spng_get_plte(source->ctx, &source->colormap));
579
1.14k
    if (source->png_bit_depth != 8 || source->colormap.n_entries > 256)
580
0
      ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
581
582
26.1k
    for (i = 0; i < (int)source->colormap.n_entries; i++) {
583
25.0k
      if (source->colormap.entries[i].red !=
584
25.0k
          source->colormap.entries[i].green ||
585
13.5k
          source->colormap.entries[i].green !=
586
13.5k
          source->colormap.entries[i].blue)
587
12.6k
        gray = 0;
588
25.0k
    }
589
590
1.14k
    if ((cinfo->in_color_space == JCS_UNKNOWN ||
591
518
         cinfo->in_color_space == JCS_RGB) && gray)
592
0
      cinfo->in_color_space = JCS_GRAYSCALE;
593
1.14k
    else if (cinfo->in_color_space == JCS_UNKNOWN)
594
0
      cinfo->in_color_space = JCS_EXT_RGB;
595
1.14k
    if (cinfo->in_color_space == JCS_GRAYSCALE && !gray)
596
62
      ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
597
598
1.14k
    source->pub.get_pixel_rows = get_indexed_row;
599
1.14k
    png_components = 1;
600
1.14k
    source->png_alpha = 0;
601
1.14k
    break;
602
11.3k
  }
603
604
0
  default:
605
0
    ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
606
32.3k
  }
607
608
22.5k
  if (IsExtRGB(cinfo->in_color_space))
609
17.4k
    cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
610
5.05k
  else if (cinfo->in_color_space == JCS_GRAYSCALE)
611
1.56k
    cinfo->input_components = 1;
612
3.49k
  else if (cinfo->in_color_space == JCS_CMYK)
613
3.49k
    cinfo->input_components = 4;
614
615
  /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */
616
22.5k
  source->buffer_width =
617
22.5k
    (size_t)ihdr.width * png_components * source->png_bit_depth / 8;
618
22.5k
  source->iobuffer = (unsigned char *)
619
22.5k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
620
22.5k
                                source->buffer_width);
621
622
  /* Create compressor input buffer. */
623
22.5k
  if (use_raw_buffer) {
624
    /* For unscaled raw-input case, we can just map it onto the I/O buffer. */
625
    /* Synthesize a _JSAMPARRAY pointer structure */
626
1.38k
    source->pixrow = (_JSAMPROW)source->iobuffer;
627
1.38k
    source->pub._buffer = &source->pixrow;
628
1.38k
    source->pub.buffer_height = 1;
629
21.1k
  } else {
630
21.1k
    unsigned int maxval = source->png_bit_depth == 16 ? 65535 : 255;
631
21.1k
    size_t val, half_maxval;
632
633
    /* Need to translate anyway, so make a separate sample buffer. */
634
21.1k
    source->pub._buffer = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
635
21.1k
      ((j_common_ptr)cinfo, JPOOL_IMAGE,
636
21.1k
       (JDIMENSION)ihdr.width * cinfo->input_components, (JDIMENSION)1);
637
21.1k
    source->pub.buffer_height = 1;
638
639
    /* Compute the rescaling array. */
640
21.1k
    source->rescale = (_JSAMPLE *)
641
21.1k
      (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
642
21.1k
                                  (maxval + 1L) * sizeof(_JSAMPLE));
643
21.1k
    memset(source->rescale, 0, (maxval + 1L) * sizeof(_JSAMPLE));
644
21.1k
    half_maxval = maxval / 2;
645
637M
    for (val = 0; val <= maxval; val++) {
646
      /* The multiplication here must be done in 32 bits to avoid overflow */
647
637M
      source->rescale[val] =
648
637M
        (_JSAMPLE)((val * ((1 << cinfo->data_precision) - 1) + half_maxval) /
649
637M
                   maxval);
650
637M
    }
651
21.1k
  }
652
653
22.5k
  TRY_SPNG(spng_decode_image(source->ctx, NULL, 0, SPNG_FMT_PNG,
654
22.5k
                             SPNG_DECODE_PROGRESSIVE));
655
22.5k
}
656
657
658
/*
659
 * Return the ICC profile (if any) embedded in the PNG image.
660
 */
661
662
METHODDEF(boolean)
663
read_icc_profile_png(j_compress_ptr cinfo, cjpeg_source_ptr sinfo,
664
                     JOCTET **icc_data_ptr, unsigned int *icc_data_len)
665
7.83k
{
666
7.83k
  png_source_ptr source = (png_source_ptr)sinfo;
667
7.83k
  struct spng_iccp iccp;
668
669
7.83k
  if (!icc_data_ptr || !icc_data_len)
670
0
    ERREXIT(cinfo, JERR_BUFFER_SIZE);
671
672
7.83k
  if (source->ctx && spng_get_iccp(source->ctx, &iccp) == 0) {
673
7
    *icc_data_ptr = (JOCTET *)iccp.profile;
674
7
    *icc_data_len = (unsigned int)iccp.profile_len;
675
7
    return TRUE;
676
7
  }
677
678
7.82k
  return FALSE;
679
7.83k
}
Unexecuted instantiation: rdpng-8.c:read_icc_profile_png
Unexecuted instantiation: rdpng-12.c:read_icc_profile_png
rdpng-16.c:read_icc_profile_png
Line
Count
Source
665
7.83k
{
666
7.83k
  png_source_ptr source = (png_source_ptr)sinfo;
667
7.83k
  struct spng_iccp iccp;
668
669
7.83k
  if (!icc_data_ptr || !icc_data_len)
670
0
    ERREXIT(cinfo, JERR_BUFFER_SIZE);
671
672
7.83k
  if (source->ctx && spng_get_iccp(source->ctx, &iccp) == 0) {
673
7
    *icc_data_ptr = (JOCTET *)iccp.profile;
674
7
    *icc_data_len = (unsigned int)iccp.profile_len;
675
7
    return TRUE;
676
7
  }
677
678
7.82k
  return FALSE;
679
7.83k
}
680
681
682
/*
683
 * Finish up at the end of the file.
684
 */
685
686
METHODDEF(void)
687
finish_input_png(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
688
32.3k
{
689
32.3k
  png_source_ptr source = (png_source_ptr)sinfo;
690
691
32.3k
  if (source->ctx) {
692
32.3k
    spng_decode_chunks(source->ctx);
693
32.3k
    spng_ctx_free(source->ctx);
694
32.3k
    source->ctx = NULL;
695
32.3k
  }
696
32.3k
}
Unexecuted instantiation: rdpng-8.c:finish_input_png
Unexecuted instantiation: rdpng-12.c:finish_input_png
rdpng-16.c:finish_input_png
Line
Count
Source
688
32.3k
{
689
32.3k
  png_source_ptr source = (png_source_ptr)sinfo;
690
691
32.3k
  if (source->ctx) {
692
32.3k
    spng_decode_chunks(source->ctx);
693
32.3k
    spng_ctx_free(source->ctx);
694
    source->ctx = NULL;
695
32.3k
  }
696
32.3k
}
697
698
699
/*
700
 * The module selection routine for PNG format input.
701
 */
702
703
GLOBAL(cjpeg_source_ptr)
704
_jinit_read_png(j_compress_ptr cinfo)
705
32.3k
{
706
32.3k
  png_source_ptr source;
707
708
#if BITS_IN_JSAMPLE == 8
709
0
  if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)
710
#else
711
32.3k
  if (cinfo->data_precision > BITS_IN_JSAMPLE ||
712
32.3k
      cinfo->data_precision < BITS_IN_JSAMPLE - 3)
713
0
#endif
714
0
    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
715
716
  /* Create module interface object */
717
32.3k
  source = (png_source_ptr)
718
32.3k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
719
32.3k
                                sizeof(png_source_struct));
720
  /* Fill in method ptrs, except get_pixel_rows which start_input sets */
721
32.3k
  source->pub.start_input = start_input_png;
722
32.3k
  source->pub.read_icc_profile = read_icc_profile_png;
723
32.3k
  source->pub.finish_input = finish_input_png;
724
32.3k
  source->pub.max_pixels = 0;
725
726
32.3k
  return (cjpeg_source_ptr)source;
727
32.3k
}
Unexecuted instantiation: jinit_read_png
Unexecuted instantiation: j12init_read_png
j16init_read_png
Line
Count
Source
705
32.3k
{
706
32.3k
  png_source_ptr source;
707
708
#if BITS_IN_JSAMPLE == 8
709
  if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)
710
#else
711
32.3k
  if (cinfo->data_precision > BITS_IN_JSAMPLE ||
712
32.3k
      cinfo->data_precision < BITS_IN_JSAMPLE - 3)
713
0
#endif
714
0
    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
715
716
  /* Create module interface object */
717
32.3k
  source = (png_source_ptr)
718
32.3k
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
719
32.3k
                                sizeof(png_source_struct));
720
  /* Fill in method ptrs, except get_pixel_rows which start_input sets */
721
32.3k
  source->pub.start_input = start_input_png;
722
32.3k
  source->pub.read_icc_profile = read_icc_profile_png;
723
32.3k
  source->pub.finish_input = finish_input_png;
724
32.3k
  source->pub.max_pixels = 0;
725
726
32.3k
  return (cjpeg_source_ptr)source;
727
32.3k
}
728
729
#endif /* defined(PNG_SUPPORTED) &&
730
          (BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)) */