/src/libjpeg-turbo.3.0.x/turbojpeg-mp.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2009-2026 D. R. Commander. All Rights Reserved. |
3 | | * |
4 | | * Redistribution and use in source and binary forms, with or without |
5 | | * modification, are permitted provided that the following conditions are met: |
6 | | * |
7 | | * - Redistributions of source code must retain the above copyright notice, |
8 | | * this list of conditions and the following disclaimer. |
9 | | * - Redistributions in binary form must reproduce the above copyright notice, |
10 | | * this list of conditions and the following disclaimer in the documentation |
11 | | * and/or other materials provided with the distribution. |
12 | | * - Neither the name of the libjpeg-turbo Project nor the names of its |
13 | | * contributors may be used to endorse or promote products derived from this |
14 | | * software without specific prior written permission. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", |
17 | | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE |
20 | | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | | * POSSIBILITY OF SUCH DAMAGE. |
27 | | */ |
28 | | |
29 | | /* TurboJPEG API functions that must be compiled for multiple data |
30 | | precisions */ |
31 | | |
32 | | #if BITS_IN_JSAMPLE == 8 |
33 | 98.4M | #define _JSAMPLE JSAMPLE |
34 | 57.9k | #define _JSAMPROW JSAMPROW |
35 | 98.3M | #define _buffer buffer |
36 | 47.3k | #define _jinit_read_ppm jinit_read_ppm |
37 | 0 | #define _jinit_write_ppm jinit_write_ppm |
38 | 1.57k | #define _jpeg_crop_scanline jpeg_crop_scanline |
39 | 26.4M | #define _jpeg_read_scanlines jpeg_read_scanlines |
40 | 3.13k | #define _jpeg_skip_scanlines jpeg_skip_scanlines |
41 | 17.6k | #define _jpeg_write_scanlines jpeg_write_scanlines |
42 | | #elif BITS_IN_JSAMPLE == 12 |
43 | 65.9M | #define _JSAMPLE J12SAMPLE |
44 | 38.3k | #define _JSAMPROW J12SAMPROW |
45 | 65.9M | #define _buffer buffer12 |
46 | 30.8k | #define _jinit_read_ppm j12init_read_ppm |
47 | 0 | #define _jinit_write_ppm j12init_write_ppm |
48 | 1.05k | #define _jpeg_crop_scanline jpeg12_crop_scanline |
49 | 12.3M | #define _jpeg_read_scanlines jpeg12_read_scanlines |
50 | 2.05k | #define _jpeg_skip_scanlines jpeg12_skip_scanlines |
51 | 18.0k | #define _jpeg_write_scanlines jpeg12_write_scanlines |
52 | | #elif BITS_IN_JSAMPLE == 16 |
53 | 13.5M | #define _JSAMPLE J16SAMPLE |
54 | 13.6k | #define _JSAMPROW J16SAMPROW |
55 | 13.4M | #define _buffer buffer16 |
56 | 10.7k | #define _jinit_read_ppm j16init_read_ppm |
57 | 0 | #define _jinit_write_ppm j16init_write_ppm |
58 | 2.62M | #define _jpeg_read_scanlines jpeg16_read_scanlines |
59 | 4.35k | #define _jpeg_write_scanlines jpeg16_write_scanlines |
60 | | #endif |
61 | | |
62 | 0 | #define _GET_NAME(name, suffix) name##suffix |
63 | 0 | #define GET_NAME(name, suffix) _GET_NAME(name, suffix) |
64 | 216k | #define _GET_STRING(name, suffix) #name #suffix |
65 | 216k | #define GET_STRING(name, suffix) _GET_STRING(name, suffix) |
66 | | |
67 | | |
68 | | /******************************** Compressor *********************************/ |
69 | | |
70 | | /* TurboJPEG 3+ */ |
71 | | DLLEXPORT int GET_NAME(tj3Compress, BITS_IN_JSAMPLE) |
72 | | (tjhandle handle, const _JSAMPLE *srcBuf, int width, int pitch, int height, |
73 | | int pixelFormat, unsigned char **jpegBuf, size_t *jpegSize) |
74 | 40.0k | { |
75 | 40.0k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); |
76 | 40.0k | int i, retval = 0; |
77 | 40.0k | boolean alloc = TRUE; |
78 | 40.0k | _JSAMPROW *row_pointer = NULL; |
79 | | |
80 | 40.0k | GET_CINSTANCE(handle) |
81 | 40.0k | if ((this->init & COMPRESS) == 0) |
82 | 40.0k | THROW("Instance has not been initialized for compression"); |
83 | | |
84 | 40.0k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || |
85 | 40.0k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || |
86 | 40.0k | jpegSize == NULL) |
87 | 40.0k | THROW("Invalid argument"); |
88 | | |
89 | 40.0k | if (!this->lossless && this->quality == -1) |
90 | 40.0k | THROW("TJPARAM_QUALITY must be specified"); |
91 | 40.0k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) |
92 | 40.0k | THROW("TJPARAM_SUBSAMP must be specified"); |
93 | | |
94 | 40.0k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; |
95 | | |
96 | 40.0k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) |
97 | 40.0k | THROW("Memory allocation failure"); |
98 | | |
99 | 40.0k | CATCH_LIBJPEG(this); |
100 | | |
101 | 40.0k | cinfo->image_width = width; |
102 | 40.0k | cinfo->image_height = height; |
103 | 40.0k | cinfo->data_precision = BITS_IN_JSAMPLE; |
104 | | |
105 | 40.0k | setCompDefaults(this, pixelFormat, FALSE); |
106 | 40.0k | if (this->noRealloc) { |
107 | 34.2k | alloc = FALSE; |
108 | 34.2k | *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); |
109 | 34.2k | } |
110 | 40.0k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); |
111 | | |
112 | 40.0k | jpeg_start_compress(cinfo, TRUE); |
113 | 140M | for (i = 0; i < height; i++) { |
114 | 140M | if (this->bottomUp) |
115 | 20.2M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; |
116 | 120M | else |
117 | 120M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; |
118 | 140M | } |
119 | 80.0k | while (cinfo->next_scanline < cinfo->image_height) |
120 | 40.0k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], |
121 | 40.0k | cinfo->image_height - cinfo->next_scanline); |
122 | 40.0k | jpeg_finish_compress(cinfo); |
123 | | |
124 | 40.0k | bailout: |
125 | 40.0k | if (cinfo->global_state > CSTATE_START && alloc) |
126 | 32 | (*cinfo->dest->term_destination) (cinfo); |
127 | 40.0k | if (cinfo->global_state > CSTATE_START || retval == -1) |
128 | 32 | jpeg_abort_compress(cinfo); |
129 | 40.0k | free(row_pointer); |
130 | 40.0k | if (this->jerr.warning) retval = -1; |
131 | 40.0k | return retval; |
132 | 40.0k | } Line | Count | Source | 74 | 17.6k | { | 75 | 17.6k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 17.6k | int i, retval = 0; | 77 | 17.6k | boolean alloc = TRUE; | 78 | 17.6k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 17.6k | GET_CINSTANCE(handle) | 81 | 17.6k | if ((this->init & COMPRESS) == 0) | 82 | 17.6k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 17.6k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 17.6k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 17.6k | jpegSize == NULL) | 87 | 17.6k | THROW("Invalid argument"); | 88 | | | 89 | 17.6k | if (!this->lossless && this->quality == -1) | 90 | 17.6k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 17.6k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 17.6k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 17.6k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 17.6k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 17.6k | THROW("Memory allocation failure"); | 98 | | | 99 | 17.6k | CATCH_LIBJPEG(this); | 100 | | | 101 | 17.6k | cinfo->image_width = width; | 102 | 17.6k | cinfo->image_height = height; | 103 | 17.6k | cinfo->data_precision = BITS_IN_JSAMPLE; | 104 | | | 105 | 17.6k | setCompDefaults(this, pixelFormat, FALSE); | 106 | 17.6k | if (this->noRealloc) { | 107 | 15.1k | alloc = FALSE; | 108 | 15.1k | *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); | 109 | 15.1k | } | 110 | 17.6k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 111 | | | 112 | 17.6k | jpeg_start_compress(cinfo, TRUE); | 113 | 61.5M | for (i = 0; i < height; i++) { | 114 | 61.5M | if (this->bottomUp) | 115 | 8.93M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 116 | 52.6M | else | 117 | 52.6M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 118 | 61.5M | } | 119 | 35.3k | while (cinfo->next_scanline < cinfo->image_height) | 120 | 17.6k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 121 | 17.6k | cinfo->image_height - cinfo->next_scanline); | 122 | 17.6k | jpeg_finish_compress(cinfo); | 123 | | | 124 | 17.6k | bailout: | 125 | 17.6k | if (cinfo->global_state > CSTATE_START && alloc) | 126 | 0 | (*cinfo->dest->term_destination) (cinfo); | 127 | 17.6k | if (cinfo->global_state > CSTATE_START || retval == -1) | 128 | 0 | jpeg_abort_compress(cinfo); | 129 | 17.6k | free(row_pointer); | 130 | 17.6k | if (this->jerr.warning) retval = -1; | 131 | 17.6k | return retval; | 132 | 17.6k | } |
Line | Count | Source | 74 | 18.0k | { | 75 | 18.0k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 18.0k | int i, retval = 0; | 77 | 18.0k | boolean alloc = TRUE; | 78 | 18.0k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 18.0k | GET_CINSTANCE(handle) | 81 | 18.0k | if ((this->init & COMPRESS) == 0) | 82 | 18.0k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 18.0k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 18.0k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 18.0k | jpegSize == NULL) | 87 | 18.0k | THROW("Invalid argument"); | 88 | | | 89 | 18.0k | if (!this->lossless && this->quality == -1) | 90 | 18.0k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 18.0k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 18.0k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 18.0k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 18.0k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 18.0k | THROW("Memory allocation failure"); | 98 | | | 99 | 18.0k | CATCH_LIBJPEG(this); | 100 | | | 101 | 18.0k | cinfo->image_width = width; | 102 | 18.0k | cinfo->image_height = height; | 103 | 18.0k | cinfo->data_precision = BITS_IN_JSAMPLE; | 104 | | | 105 | 18.0k | setCompDefaults(this, pixelFormat, FALSE); | 106 | 18.0k | if (this->noRealloc) { | 107 | 15.3k | alloc = FALSE; | 108 | 15.3k | *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); | 109 | 15.3k | } | 110 | 18.0k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 111 | | | 112 | 18.0k | jpeg_start_compress(cinfo, TRUE); | 113 | 65.8M | for (i = 0; i < height; i++) { | 114 | 65.8M | if (this->bottomUp) | 115 | 9.40M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 116 | 56.3M | else | 117 | 56.3M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 118 | 65.8M | } | 119 | 36.0k | while (cinfo->next_scanline < cinfo->image_height) | 120 | 18.0k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 121 | 18.0k | cinfo->image_height - cinfo->next_scanline); | 122 | 18.0k | jpeg_finish_compress(cinfo); | 123 | | | 124 | 18.0k | bailout: | 125 | 18.0k | if (cinfo->global_state > CSTATE_START && alloc) | 126 | 0 | (*cinfo->dest->term_destination) (cinfo); | 127 | 18.0k | if (cinfo->global_state > CSTATE_START || retval == -1) | 128 | 0 | jpeg_abort_compress(cinfo); | 129 | 18.0k | free(row_pointer); | 130 | 18.0k | if (this->jerr.warning) retval = -1; | 131 | 18.0k | return retval; | 132 | 18.0k | } |
Line | Count | Source | 74 | 4.35k | { | 75 | 4.35k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 4.35k | int i, retval = 0; | 77 | 4.35k | boolean alloc = TRUE; | 78 | 4.35k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 4.35k | GET_CINSTANCE(handle) | 81 | 4.35k | if ((this->init & COMPRESS) == 0) | 82 | 4.35k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 4.35k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 4.35k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 4.35k | jpegSize == NULL) | 87 | 4.35k | THROW("Invalid argument"); | 88 | | | 89 | 4.35k | if (!this->lossless && this->quality == -1) | 90 | 4.35k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 4.35k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 4.35k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 4.35k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 4.35k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 4.35k | THROW("Memory allocation failure"); | 98 | | | 99 | 4.35k | CATCH_LIBJPEG(this); | 100 | | | 101 | 4.32k | cinfo->image_width = width; | 102 | 4.32k | cinfo->image_height = height; | 103 | 4.32k | cinfo->data_precision = BITS_IN_JSAMPLE; | 104 | | | 105 | 4.32k | setCompDefaults(this, pixelFormat, FALSE); | 106 | 4.32k | if (this->noRealloc) { | 107 | 3.72k | alloc = FALSE; | 108 | 3.72k | *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); | 109 | 3.72k | } | 110 | 4.32k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 111 | | | 112 | 4.32k | jpeg_start_compress(cinfo, TRUE); | 113 | 13.4M | for (i = 0; i < height; i++) { | 114 | 13.4M | if (this->bottomUp) | 115 | 1.92M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 116 | 11.5M | else | 117 | 11.5M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 118 | 13.4M | } | 119 | 8.68k | while (cinfo->next_scanline < cinfo->image_height) | 120 | 4.35k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 121 | 4.35k | cinfo->image_height - cinfo->next_scanline); | 122 | 4.32k | jpeg_finish_compress(cinfo); | 123 | | | 124 | 4.35k | bailout: | 125 | 4.35k | if (cinfo->global_state > CSTATE_START && alloc) | 126 | 32 | (*cinfo->dest->term_destination) (cinfo); | 127 | 4.35k | if (cinfo->global_state > CSTATE_START || retval == -1) | 128 | 32 | jpeg_abort_compress(cinfo); | 129 | 4.35k | free(row_pointer); | 130 | 4.35k | if (this->jerr.warning) retval = -1; | 131 | 4.35k | return retval; | 132 | 4.32k | } |
|
133 | | |
134 | | |
135 | | /******************************* Decompressor ********************************/ |
136 | | |
137 | | /* TurboJPEG 3+ */ |
138 | | DLLEXPORT int GET_NAME(tj3Decompress, BITS_IN_JSAMPLE) |
139 | | (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, |
140 | | _JSAMPLE *dstBuf, int pitch, int pixelFormat) |
141 | 69.9k | { |
142 | 69.9k | static const char FUNCTION_NAME[] = |
143 | 69.9k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); |
144 | 69.9k | _JSAMPROW *row_pointer = NULL; |
145 | 69.9k | int croppedHeight, i, retval = 0; |
146 | | #if BITS_IN_JSAMPLE != 16 |
147 | | int scaledWidth; |
148 | | #endif |
149 | 69.9k | struct my_progress_mgr progress; |
150 | | |
151 | 69.9k | GET_DINSTANCE(handle); |
152 | 69.9k | if ((this->init & DECOMPRESS) == 0) |
153 | 69.9k | THROW("Instance has not been initialized for decompression"); |
154 | | |
155 | 69.9k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || |
156 | 69.9k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) |
157 | 69.9k | THROW("Invalid argument"); |
158 | | |
159 | 69.9k | if (this->scanLimit) { |
160 | 69.9k | memset(&progress, 0, sizeof(struct my_progress_mgr)); |
161 | 69.9k | progress.pub.progress_monitor = my_progress_monitor; |
162 | 69.9k | progress.this = this; |
163 | 69.9k | dinfo->progress = &progress.pub; |
164 | 69.9k | } else |
165 | 0 | dinfo->progress = NULL; |
166 | | |
167 | 69.9k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
168 | | |
169 | 69.9k | CATCH_LIBJPEG(this); |
170 | | |
171 | 69.9k | if (dinfo->global_state <= DSTATE_INHEADER) { |
172 | 69.9k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); |
173 | 69.9k | jpeg_read_header(dinfo, TRUE); |
174 | 69.9k | } |
175 | 30.7k | setDecompParameters(this); |
176 | 30.7k | if (this->maxPixels && |
177 | 0 | (unsigned long long)this->jpegWidth * this->jpegHeight > |
178 | 0 | (unsigned long long)this->maxPixels) |
179 | 30.7k | THROW("Image is too large"); |
180 | 30.7k | this->dinfo.out_color_space = pf2cs[pixelFormat]; |
181 | | #if BITS_IN_JSAMPLE != 16 |
182 | 27.8k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); |
183 | | #endif |
184 | 30.7k | dinfo->do_fancy_upsampling = !this->fastUpsample; |
185 | 30.7k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; |
186 | | |
187 | 30.7k | dinfo->scale_num = this->scalingFactor.num; |
188 | 30.7k | dinfo->scale_denom = this->scalingFactor.denom; |
189 | | |
190 | 30.7k | jpeg_start_decompress(dinfo); |
191 | | |
192 | | #if BITS_IN_JSAMPLE != 16 |
193 | 27.8k | if (this->croppingRegion.x != 0 || |
194 | 25.2k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { |
195 | 2.62k | JDIMENSION crop_x = this->croppingRegion.x; |
196 | 2.62k | JDIMENSION crop_w = this->croppingRegion.w; |
197 | | |
198 | 2.62k | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); |
199 | 2.62k | if ((int)crop_x != this->croppingRegion.x) |
200 | 3 | THROWI("Unexplained mismatch between specified (%d) and\n" |
201 | 2.62k | "actual (%d) cropping region left boundary", |
202 | 2.62k | this->croppingRegion.x, (int)crop_x); |
203 | 2.62k | if ((int)crop_w != this->croppingRegion.w) |
204 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
205 | 2.62k | "actual (%d) cropping region width", |
206 | 2.62k | this->croppingRegion.w, (int)crop_w); |
207 | 2.62k | } |
208 | 27.8k | #endif |
209 | | |
210 | 30.7k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; |
211 | | |
212 | 27.8k | croppedHeight = dinfo->output_height; |
213 | | #if BITS_IN_JSAMPLE != 16 |
214 | 27.8k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) |
215 | 2.62k | croppedHeight = this->croppingRegion.h; |
216 | | #endif |
217 | 30.7k | if ((row_pointer = |
218 | 30.7k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) |
219 | 30.7k | THROW("Memory allocation failure"); |
220 | 30.7k | CATCH_LIBJPEG(this); |
221 | 111M | for (i = 0; i < (int)croppedHeight; i++) { |
222 | 111M | if (this->bottomUp) |
223 | 40.8M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; |
224 | 70.6M | else |
225 | 70.6M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; |
226 | 111M | } |
227 | | |
228 | | #if BITS_IN_JSAMPLE != 16 |
229 | 25.2k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { |
230 | 2.62k | if (this->croppingRegion.y != 0) { |
231 | 2.62k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); |
232 | | |
233 | 2.62k | if ((int)lines != this->croppingRegion.y) |
234 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
235 | | "actual (%d) cropping region upper boundary", |
236 | 2.62k | this->croppingRegion.y, (int)lines); |
237 | 2.62k | } |
238 | 106k | while ((int)dinfo->output_scanline < |
239 | 106k | this->croppingRegion.y + this->croppingRegion.h) |
240 | 103k | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - |
241 | 103k | this->croppingRegion.y], |
242 | 103k | this->croppingRegion.y + this->croppingRegion.h - |
243 | 103k | dinfo->output_scanline); |
244 | 2.62k | if (this->croppingRegion.y + this->croppingRegion.h != |
245 | 2.62k | (int)dinfo->output_height) { |
246 | 2.55k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - |
247 | | this->croppingRegion.y - |
248 | | this->croppingRegion.h); |
249 | | |
250 | 2.55k | if (lines != dinfo->output_height - this->croppingRegion.y - |
251 | 2.55k | this->croppingRegion.h) |
252 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
253 | 2.55k | "actual (%d) cropping region lower boundary", |
254 | 2.55k | this->croppingRegion.y + this->croppingRegion.h, |
255 | 2.55k | (int)(dinfo->output_height - lines)); |
256 | 2.55k | } |
257 | 2.62k | } else |
258 | 20.3k | #endif |
259 | 20.3k | { |
260 | 41.3M | while (dinfo->output_scanline < dinfo->output_height) |
261 | 41.3M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], |
262 | 41.3M | dinfo->output_height - dinfo->output_scanline); |
263 | 20.3k | } |
264 | 22.9k | jpeg_finish_decompress(dinfo); |
265 | | |
266 | 69.9k | bailout: |
267 | 69.9k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); |
268 | 69.9k | free(row_pointer); |
269 | 69.9k | if (this->jerr.warning) retval = -1; |
270 | 69.9k | return retval; |
271 | 22.9k | } Line | Count | Source | 141 | 40.3k | { | 142 | 40.3k | static const char FUNCTION_NAME[] = | 143 | 40.3k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 144 | 40.3k | _JSAMPROW *row_pointer = NULL; | 145 | 40.3k | int croppedHeight, i, retval = 0; | 146 | 40.3k | #if BITS_IN_JSAMPLE != 16 | 147 | 40.3k | int scaledWidth; | 148 | 40.3k | #endif | 149 | 40.3k | struct my_progress_mgr progress; | 150 | | | 151 | 40.3k | GET_DINSTANCE(handle); | 152 | 40.3k | if ((this->init & DECOMPRESS) == 0) | 153 | 40.3k | THROW("Instance has not been initialized for decompression"); | 154 | | | 155 | 40.3k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 156 | 40.3k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 157 | 40.3k | THROW("Invalid argument"); | 158 | | | 159 | 40.3k | if (this->scanLimit) { | 160 | 40.3k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 161 | 40.3k | progress.pub.progress_monitor = my_progress_monitor; | 162 | 40.3k | progress.this = this; | 163 | 40.3k | dinfo->progress = &progress.pub; | 164 | 40.3k | } else | 165 | 0 | dinfo->progress = NULL; | 166 | | | 167 | 40.3k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 168 | | | 169 | 40.3k | CATCH_LIBJPEG(this); | 170 | | | 171 | 40.3k | if (dinfo->global_state <= DSTATE_INHEADER) { | 172 | 40.3k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 173 | 40.3k | jpeg_read_header(dinfo, TRUE); | 174 | 40.3k | } | 175 | 17.6k | setDecompParameters(this); | 176 | 17.6k | if (this->maxPixels && | 177 | 0 | (unsigned long long)this->jpegWidth * this->jpegHeight > | 178 | 0 | (unsigned long long)this->maxPixels) | 179 | 17.6k | THROW("Image is too large"); | 180 | 17.6k | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 181 | 17.6k | #if BITS_IN_JSAMPLE != 16 | 182 | 17.6k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 183 | 17.6k | #endif | 184 | 17.6k | dinfo->do_fancy_upsampling = !this->fastUpsample; | 185 | 17.6k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 186 | | | 187 | 17.6k | dinfo->scale_num = this->scalingFactor.num; | 188 | 17.6k | dinfo->scale_denom = this->scalingFactor.denom; | 189 | | | 190 | 17.6k | jpeg_start_decompress(dinfo); | 191 | | | 192 | 17.6k | #if BITS_IN_JSAMPLE != 16 | 193 | 17.6k | if (this->croppingRegion.x != 0 || | 194 | 16.0k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 195 | 1.57k | JDIMENSION crop_x = this->croppingRegion.x; | 196 | 1.57k | JDIMENSION crop_w = this->croppingRegion.w; | 197 | | | 198 | 1.57k | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 199 | 1.57k | if ((int)crop_x != this->croppingRegion.x) | 200 | 3 | THROWI("Unexplained mismatch between specified (%d) and\n" | 201 | 1.57k | "actual (%d) cropping region left boundary", | 202 | 1.57k | this->croppingRegion.x, (int)crop_x); | 203 | 1.57k | if ((int)crop_w != this->croppingRegion.w) | 204 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 205 | 1.57k | "actual (%d) cropping region width", | 206 | 1.57k | this->croppingRegion.w, (int)crop_w); | 207 | 1.57k | } | 208 | 17.6k | #endif | 209 | | | 210 | 17.6k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 211 | | | 212 | 17.6k | croppedHeight = dinfo->output_height; | 213 | 17.6k | #if BITS_IN_JSAMPLE != 16 | 214 | 17.6k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 215 | 1.57k | croppedHeight = this->croppingRegion.h; | 216 | 17.6k | #endif | 217 | 17.6k | if ((row_pointer = | 218 | 17.6k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 219 | 17.6k | THROW("Memory allocation failure"); | 220 | 17.6k | CATCH_LIBJPEG(this); | 221 | 60.6M | for (i = 0; i < (int)croppedHeight; i++) { | 222 | 60.6M | if (this->bottomUp) | 223 | 22.2M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 224 | 38.3M | else | 225 | 38.3M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 226 | 60.6M | } | 227 | | | 228 | 14.4k | #if BITS_IN_JSAMPLE != 16 | 229 | 16.0k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 230 | 1.57k | if (this->croppingRegion.y != 0) { | 231 | 1.57k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 232 | | | 233 | 1.57k | if ((int)lines != this->croppingRegion.y) | 234 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 235 | 1.57k | "actual (%d) cropping region upper boundary", | 236 | 1.57k | this->croppingRegion.y, (int)lines); | 237 | 1.57k | } | 238 | 70.0k | while ((int)dinfo->output_scanline < | 239 | 70.0k | this->croppingRegion.y + this->croppingRegion.h) | 240 | 68.4k | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 241 | 68.4k | this->croppingRegion.y], | 242 | 68.4k | this->croppingRegion.y + this->croppingRegion.h - | 243 | 68.4k | dinfo->output_scanline); | 244 | 1.57k | if (this->croppingRegion.y + this->croppingRegion.h != | 245 | 1.57k | (int)dinfo->output_height) { | 246 | 1.56k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 247 | 1.56k | this->croppingRegion.y - | 248 | 1.56k | this->croppingRegion.h); | 249 | | | 250 | 1.56k | if (lines != dinfo->output_height - this->croppingRegion.y - | 251 | 1.56k | this->croppingRegion.h) | 252 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 253 | 1.56k | "actual (%d) cropping region lower boundary", | 254 | 1.56k | this->croppingRegion.y + this->croppingRegion.h, | 255 | 1.56k | (int)(dinfo->output_height - lines)); | 256 | 1.56k | } | 257 | 1.57k | } else | 258 | 12.9k | #endif | 259 | 12.9k | { | 260 | 26.4M | while (dinfo->output_scanline < dinfo->output_height) | 261 | 26.4M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 262 | 26.4M | dinfo->output_height - dinfo->output_scanline); | 263 | 12.9k | } | 264 | 14.4k | jpeg_finish_decompress(dinfo); | 265 | | | 266 | 40.3k | bailout: | 267 | 40.3k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 268 | 40.3k | free(row_pointer); | 269 | 40.3k | if (this->jerr.warning) retval = -1; | 270 | 40.3k | return retval; | 271 | 14.4k | } |
Line | Count | Source | 141 | 20.3k | { | 142 | 20.3k | static const char FUNCTION_NAME[] = | 143 | 20.3k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 144 | 20.3k | _JSAMPROW *row_pointer = NULL; | 145 | 20.3k | int croppedHeight, i, retval = 0; | 146 | 20.3k | #if BITS_IN_JSAMPLE != 16 | 147 | 20.3k | int scaledWidth; | 148 | 20.3k | #endif | 149 | 20.3k | struct my_progress_mgr progress; | 150 | | | 151 | 20.3k | GET_DINSTANCE(handle); | 152 | 20.3k | if ((this->init & DECOMPRESS) == 0) | 153 | 20.3k | THROW("Instance has not been initialized for decompression"); | 154 | | | 155 | 20.3k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 156 | 20.3k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 157 | 20.3k | THROW("Invalid argument"); | 158 | | | 159 | 20.3k | if (this->scanLimit) { | 160 | 20.3k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 161 | 20.3k | progress.pub.progress_monitor = my_progress_monitor; | 162 | 20.3k | progress.this = this; | 163 | 20.3k | dinfo->progress = &progress.pub; | 164 | 20.3k | } else | 165 | 0 | dinfo->progress = NULL; | 166 | | | 167 | 20.3k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 168 | | | 169 | 20.3k | CATCH_LIBJPEG(this); | 170 | | | 171 | 20.3k | if (dinfo->global_state <= DSTATE_INHEADER) { | 172 | 20.3k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 173 | 20.3k | jpeg_read_header(dinfo, TRUE); | 174 | 20.3k | } | 175 | 10.1k | setDecompParameters(this); | 176 | 10.1k | if (this->maxPixels && | 177 | 0 | (unsigned long long)this->jpegWidth * this->jpegHeight > | 178 | 0 | (unsigned long long)this->maxPixels) | 179 | 10.1k | THROW("Image is too large"); | 180 | 10.1k | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 181 | 10.1k | #if BITS_IN_JSAMPLE != 16 | 182 | 10.1k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 183 | 10.1k | #endif | 184 | 10.1k | dinfo->do_fancy_upsampling = !this->fastUpsample; | 185 | 10.1k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 186 | | | 187 | 10.1k | dinfo->scale_num = this->scalingFactor.num; | 188 | 10.1k | dinfo->scale_denom = this->scalingFactor.denom; | 189 | | | 190 | 10.1k | jpeg_start_decompress(dinfo); | 191 | | | 192 | 10.1k | #if BITS_IN_JSAMPLE != 16 | 193 | 10.1k | if (this->croppingRegion.x != 0 || | 194 | 9.14k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 195 | 1.05k | JDIMENSION crop_x = this->croppingRegion.x; | 196 | 1.05k | JDIMENSION crop_w = this->croppingRegion.w; | 197 | | | 198 | 1.05k | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 199 | 1.05k | if ((int)crop_x != this->croppingRegion.x) | 200 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 201 | 1.05k | "actual (%d) cropping region left boundary", | 202 | 1.05k | this->croppingRegion.x, (int)crop_x); | 203 | 1.05k | if ((int)crop_w != this->croppingRegion.w) | 204 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 205 | 1.05k | "actual (%d) cropping region width", | 206 | 1.05k | this->croppingRegion.w, (int)crop_w); | 207 | 1.05k | } | 208 | 10.1k | #endif | 209 | | | 210 | 10.1k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 211 | | | 212 | 10.1k | croppedHeight = dinfo->output_height; | 213 | 10.1k | #if BITS_IN_JSAMPLE != 16 | 214 | 10.1k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 215 | 1.05k | croppedHeight = this->croppingRegion.h; | 216 | 10.1k | #endif | 217 | 10.1k | if ((row_pointer = | 218 | 10.1k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 219 | 10.1k | THROW("Memory allocation failure"); | 220 | 10.1k | CATCH_LIBJPEG(this); | 221 | 29.4M | for (i = 0; i < (int)croppedHeight; i++) { | 222 | 29.4M | if (this->bottomUp) | 223 | 11.2M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 224 | 18.1M | else | 225 | 18.1M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 226 | 29.4M | } | 227 | | | 228 | 8.45k | #if BITS_IN_JSAMPLE != 16 | 229 | 9.14k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 230 | 1.05k | if (this->croppingRegion.y != 0) { | 231 | 1.05k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 232 | | | 233 | 1.05k | if ((int)lines != this->croppingRegion.y) | 234 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 235 | 1.05k | "actual (%d) cropping region upper boundary", | 236 | 1.05k | this->croppingRegion.y, (int)lines); | 237 | 1.05k | } | 238 | 36.0k | while ((int)dinfo->output_scanline < | 239 | 36.0k | this->croppingRegion.y + this->croppingRegion.h) | 240 | 35.0k | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 241 | 35.0k | this->croppingRegion.y], | 242 | 35.0k | this->croppingRegion.y + this->croppingRegion.h - | 243 | 35.0k | dinfo->output_scanline); | 244 | 1.05k | if (this->croppingRegion.y + this->croppingRegion.h != | 245 | 1.05k | (int)dinfo->output_height) { | 246 | 998 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 247 | 998 | this->croppingRegion.y - | 248 | 998 | this->croppingRegion.h); | 249 | | | 250 | 998 | if (lines != dinfo->output_height - this->croppingRegion.y - | 251 | 998 | this->croppingRegion.h) | 252 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 253 | 998 | "actual (%d) cropping region lower boundary", | 254 | 998 | this->croppingRegion.y + this->croppingRegion.h, | 255 | 998 | (int)(dinfo->output_height - lines)); | 256 | 998 | } | 257 | 1.05k | } else | 258 | 7.40k | #endif | 259 | 7.40k | { | 260 | 12.3M | while (dinfo->output_scanline < dinfo->output_height) | 261 | 12.3M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 262 | 12.3M | dinfo->output_height - dinfo->output_scanline); | 263 | 7.40k | } | 264 | 8.45k | jpeg_finish_decompress(dinfo); | 265 | | | 266 | 20.3k | bailout: | 267 | 20.3k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 268 | 20.3k | free(row_pointer); | 269 | 20.3k | if (this->jerr.warning) retval = -1; | 270 | 20.3k | return retval; | 271 | 8.45k | } |
Line | Count | Source | 141 | 9.32k | { | 142 | 9.32k | static const char FUNCTION_NAME[] = | 143 | 9.32k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 144 | 9.32k | _JSAMPROW *row_pointer = NULL; | 145 | 9.32k | int croppedHeight, i, retval = 0; | 146 | | #if BITS_IN_JSAMPLE != 16 | 147 | | int scaledWidth; | 148 | | #endif | 149 | 9.32k | struct my_progress_mgr progress; | 150 | | | 151 | 9.32k | GET_DINSTANCE(handle); | 152 | 9.32k | if ((this->init & DECOMPRESS) == 0) | 153 | 9.32k | THROW("Instance has not been initialized for decompression"); | 154 | | | 155 | 9.32k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 156 | 9.32k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 157 | 9.32k | THROW("Invalid argument"); | 158 | | | 159 | 9.32k | if (this->scanLimit) { | 160 | 9.32k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 161 | 9.32k | progress.pub.progress_monitor = my_progress_monitor; | 162 | 9.32k | progress.this = this; | 163 | 9.32k | dinfo->progress = &progress.pub; | 164 | 9.32k | } else | 165 | 0 | dinfo->progress = NULL; | 166 | | | 167 | 9.32k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 168 | | | 169 | 9.32k | CATCH_LIBJPEG(this); | 170 | | | 171 | 9.32k | if (dinfo->global_state <= DSTATE_INHEADER) { | 172 | 9.32k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 173 | 9.32k | jpeg_read_header(dinfo, TRUE); | 174 | 9.32k | } | 175 | 2.87k | setDecompParameters(this); | 176 | 2.87k | if (this->maxPixels && | 177 | 0 | (unsigned long long)this->jpegWidth * this->jpegHeight > | 178 | 0 | (unsigned long long)this->maxPixels) | 179 | 2.87k | THROW("Image is too large"); | 180 | 2.87k | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 181 | | #if BITS_IN_JSAMPLE != 16 | 182 | | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 183 | | #endif | 184 | 2.87k | dinfo->do_fancy_upsampling = !this->fastUpsample; | 185 | 2.87k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 186 | | | 187 | 2.87k | dinfo->scale_num = this->scalingFactor.num; | 188 | 2.87k | dinfo->scale_denom = this->scalingFactor.denom; | 189 | | | 190 | 2.87k | jpeg_start_decompress(dinfo); | 191 | | | 192 | | #if BITS_IN_JSAMPLE != 16 | 193 | | if (this->croppingRegion.x != 0 || | 194 | | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 195 | | JDIMENSION crop_x = this->croppingRegion.x; | 196 | | JDIMENSION crop_w = this->croppingRegion.w; | 197 | | | 198 | | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 199 | | if ((int)crop_x != this->croppingRegion.x) | 200 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 201 | | "actual (%d) cropping region left boundary", | 202 | | this->croppingRegion.x, (int)crop_x); | 203 | | if ((int)crop_w != this->croppingRegion.w) | 204 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 205 | | "actual (%d) cropping region width", | 206 | | this->croppingRegion.w, (int)crop_w); | 207 | | } | 208 | | #endif | 209 | | | 210 | 2.87k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 211 | | | 212 | 2.87k | croppedHeight = dinfo->output_height; | 213 | | #if BITS_IN_JSAMPLE != 16 | 214 | | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 215 | | croppedHeight = this->croppingRegion.h; | 216 | | #endif | 217 | 2.87k | if ((row_pointer = | 218 | 2.87k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 219 | 2.87k | THROW("Memory allocation failure"); | 220 | 2.87k | CATCH_LIBJPEG(this); | 221 | 21.4M | for (i = 0; i < (int)croppedHeight; i++) { | 222 | 21.4M | if (this->bottomUp) | 223 | 7.31M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 224 | 14.1M | else | 225 | 14.1M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 226 | 21.4M | } | 227 | | | 228 | | #if BITS_IN_JSAMPLE != 16 | 229 | | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 230 | | if (this->croppingRegion.y != 0) { | 231 | | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 232 | | | 233 | | if ((int)lines != this->croppingRegion.y) | 234 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 235 | | "actual (%d) cropping region upper boundary", | 236 | | this->croppingRegion.y, (int)lines); | 237 | | } | 238 | | while ((int)dinfo->output_scanline < | 239 | | this->croppingRegion.y + this->croppingRegion.h) | 240 | | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 241 | | this->croppingRegion.y], | 242 | | this->croppingRegion.y + this->croppingRegion.h - | 243 | | dinfo->output_scanline); | 244 | | if (this->croppingRegion.y + this->croppingRegion.h != | 245 | | (int)dinfo->output_height) { | 246 | | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 247 | | this->croppingRegion.y - | 248 | | this->croppingRegion.h); | 249 | | | 250 | | if (lines != dinfo->output_height - this->croppingRegion.y - | 251 | | this->croppingRegion.h) | 252 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 253 | | "actual (%d) cropping region lower boundary", | 254 | | this->croppingRegion.y + this->croppingRegion.h, | 255 | | (int)(dinfo->output_height - lines)); | 256 | | } | 257 | | } else | 258 | | #endif | 259 | 835 | { | 260 | 2.62M | while (dinfo->output_scanline < dinfo->output_height) | 261 | 2.62M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 262 | 2.62M | dinfo->output_height - dinfo->output_scanline); | 263 | 835 | } | 264 | 835 | jpeg_finish_decompress(dinfo); | 265 | | | 266 | 9.32k | bailout: | 267 | 9.32k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 268 | 9.32k | free(row_pointer); | 269 | 9.32k | if (this->jerr.warning) retval = -1; | 270 | 9.32k | return retval; | 271 | 835 | } |
|
272 | | |
273 | | |
274 | | /*************************** Packed-Pixel Image I/O **************************/ |
275 | | |
276 | | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) |
277 | | |
278 | | /* TurboJPEG 3+ */ |
279 | | #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
280 | | static |
281 | | #endif |
282 | | _JSAMPLE *GET_NAME(_tj3LoadImageFromFileHandle, BITS_IN_JSAMPLE) |
283 | | (tjhandle handle, FILE *file, int *width, int align, int *height, |
284 | | int *pixelFormat) |
285 | 106k | { |
286 | 106k | static const char FUNCTION_NAME[] = |
287 | 106k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); |
288 | | |
289 | 106k | int retval = 0, tempc; |
290 | 106k | size_t pitch; |
291 | 106k | tjhandle handle2 = NULL; |
292 | 106k | tjinstance *this2; |
293 | 106k | j_compress_ptr cinfo = NULL; |
294 | 106k | cjpeg_source_ptr src; |
295 | 106k | _JSAMPLE *dstBuf = NULL; |
296 | 106k | boolean invert; |
297 | | |
298 | 106k | GET_TJINSTANCE(handle, NULL) |
299 | | |
300 | 106k | if (!file || !width || align < 1 || !height || !pixelFormat || |
301 | 106k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) |
302 | 106k | THROW("Invalid argument"); |
303 | 106k | if ((align & (align - 1)) != 0) |
304 | 106k | THROW("Alignment must be a power of 2"); |
305 | | |
306 | | /* The instance handle passed to this function is used only for parameter |
307 | | retrieval. Create a new temporary instance to avoid interfering with the |
308 | | libjpeg state of the primary instance. */ |
309 | 106k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; |
310 | 106k | this2 = (tjinstance *)handle2; |
311 | 106k | cinfo = &this2->cinfo; |
312 | | |
313 | 106k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) |
314 | 0 | THROW_UNIX("Could not read input file") |
315 | 106k | else if (tempc == EOF) |
316 | 106k | THROW("Input file contains no data"); |
317 | | |
318 | 106k | CATCH_LIBJPEG(this2); |
319 | | |
320 | 82.2k | cinfo->data_precision = BITS_IN_JSAMPLE; |
321 | 82.2k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; |
322 | 82.2k | else cinfo->in_color_space = pf2cs[*pixelFormat]; |
323 | 82.2k | if (tempc == 'B') { |
324 | 16.7k | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) |
325 | 16.7k | THROW("Could not initialize bitmap loader"); |
326 | 16.7k | invert = !this->bottomUp; |
327 | 88.9k | } else if (tempc == 'P') { |
328 | 88.9k | if ((src = _jinit_read_ppm(cinfo)) == NULL) |
329 | 88.9k | THROW("Could not initialize PPM loader"); |
330 | 88.9k | invert = this->bottomUp; |
331 | 88.9k | } else |
332 | 18.4E | THROW("Unsupported file type"); |
333 | | |
334 | 105k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
335 | | |
336 | 105k | src->input_file = file; |
337 | | /* Refuse to load images larger than the specified size. */ |
338 | 105k | src->max_pixels = this->maxPixels; |
339 | 105k | (*src->start_input) (cinfo, src); |
340 | 105k | if (tempc == 'B') { |
341 | 4.70k | if (cinfo->X_density && cinfo->Y_density) { |
342 | 1.16k | this->xDensity = cinfo->X_density; |
343 | 1.16k | this->yDensity = cinfo->Y_density; |
344 | 1.16k | this->densityUnits = cinfo->density_unit; |
345 | 1.16k | } |
346 | 4.70k | } |
347 | 105k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); |
348 | | |
349 | 105k | *width = cinfo->image_width; *height = cinfo->image_height; |
350 | 105k | *pixelFormat = cs2pf[cinfo->in_color_space]; |
351 | | |
352 | 105k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); |
353 | 105k | if ( |
354 | | #if ULLONG_MAX > SIZE_MAX |
355 | | (unsigned long long)pitch * (unsigned long long)(*height) > |
356 | | (unsigned long long)((size_t)-1) || |
357 | | #endif |
358 | 105k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * |
359 | 105k | sizeof(_JSAMPLE))) == NULL) |
360 | 105k | THROW("Memory allocation failure"); |
361 | | |
362 | 105k | CATCH_LIBJPEG(this2); |
363 | | |
364 | 177M | while (cinfo->next_scanline < cinfo->image_height) { |
365 | 177M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); |
366 | | |
367 | 355M | for (i = 0; i < nlines; i++) { |
368 | 177M | _JSAMPLE *dstptr; |
369 | 177M | int row; |
370 | | |
371 | 177M | row = cinfo->next_scanline + i; |
372 | 177M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; |
373 | 147M | else dstptr = &dstBuf[row * pitch]; |
374 | 177M | memcpy(dstptr, src->_buffer[i], |
375 | 177M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); |
376 | 177M | } |
377 | 177M | cinfo->next_scanline += nlines; |
378 | 177M | } |
379 | | |
380 | 75.4k | (*src->finish_input) (cinfo, src); |
381 | | |
382 | 106k | bailout: |
383 | 106k | tj3Destroy(handle2); |
384 | 106k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } |
385 | 106k | return dstBuf; |
386 | 75.4k | } _tj3LoadImageFromFileHandle8 Line | Count | Source | 285 | 64.3k | { | 286 | 64.3k | static const char FUNCTION_NAME[] = | 287 | 64.3k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 288 | | | 289 | 64.3k | int retval = 0, tempc; | 290 | 64.3k | size_t pitch; | 291 | 64.3k | tjhandle handle2 = NULL; | 292 | 64.3k | tjinstance *this2; | 293 | 64.3k | j_compress_ptr cinfo = NULL; | 294 | 64.3k | cjpeg_source_ptr src; | 295 | 64.3k | _JSAMPLE *dstBuf = NULL; | 296 | 64.3k | boolean invert; | 297 | | | 298 | 64.3k | GET_TJINSTANCE(handle, NULL) | 299 | | | 300 | 64.3k | if (!file || !width || align < 1 || !height || !pixelFormat || | 301 | 64.3k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 302 | 64.3k | THROW("Invalid argument"); | 303 | 64.3k | if ((align & (align - 1)) != 0) | 304 | 64.3k | THROW("Alignment must be a power of 2"); | 305 | | | 306 | | /* The instance handle passed to this function is used only for parameter | 307 | | retrieval. Create a new temporary instance to avoid interfering with the | 308 | | libjpeg state of the primary instance. */ | 309 | 64.3k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 310 | 64.3k | this2 = (tjinstance *)handle2; | 311 | 64.3k | cinfo = &this2->cinfo; | 312 | | | 313 | 64.3k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 314 | 0 | THROW_UNIX("Could not read input file") | 315 | 64.3k | else if (tempc == EOF) | 316 | 64.3k | THROW("Input file contains no data"); | 317 | | | 318 | 64.3k | CATCH_LIBJPEG(this2); | 319 | | | 320 | 46.3k | cinfo->data_precision = BITS_IN_JSAMPLE; | 321 | 46.3k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 322 | 46.3k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 323 | 46.3k | if (tempc == 'B') { | 324 | 16.7k | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 325 | 16.7k | THROW("Could not initialize bitmap loader"); | 326 | 16.7k | invert = !this->bottomUp; | 327 | 47.3k | } else if (tempc == 'P') { | 328 | 47.3k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 329 | 47.3k | THROW("Could not initialize PPM loader"); | 330 | 47.3k | invert = this->bottomUp; | 331 | 47.3k | } else | 332 | 18.4E | THROW("Unsupported file type"); | 333 | | | 334 | 64.0k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 335 | | | 336 | 64.0k | src->input_file = file; | 337 | | /* Refuse to load images larger than the specified size. */ | 338 | 64.0k | src->max_pixels = this->maxPixels; | 339 | 64.0k | (*src->start_input) (cinfo, src); | 340 | 64.0k | if (tempc == 'B') { | 341 | 4.70k | if (cinfo->X_density && cinfo->Y_density) { | 342 | 1.16k | this->xDensity = cinfo->X_density; | 343 | 1.16k | this->yDensity = cinfo->Y_density; | 344 | 1.16k | this->densityUnits = cinfo->density_unit; | 345 | 1.16k | } | 346 | 4.70k | } | 347 | 64.0k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 348 | | | 349 | 64.0k | *width = cinfo->image_width; *height = cinfo->image_height; | 350 | 64.0k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 351 | | | 352 | 64.0k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 353 | 64.0k | if ( | 354 | | #if ULLONG_MAX > SIZE_MAX | 355 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 356 | | (unsigned long long)((size_t)-1) || | 357 | | #endif | 358 | 64.0k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 359 | 64.0k | sizeof(_JSAMPLE))) == NULL) | 360 | 64.0k | THROW("Memory allocation failure"); | 361 | | | 362 | 64.0k | CATCH_LIBJPEG(this2); | 363 | | | 364 | 98.4M | while (cinfo->next_scanline < cinfo->image_height) { | 365 | 98.3M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 366 | | | 367 | 196M | for (i = 0; i < nlines; i++) { | 368 | 98.3M | _JSAMPLE *dstptr; | 369 | 98.3M | int row; | 370 | | | 371 | 98.3M | row = cinfo->next_scanline + i; | 372 | 98.3M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 373 | 79.0M | else dstptr = &dstBuf[row * pitch]; | 374 | 98.3M | memcpy(dstptr, src->_buffer[i], | 375 | 98.3M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 376 | 98.3M | } | 377 | 98.3M | cinfo->next_scanline += nlines; | 378 | 98.3M | } | 379 | | | 380 | 46.9k | (*src->finish_input) (cinfo, src); | 381 | | | 382 | 64.3k | bailout: | 383 | 64.3k | tj3Destroy(handle2); | 384 | 64.3k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 385 | 64.3k | return dstBuf; | 386 | 46.9k | } |
_tj3LoadImageFromFileHandle12 Line | Count | Source | 285 | 31.1k | { | 286 | 31.1k | static const char FUNCTION_NAME[] = | 287 | 31.1k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 288 | | | 289 | 31.1k | int retval = 0, tempc; | 290 | 31.1k | size_t pitch; | 291 | 31.1k | tjhandle handle2 = NULL; | 292 | 31.1k | tjinstance *this2; | 293 | 31.1k | j_compress_ptr cinfo = NULL; | 294 | 31.1k | cjpeg_source_ptr src; | 295 | 31.1k | _JSAMPLE *dstBuf = NULL; | 296 | 31.1k | boolean invert; | 297 | | | 298 | 31.1k | GET_TJINSTANCE(handle, NULL) | 299 | | | 300 | 31.1k | if (!file || !width || align < 1 || !height || !pixelFormat || | 301 | 31.1k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 302 | 31.1k | THROW("Invalid argument"); | 303 | 31.1k | if ((align & (align - 1)) != 0) | 304 | 31.1k | THROW("Alignment must be a power of 2"); | 305 | | | 306 | | /* The instance handle passed to this function is used only for parameter | 307 | | retrieval. Create a new temporary instance to avoid interfering with the | 308 | | libjpeg state of the primary instance. */ | 309 | 31.1k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 310 | 31.1k | this2 = (tjinstance *)handle2; | 311 | 31.1k | cinfo = &this2->cinfo; | 312 | | | 313 | 31.1k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 314 | 0 | THROW_UNIX("Could not read input file") | 315 | 31.1k | else if (tempc == EOF) | 316 | 31.1k | THROW("Input file contains no data"); | 317 | | | 318 | 31.1k | CATCH_LIBJPEG(this2); | 319 | | | 320 | 26.9k | cinfo->data_precision = BITS_IN_JSAMPLE; | 321 | 26.9k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 322 | 26.9k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 323 | 26.9k | if (tempc == 'B') { | 324 | 14 | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 325 | 14 | THROW("Could not initialize bitmap loader"); | 326 | 14 | invert = !this->bottomUp; | 327 | 30.8k | } else if (tempc == 'P') { | 328 | 30.8k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 329 | 30.8k | THROW("Could not initialize PPM loader"); | 330 | 30.8k | invert = this->bottomUp; | 331 | 30.8k | } else | 332 | 18.4E | THROW("Unsupported file type"); | 333 | | | 334 | 30.8k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 335 | | | 336 | 30.8k | src->input_file = file; | 337 | | /* Refuse to load images larger than the specified size. */ | 338 | 30.8k | src->max_pixels = this->maxPixels; | 339 | 30.8k | (*src->start_input) (cinfo, src); | 340 | 30.8k | if (tempc == 'B') { | 341 | 0 | if (cinfo->X_density && cinfo->Y_density) { | 342 | 0 | this->xDensity = cinfo->X_density; | 343 | 0 | this->yDensity = cinfo->Y_density; | 344 | 0 | this->densityUnits = cinfo->density_unit; | 345 | 0 | } | 346 | 0 | } | 347 | 30.8k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 348 | | | 349 | 30.8k | *width = cinfo->image_width; *height = cinfo->image_height; | 350 | 30.8k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 351 | | | 352 | 30.8k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 353 | 30.8k | if ( | 354 | | #if ULLONG_MAX > SIZE_MAX | 355 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 356 | | (unsigned long long)((size_t)-1) || | 357 | | #endif | 358 | 30.8k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 359 | 30.8k | sizeof(_JSAMPLE))) == NULL) | 360 | 30.8k | THROW("Memory allocation failure"); | 361 | | | 362 | 30.8k | CATCH_LIBJPEG(this2); | 363 | | | 364 | 65.9M | while (cinfo->next_scanline < cinfo->image_height) { | 365 | 65.9M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 366 | | | 367 | 131M | for (i = 0; i < nlines; i++) { | 368 | 65.9M | _JSAMPLE *dstptr; | 369 | 65.9M | int row; | 370 | | | 371 | 65.9M | row = cinfo->next_scanline + i; | 372 | 65.9M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 373 | 56.4M | else dstptr = &dstBuf[row * pitch]; | 374 | 65.9M | memcpy(dstptr, src->_buffer[i], | 375 | 65.9M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 376 | 65.9M | } | 377 | 65.9M | cinfo->next_scanline += nlines; | 378 | 65.9M | } | 379 | | | 380 | 22.1k | (*src->finish_input) (cinfo, src); | 381 | | | 382 | 31.1k | bailout: | 383 | 31.1k | tj3Destroy(handle2); | 384 | 31.1k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 385 | 31.1k | return dstBuf; | 386 | 22.1k | } |
_tj3LoadImageFromFileHandle16 Line | Count | Source | 285 | 10.8k | { | 286 | 10.8k | static const char FUNCTION_NAME[] = | 287 | 10.8k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 288 | | | 289 | 10.8k | int retval = 0, tempc; | 290 | 10.8k | size_t pitch; | 291 | 10.8k | tjhandle handle2 = NULL; | 292 | 10.8k | tjinstance *this2; | 293 | 10.8k | j_compress_ptr cinfo = NULL; | 294 | 10.8k | cjpeg_source_ptr src; | 295 | 10.8k | _JSAMPLE *dstBuf = NULL; | 296 | 10.8k | boolean invert; | 297 | | | 298 | 10.8k | GET_TJINSTANCE(handle, NULL) | 299 | | | 300 | 10.8k | if (!file || !width || align < 1 || !height || !pixelFormat || | 301 | 10.8k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 302 | 10.8k | THROW("Invalid argument"); | 303 | 10.8k | if ((align & (align - 1)) != 0) | 304 | 10.8k | THROW("Alignment must be a power of 2"); | 305 | | | 306 | | /* The instance handle passed to this function is used only for parameter | 307 | | retrieval. Create a new temporary instance to avoid interfering with the | 308 | | libjpeg state of the primary instance. */ | 309 | 10.8k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 310 | 10.8k | this2 = (tjinstance *)handle2; | 311 | 10.8k | cinfo = &this2->cinfo; | 312 | | | 313 | 10.8k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 314 | 0 | THROW_UNIX("Could not read input file") | 315 | 10.8k | else if (tempc == EOF) | 316 | 10.8k | THROW("Input file contains no data"); | 317 | | | 318 | 10.8k | CATCH_LIBJPEG(this2); | 319 | | | 320 | 8.95k | cinfo->data_precision = BITS_IN_JSAMPLE; | 321 | 8.95k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 322 | 8.95k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 323 | 8.95k | if (tempc == 'B') { | 324 | 7 | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 325 | 7 | THROW("Could not initialize bitmap loader"); | 326 | 7 | invert = !this->bottomUp; | 327 | 10.7k | } else if (tempc == 'P') { | 328 | 10.7k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 329 | 10.7k | THROW("Could not initialize PPM loader"); | 330 | 10.7k | invert = this->bottomUp; | 331 | 10.7k | } else | 332 | 18.4E | THROW("Unsupported file type"); | 333 | | | 334 | 10.7k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 335 | | | 336 | 10.7k | src->input_file = file; | 337 | | /* Refuse to load images larger than the specified size. */ | 338 | 10.7k | src->max_pixels = this->maxPixels; | 339 | 10.7k | (*src->start_input) (cinfo, src); | 340 | 10.7k | if (tempc == 'B') { | 341 | 0 | if (cinfo->X_density && cinfo->Y_density) { | 342 | 0 | this->xDensity = cinfo->X_density; | 343 | 0 | this->yDensity = cinfo->Y_density; | 344 | 0 | this->densityUnits = cinfo->density_unit; | 345 | 0 | } | 346 | 0 | } | 347 | 10.7k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 348 | | | 349 | 10.7k | *width = cinfo->image_width; *height = cinfo->image_height; | 350 | 10.7k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 351 | | | 352 | 10.7k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 353 | 10.7k | if ( | 354 | | #if ULLONG_MAX > SIZE_MAX | 355 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 356 | | (unsigned long long)((size_t)-1) || | 357 | | #endif | 358 | 10.7k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 359 | 10.7k | sizeof(_JSAMPLE))) == NULL) | 360 | 10.7k | THROW("Memory allocation failure"); | 361 | | | 362 | 10.7k | CATCH_LIBJPEG(this2); | 363 | | | 364 | 13.5M | while (cinfo->next_scanline < cinfo->image_height) { | 365 | 13.5M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 366 | | | 367 | 27.0M | for (i = 0; i < nlines; i++) { | 368 | 13.4M | _JSAMPLE *dstptr; | 369 | 13.4M | int row; | 370 | | | 371 | 13.4M | row = cinfo->next_scanline + i; | 372 | 13.4M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 373 | 11.5M | else dstptr = &dstBuf[row * pitch]; | 374 | 13.4M | memcpy(dstptr, src->_buffer[i], | 375 | 13.4M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 376 | 13.4M | } | 377 | 13.5M | cinfo->next_scanline += nlines; | 378 | 13.5M | } | 379 | | | 380 | 6.30k | (*src->finish_input) (cinfo, src); | 381 | | | 382 | 10.8k | bailout: | 383 | 10.8k | tj3Destroy(handle2); | 384 | 10.8k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 385 | 10.8k | return dstBuf; | 386 | 6.30k | } |
|
387 | | |
388 | | #endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ |
389 | | |
390 | | DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE) |
391 | | (tjhandle handle, const char *filename, int *width, int align, int *height, |
392 | | int *pixelFormat) |
393 | 0 | { |
394 | 0 | static const char FUNCTION_NAME[] = |
395 | 0 | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); |
396 | |
|
397 | 0 | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) |
398 | |
|
399 | 0 | int retval = 0; |
400 | 0 | _JSAMPLE *dstBuf = NULL; |
401 | 0 | FILE *file = NULL; |
402 | |
|
403 | 0 | GET_TJINSTANCE(handle, NULL) |
404 | |
|
405 | 0 | if (!filename) |
406 | 0 | THROW("Invalid argument"); |
407 | |
|
408 | | #ifdef _MSC_VER |
409 | | if (fopen_s(&file, filename, "rb") || file == NULL) |
410 | | #else |
411 | 0 | if ((file = fopen(filename, "rb")) == NULL) |
412 | 0 | #endif |
413 | 0 | THROW_UNIX("Cannot open input file"); |
414 | |
|
415 | 0 | dstBuf = GET_NAME(_tj3LoadImageFromFileHandle, BITS_IN_JSAMPLE) |
416 | 0 | (handle, file, width, align, height, pixelFormat); |
417 | |
|
418 | 0 | bailout: |
419 | 0 | if (file) fclose(file); |
420 | 0 | if (retval < 0) { free(dstBuf); dstBuf = NULL; } |
421 | 0 | return dstBuf; |
422 | |
|
423 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ |
424 | | |
425 | | static const char ERROR_MSG[] = |
426 | | "16-bit data precision requires lossless JPEG,\n" |
427 | | "which was disabled at build time."; |
428 | | _JSAMPLE *retval = NULL; |
429 | | |
430 | | GET_TJINSTANCE(handle, NULL) |
431 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, |
432 | | ERROR_MSG); |
433 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) |
434 | | |
435 | | bailout: |
436 | | return retval; |
437 | | |
438 | | #endif |
439 | 0 | } Unexecuted instantiation: tj3LoadImage8 Unexecuted instantiation: tj3LoadImage12 Unexecuted instantiation: tj3LoadImage16 |
440 | | |
441 | | |
442 | | /* TurboJPEG 3+ */ |
443 | | DLLEXPORT int GET_NAME(tj3SaveImage, BITS_IN_JSAMPLE) |
444 | | (tjhandle handle, const char *filename, const _JSAMPLE *buffer, int width, |
445 | | int pitch, int height, int pixelFormat) |
446 | 0 | { |
447 | 0 | static const char FUNCTION_NAME[] = |
448 | 0 | GET_STRING(tj3SaveImage, BITS_IN_JSAMPLE); |
449 | 0 | int retval = 0; |
450 | |
|
451 | 0 | #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) |
452 | |
|
453 | 0 | tjhandle handle2 = NULL; |
454 | 0 | tjinstance *this2; |
455 | 0 | j_decompress_ptr dinfo = NULL; |
456 | 0 | djpeg_dest_ptr dst; |
457 | 0 | FILE *file = NULL; |
458 | 0 | const char *ptr = NULL; |
459 | 0 | boolean invert; |
460 | |
|
461 | 0 | GET_TJINSTANCE(handle, -1) |
462 | |
|
463 | 0 | if (!filename || !buffer || width < 1 || pitch < 0 || height < 1 || |
464 | 0 | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) |
465 | 0 | THROW("Invalid argument"); |
466 | | |
467 | | /* The instance handle passed to this function is used only for parameter |
468 | | retrieval. Create a new temporary instance to avoid interfering with the |
469 | | libjpeg state of the primary instance. */ |
470 | 0 | if ((handle2 = tj3Init(TJINIT_DECOMPRESS)) == NULL) |
471 | 0 | return -1; |
472 | 0 | this2 = (tjinstance *)handle2; |
473 | 0 | dinfo = &this2->dinfo; |
474 | |
|
475 | | #ifdef _MSC_VER |
476 | | if (fopen_s(&file, filename, "wb") || file == NULL) |
477 | | #else |
478 | 0 | if ((file = fopen(filename, "wb")) == NULL) |
479 | 0 | #endif |
480 | 0 | THROW_UNIX("Cannot open output file"); |
481 | |
|
482 | 0 | CATCH_LIBJPEG(this2); |
483 | |
|
484 | 0 | this2->dinfo.out_color_space = pf2cs[pixelFormat]; |
485 | 0 | dinfo->image_width = width; dinfo->image_height = height; |
486 | 0 | dinfo->global_state = DSTATE_READY; |
487 | 0 | dinfo->scale_num = dinfo->scale_denom = 1; |
488 | 0 | dinfo->data_precision = BITS_IN_JSAMPLE; |
489 | |
|
490 | 0 | ptr = strrchr(filename, '.'); |
491 | 0 | if (ptr && !strcasecmp(ptr, ".bmp")) { |
492 | 0 | if ((dst = jinit_write_bmp(dinfo, FALSE, FALSE)) == NULL) |
493 | 0 | THROW("Could not initialize bitmap writer"); |
494 | 0 | invert = !this->bottomUp; |
495 | 0 | dinfo->X_density = (UINT16)this->xDensity; |
496 | 0 | dinfo->Y_density = (UINT16)this->yDensity; |
497 | 0 | dinfo->density_unit = (UINT8)this->densityUnits; |
498 | 0 | } else { |
499 | 0 | if ((dst = _jinit_write_ppm(dinfo)) == NULL) |
500 | 0 | THROW("Could not initialize PPM writer"); |
501 | 0 | invert = this->bottomUp; |
502 | 0 | } |
503 | | |
504 | 0 | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
505 | |
|
506 | 0 | dst->output_file = file; |
507 | 0 | (*dst->start_output) (dinfo, dst); |
508 | 0 | (*dinfo->mem->realize_virt_arrays) ((j_common_ptr)dinfo); |
509 | |
|
510 | 0 | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; |
511 | |
|
512 | 0 | while (dinfo->output_scanline < dinfo->output_height) { |
513 | 0 | _JSAMPLE *rowptr; |
514 | |
|
515 | 0 | if (invert) |
516 | 0 | rowptr = |
517 | 0 | (_JSAMPLE *)&buffer[(height - dinfo->output_scanline - 1) * pitch]; |
518 | 0 | else |
519 | 0 | rowptr = (_JSAMPLE *)&buffer[dinfo->output_scanline * pitch]; |
520 | 0 | memcpy(dst->_buffer[0], rowptr, |
521 | 0 | width * tjPixelSize[pixelFormat] * sizeof(_JSAMPLE)); |
522 | 0 | (*dst->put_pixel_rows) (dinfo, dst, 1); |
523 | 0 | dinfo->output_scanline++; |
524 | 0 | } |
525 | |
|
526 | 0 | (*dst->finish_output) (dinfo, dst); |
527 | |
|
528 | 0 | bailout: |
529 | 0 | tj3Destroy(handle2); |
530 | 0 | if (file) fclose(file); |
531 | 0 | return retval; |
532 | |
|
533 | | #else /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */ |
534 | | |
535 | | GET_TJINSTANCE(handle, -1) |
536 | | THROW("16-bit data precision requires lossless JPEG,\n" |
537 | | "which was disabled at build time.") |
538 | | bailout: |
539 | | return retval; |
540 | | |
541 | | #endif |
542 | 0 | } Unexecuted instantiation: tj3SaveImage8 Unexecuted instantiation: tj3SaveImage12 Unexecuted instantiation: tj3SaveImage16 |
543 | | |
544 | | |
545 | | #undef _JSAMPLE |
546 | | #undef _JSAMPROW |
547 | | #undef _buffer |
548 | | #undef _jinit_read_ppm |
549 | | #undef _jinit_write_ppm |
550 | | #undef _jpeg_crop_scanline |
551 | | #undef _jpeg_read_scanlines |
552 | | #undef _jpeg_skip_scanlines |
553 | | #undef _jpeg_write_scanlines |