/src/libjpeg-turbo.3.0.x/turbojpeg-mp.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C)2009-2024 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.0M | #define _JSAMPLE JSAMPLE |
34 | 26.1k | #define _JSAMPROW JSAMPROW |
35 | 97.9M | #define _buffer buffer |
36 | 48.2k | #define _jinit_read_ppm jinit_read_ppm |
37 | 0 | #define _jinit_write_ppm jinit_write_ppm |
38 | 0 | #define _jpeg_crop_scanline jpeg_crop_scanline |
39 | 13.5M | #define _jpeg_read_scanlines jpeg_read_scanlines |
40 | 0 | #define _jpeg_skip_scanlines jpeg_skip_scanlines |
41 | 18.1k | #define _jpeg_write_scanlines jpeg_write_scanlines |
42 | | #elif BITS_IN_JSAMPLE == 12 |
43 | 98.0M | #define _JSAMPLE J12SAMPLE |
44 | 33.9k | #define _JSAMPROW J12SAMPROW |
45 | 97.9M | #define _buffer buffer12 |
46 | 40.1k | #define _jinit_read_ppm j12init_read_ppm |
47 | 0 | #define _jinit_write_ppm j12init_write_ppm |
48 | 0 | #define _jpeg_crop_scanline jpeg12_crop_scanline |
49 | 9.99M | #define _jpeg_read_scanlines jpeg12_read_scanlines |
50 | 0 | #define _jpeg_skip_scanlines jpeg12_skip_scanlines |
51 | 26.7k | #define _jpeg_write_scanlines jpeg12_write_scanlines |
52 | | #elif BITS_IN_JSAMPLE == 16 |
53 | 14.2M | #define _JSAMPLE J16SAMPLE |
54 | 5.91k | #define _JSAMPROW J16SAMPROW |
55 | 14.2M | #define _buffer buffer16 |
56 | 11.1k | #define _jinit_read_ppm j16init_read_ppm |
57 | 0 | #define _jinit_write_ppm j16init_write_ppm |
58 | 435k | #define _jpeg_read_scanlines jpeg16_read_scanlines |
59 | 4.56k | #define _jpeg_write_scanlines jpeg16_write_scanlines |
60 | | #endif |
61 | | |
62 | | #define _GET_NAME(name, suffix) name##suffix |
63 | | #define GET_NAME(name, suffix) _GET_NAME(name, suffix) |
64 | 185k | #define _GET_STRING(name, suffix) #name #suffix |
65 | 185k | #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 | 49.6k | { |
75 | 49.6k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); |
76 | 49.6k | int i, retval = 0; |
77 | 49.6k | boolean alloc = TRUE; |
78 | 49.6k | _JSAMPROW *row_pointer = NULL; |
79 | | |
80 | 49.6k | GET_CINSTANCE(handle) |
81 | 49.6k | if ((this->init & COMPRESS) == 0) |
82 | 49.6k | THROW("Instance has not been initialized for compression"); |
83 | | |
84 | 49.6k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || |
85 | 49.6k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || |
86 | 49.6k | jpegSize == NULL) |
87 | 49.6k | THROW("Invalid argument"); |
88 | | |
89 | 49.6k | if (!this->lossless && this->quality == -1) |
90 | 49.6k | THROW("TJPARAM_QUALITY must be specified"); |
91 | 49.6k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) |
92 | 49.6k | THROW("TJPARAM_SUBSAMP must be specified"); |
93 | | |
94 | 49.6k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; |
95 | | |
96 | 49.6k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) |
97 | 49.6k | THROW("Memory allocation failure"); |
98 | | |
99 | 49.6k | if (setjmp(this->jerr.setjmp_buffer)) { |
100 | | /* If we get here, the JPEG code has signaled an error. */ |
101 | 257 | retval = -1; goto bailout; |
102 | 257 | } |
103 | | |
104 | 49.4k | cinfo->image_width = width; |
105 | 49.4k | cinfo->image_height = height; |
106 | 49.4k | cinfo->data_precision = BITS_IN_JSAMPLE; |
107 | | |
108 | 49.4k | setCompDefaults(this, pixelFormat); |
109 | 49.4k | if (this->noRealloc) { |
110 | 42.4k | alloc = FALSE; |
111 | 42.4k | *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); |
112 | 42.4k | } |
113 | 49.4k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); |
114 | | |
115 | 49.4k | jpeg_start_compress(cinfo, TRUE); |
116 | 169M | for (i = 0; i < height; i++) { |
117 | 169M | if (this->bottomUp) |
118 | 24.3M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; |
119 | 144M | else |
120 | 144M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; |
121 | 169M | } |
122 | 98.9k | while (cinfo->next_scanline < cinfo->image_height) |
123 | 49.4k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], |
124 | 49.4k | cinfo->image_height - cinfo->next_scanline); |
125 | 49.4k | jpeg_finish_compress(cinfo); |
126 | | |
127 | 49.6k | bailout: |
128 | 49.6k | if (cinfo->global_state > CSTATE_START && alloc) |
129 | 32 | (*cinfo->dest->term_destination) (cinfo); |
130 | 49.6k | if (cinfo->global_state > CSTATE_START || retval == -1) |
131 | 257 | jpeg_abort_compress(cinfo); |
132 | 49.6k | free(row_pointer); |
133 | 49.6k | if (this->jerr.warning) retval = -1; |
134 | 49.6k | return retval; |
135 | 49.4k | } Line | Count | Source | 74 | 18.3k | { | 75 | 18.3k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 18.3k | int i, retval = 0; | 77 | 18.3k | boolean alloc = TRUE; | 78 | 18.3k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 18.3k | GET_CINSTANCE(handle) | 81 | 18.3k | if ((this->init & COMPRESS) == 0) | 82 | 18.3k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 18.3k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 18.3k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 18.3k | jpegSize == NULL) | 87 | 18.3k | THROW("Invalid argument"); | 88 | | | 89 | 18.3k | if (!this->lossless && this->quality == -1) | 90 | 18.3k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 18.3k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 18.3k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 18.3k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 18.3k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 18.3k | THROW("Memory allocation failure"); | 98 | | | 99 | 18.3k | if (setjmp(this->jerr.setjmp_buffer)) { | 100 | | /* If we get here, the JPEG code has signaled an error. */ | 101 | 117 | retval = -1; goto bailout; | 102 | 117 | } | 103 | | | 104 | 18.1k | cinfo->image_width = width; | 105 | 18.1k | cinfo->image_height = height; | 106 | 18.1k | cinfo->data_precision = BITS_IN_JSAMPLE; | 107 | | | 108 | 18.1k | setCompDefaults(this, pixelFormat); | 109 | 18.1k | if (this->noRealloc) { | 110 | 15.6k | alloc = FALSE; | 111 | 15.6k | *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); | 112 | 15.6k | } | 113 | 18.1k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 114 | | | 115 | 18.1k | jpeg_start_compress(cinfo, TRUE); | 116 | 60.1M | for (i = 0; i < height; i++) { | 117 | 60.1M | if (this->bottomUp) | 118 | 8.73M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 119 | 51.3M | else | 120 | 51.3M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 121 | 60.1M | } | 122 | 36.3k | while (cinfo->next_scanline < cinfo->image_height) | 123 | 18.1k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 124 | 18.1k | cinfo->image_height - cinfo->next_scanline); | 125 | 18.1k | jpeg_finish_compress(cinfo); | 126 | | | 127 | 18.3k | bailout: | 128 | 18.3k | if (cinfo->global_state > CSTATE_START && alloc) | 129 | 0 | (*cinfo->dest->term_destination) (cinfo); | 130 | 18.3k | if (cinfo->global_state > CSTATE_START || retval == -1) | 131 | 117 | jpeg_abort_compress(cinfo); | 132 | 18.3k | free(row_pointer); | 133 | 18.3k | if (this->jerr.warning) retval = -1; | 134 | 18.3k | return retval; | 135 | 18.1k | } |
Line | Count | Source | 74 | 26.7k | { | 75 | 26.7k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 26.7k | int i, retval = 0; | 77 | 26.7k | boolean alloc = TRUE; | 78 | 26.7k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 26.7k | GET_CINSTANCE(handle) | 81 | 26.7k | if ((this->init & COMPRESS) == 0) | 82 | 26.7k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 26.7k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 26.7k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 26.7k | jpegSize == NULL) | 87 | 26.7k | THROW("Invalid argument"); | 88 | | | 89 | 26.7k | if (!this->lossless && this->quality == -1) | 90 | 26.7k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 26.7k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 26.7k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 26.7k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 26.7k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 26.7k | THROW("Memory allocation failure"); | 98 | | | 99 | 26.7k | if (setjmp(this->jerr.setjmp_buffer)) { | 100 | | /* If we get here, the JPEG code has signaled an error. */ | 101 | 81 | retval = -1; goto bailout; | 102 | 81 | } | 103 | | | 104 | 26.7k | cinfo->image_width = width; | 105 | 26.7k | cinfo->image_height = height; | 106 | 26.7k | cinfo->data_precision = BITS_IN_JSAMPLE; | 107 | | | 108 | 26.7k | setCompDefaults(this, pixelFormat); | 109 | 26.7k | if (this->noRealloc) { | 110 | 22.8k | alloc = FALSE; | 111 | 22.8k | *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); | 112 | 22.8k | } | 113 | 26.7k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 114 | | | 115 | 26.7k | jpeg_start_compress(cinfo, TRUE); | 116 | 95.5M | for (i = 0; i < height; i++) { | 117 | 95.5M | if (this->bottomUp) | 118 | 13.6M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 119 | 81.8M | else | 120 | 81.8M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 121 | 95.5M | } | 122 | 53.4k | while (cinfo->next_scanline < cinfo->image_height) | 123 | 26.7k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 124 | 26.7k | cinfo->image_height - cinfo->next_scanline); | 125 | 26.7k | jpeg_finish_compress(cinfo); | 126 | | | 127 | 26.7k | bailout: | 128 | 26.7k | if (cinfo->global_state > CSTATE_START && alloc) | 129 | 0 | (*cinfo->dest->term_destination) (cinfo); | 130 | 26.7k | if (cinfo->global_state > CSTATE_START || retval == -1) | 131 | 81 | jpeg_abort_compress(cinfo); | 132 | 26.7k | free(row_pointer); | 133 | 26.7k | if (this->jerr.warning) retval = -1; | 134 | 26.7k | return retval; | 135 | 26.7k | } |
Line | Count | Source | 74 | 4.58k | { | 75 | 4.58k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 4.58k | int i, retval = 0; | 77 | 4.58k | boolean alloc = TRUE; | 78 | 4.58k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 4.58k | GET_CINSTANCE(handle) | 81 | 4.58k | if ((this->init & COMPRESS) == 0) | 82 | 4.58k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 4.58k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 4.58k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 4.58k | jpegSize == NULL) | 87 | 4.58k | THROW("Invalid argument"); | 88 | | | 89 | 4.58k | if (!this->lossless && this->quality == -1) | 90 | 4.58k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 4.58k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 4.58k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 4.58k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 4.58k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 4.58k | THROW("Memory allocation failure"); | 98 | | | 99 | 4.58k | if (setjmp(this->jerr.setjmp_buffer)) { | 100 | | /* If we get here, the JPEG code has signaled an error. */ | 101 | 59 | retval = -1; goto bailout; | 102 | 59 | } | 103 | | | 104 | 4.52k | cinfo->image_width = width; | 105 | 4.52k | cinfo->image_height = height; | 106 | 4.52k | cinfo->data_precision = BITS_IN_JSAMPLE; | 107 | | | 108 | 4.52k | setCompDefaults(this, pixelFormat); | 109 | 4.52k | if (this->noRealloc) { | 110 | 3.91k | alloc = FALSE; | 111 | 3.91k | *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); | 112 | 3.91k | } | 113 | 4.52k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 114 | | | 115 | 4.52k | jpeg_start_compress(cinfo, TRUE); | 116 | 13.6M | for (i = 0; i < height; i++) { | 117 | 13.6M | if (this->bottomUp) | 118 | 1.95M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 119 | 11.7M | else | 120 | 11.7M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 121 | 13.6M | } | 122 | 9.08k | while (cinfo->next_scanline < cinfo->image_height) | 123 | 4.56k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 124 | 4.56k | cinfo->image_height - cinfo->next_scanline); | 125 | 4.52k | jpeg_finish_compress(cinfo); | 126 | | | 127 | 4.58k | bailout: | 128 | 4.58k | if (cinfo->global_state > CSTATE_START && alloc) | 129 | 32 | (*cinfo->dest->term_destination) (cinfo); | 130 | 4.58k | if (cinfo->global_state > CSTATE_START || retval == -1) | 131 | 59 | jpeg_abort_compress(cinfo); | 132 | 4.58k | free(row_pointer); | 133 | 4.58k | if (this->jerr.warning) retval = -1; | 134 | 4.58k | return retval; | 135 | 4.52k | } |
|
136 | | |
137 | | |
138 | | /******************************* Decompressor ********************************/ |
139 | | |
140 | | /* TurboJPEG 3+ */ |
141 | | DLLEXPORT int GET_NAME(tj3Decompress, BITS_IN_JSAMPLE) |
142 | | (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, |
143 | | _JSAMPLE *dstBuf, int pitch, int pixelFormat) |
144 | 16.2k | { |
145 | 16.2k | static const char FUNCTION_NAME[] = |
146 | 16.2k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); |
147 | 16.2k | _JSAMPROW *row_pointer = NULL; |
148 | 16.2k | int croppedHeight, i, retval = 0; |
149 | | #if BITS_IN_JSAMPLE != 16 |
150 | | int scaledWidth; |
151 | | #endif |
152 | 16.2k | struct my_progress_mgr progress; |
153 | | |
154 | 16.2k | GET_DINSTANCE(handle); |
155 | 16.2k | if ((this->init & DECOMPRESS) == 0) |
156 | 16.2k | THROW("Instance has not been initialized for decompression"); |
157 | | |
158 | 16.2k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || |
159 | 16.2k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) |
160 | 16.2k | THROW("Invalid argument"); |
161 | | |
162 | 16.2k | if (this->scanLimit) { |
163 | 16.2k | memset(&progress, 0, sizeof(struct my_progress_mgr)); |
164 | 16.2k | progress.pub.progress_monitor = my_progress_monitor; |
165 | 16.2k | progress.this = this; |
166 | 16.2k | dinfo->progress = &progress.pub; |
167 | 16.2k | } else |
168 | 0 | dinfo->progress = NULL; |
169 | | |
170 | 16.2k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
171 | | |
172 | 16.2k | if (setjmp(this->jerr.setjmp_buffer)) { |
173 | | /* If we get here, the JPEG code has signaled an error. */ |
174 | 4.25k | retval = -1; goto bailout; |
175 | 4.25k | } |
176 | | |
177 | 16.2k | if (dinfo->global_state <= DSTATE_INHEADER) { |
178 | 16.2k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); |
179 | 16.2k | jpeg_read_header(dinfo, TRUE); |
180 | 16.2k | } |
181 | 12.0k | setDecompParameters(this); |
182 | 12.0k | if (this->maxPixels && |
183 | 12.0k | (unsigned long long)this->jpegWidth * this->jpegHeight > |
184 | 0 | (unsigned long long)this->maxPixels) |
185 | 12.0k | THROW("Image is too large"); |
186 | 12.0k | this->dinfo.out_color_space = pf2cs[pixelFormat]; |
187 | | #if BITS_IN_JSAMPLE != 16 |
188 | 11.0k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); |
189 | | #endif |
190 | 12.0k | dinfo->do_fancy_upsampling = !this->fastUpsample; |
191 | 12.0k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; |
192 | | |
193 | 12.0k | dinfo->scale_num = this->scalingFactor.num; |
194 | 12.0k | dinfo->scale_denom = this->scalingFactor.denom; |
195 | | |
196 | 12.0k | jpeg_start_decompress(dinfo); |
197 | | |
198 | | #if BITS_IN_JSAMPLE != 16 |
199 | 11.0k | if (this->croppingRegion.x != 0 || |
200 | 11.0k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { |
201 | 0 | JDIMENSION crop_x = this->croppingRegion.x; |
202 | 0 | JDIMENSION crop_w = this->croppingRegion.w; |
203 | |
|
204 | 0 | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); |
205 | 0 | if ((int)crop_x != this->croppingRegion.x) |
206 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
207 | 0 | "actual (%d) cropping region left boundary", |
208 | 0 | this->croppingRegion.x, (int)crop_x); |
209 | 0 | if ((int)crop_w != this->croppingRegion.w) |
210 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
211 | 0 | "actual (%d) cropping region width", |
212 | 0 | this->croppingRegion.w, (int)crop_w); |
213 | 0 | } |
214 | 11.0k | #endif |
215 | | |
216 | 12.0k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; |
217 | | |
218 | 11.0k | croppedHeight = dinfo->output_height; |
219 | | #if BITS_IN_JSAMPLE != 16 |
220 | 11.0k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) |
221 | 0 | croppedHeight = this->croppingRegion.h; |
222 | | #endif |
223 | 12.0k | if ((row_pointer = |
224 | 12.0k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) |
225 | 12.0k | THROW("Memory allocation failure"); |
226 | 12.0k | if (setjmp(this->jerr.setjmp_buffer)) { |
227 | | /* If we get here, the JPEG code has signaled an error. */ |
228 | 2.03k | retval = -1; goto bailout; |
229 | 2.03k | } |
230 | 60.9M | for (i = 0; i < (int)croppedHeight; i++) { |
231 | 60.9M | if (this->bottomUp) |
232 | 53.4M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; |
233 | 7.50M | else |
234 | 7.50M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; |
235 | 60.9M | } |
236 | | |
237 | | #if BITS_IN_JSAMPLE != 16 |
238 | 11.0k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { |
239 | 0 | if (this->croppingRegion.y != 0) { |
240 | 0 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); |
241 | | |
242 | 0 | if ((int)lines != this->croppingRegion.y) |
243 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
244 | | "actual (%d) cropping region upper boundary", |
245 | 0 | this->croppingRegion.y, (int)lines); |
246 | 0 | } |
247 | 0 | while ((int)dinfo->output_scanline < |
248 | 0 | this->croppingRegion.y + this->croppingRegion.h) |
249 | 0 | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - |
250 | 0 | this->croppingRegion.y], |
251 | 0 | this->croppingRegion.y + this->croppingRegion.h - |
252 | 0 | dinfo->output_scanline); |
253 | 0 | if (this->croppingRegion.y + this->croppingRegion.h != |
254 | 0 | (int)dinfo->output_height) { |
255 | 0 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - |
256 | | this->croppingRegion.y - |
257 | | this->croppingRegion.h); |
258 | |
|
259 | 0 | if (lines != dinfo->output_height - this->croppingRegion.y - |
260 | 0 | this->croppingRegion.h) |
261 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
262 | 0 | "actual (%d) cropping region lower boundary", |
263 | 0 | this->croppingRegion.y + this->croppingRegion.h, |
264 | 0 | (int)(dinfo->output_height - lines)); |
265 | 0 | } |
266 | 0 | } else |
267 | 9.71k | #endif |
268 | 9.71k | { |
269 | 23.9M | while (dinfo->output_scanline < dinfo->output_height) |
270 | 23.9M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], |
271 | 23.9M | dinfo->output_height - dinfo->output_scanline); |
272 | 9.71k | } |
273 | 9.71k | jpeg_finish_decompress(dinfo); |
274 | | |
275 | 16.2k | bailout: |
276 | 16.2k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); |
277 | 16.2k | free(row_pointer); |
278 | 16.2k | if (this->jerr.warning) retval = -1; |
279 | 16.2k | return retval; |
280 | 9.71k | } Line | Count | Source | 144 | 7.79k | { | 145 | 7.79k | static const char FUNCTION_NAME[] = | 146 | 7.79k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 147 | 7.79k | _JSAMPROW *row_pointer = NULL; | 148 | 7.79k | int croppedHeight, i, retval = 0; | 149 | 7.79k | #if BITS_IN_JSAMPLE != 16 | 150 | 7.79k | int scaledWidth; | 151 | 7.79k | #endif | 152 | 7.79k | struct my_progress_mgr progress; | 153 | | | 154 | 7.79k | GET_DINSTANCE(handle); | 155 | 7.79k | if ((this->init & DECOMPRESS) == 0) | 156 | 7.79k | THROW("Instance has not been initialized for decompression"); | 157 | | | 158 | 7.79k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 159 | 7.79k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 160 | 7.79k | THROW("Invalid argument"); | 161 | | | 162 | 7.79k | if (this->scanLimit) { | 163 | 7.79k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 164 | 7.79k | progress.pub.progress_monitor = my_progress_monitor; | 165 | 7.79k | progress.this = this; | 166 | 7.79k | dinfo->progress = &progress.pub; | 167 | 7.79k | } else | 168 | 0 | dinfo->progress = NULL; | 169 | | | 170 | 7.79k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 171 | | | 172 | 7.79k | if (setjmp(this->jerr.setjmp_buffer)) { | 173 | | /* If we get here, the JPEG code has signaled an error. */ | 174 | 2.21k | retval = -1; goto bailout; | 175 | 2.21k | } | 176 | | | 177 | 7.79k | if (dinfo->global_state <= DSTATE_INHEADER) { | 178 | 7.79k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 179 | 7.79k | jpeg_read_header(dinfo, TRUE); | 180 | 7.79k | } | 181 | 5.57k | setDecompParameters(this); | 182 | 5.57k | if (this->maxPixels && | 183 | 5.57k | (unsigned long long)this->jpegWidth * this->jpegHeight > | 184 | 0 | (unsigned long long)this->maxPixels) | 185 | 5.57k | THROW("Image is too large"); | 186 | 5.57k | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 187 | 5.57k | #if BITS_IN_JSAMPLE != 16 | 188 | 5.57k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 189 | 5.57k | #endif | 190 | 5.57k | dinfo->do_fancy_upsampling = !this->fastUpsample; | 191 | 5.57k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 192 | | | 193 | 5.57k | dinfo->scale_num = this->scalingFactor.num; | 194 | 5.57k | dinfo->scale_denom = this->scalingFactor.denom; | 195 | | | 196 | 5.57k | jpeg_start_decompress(dinfo); | 197 | | | 198 | 5.57k | #if BITS_IN_JSAMPLE != 16 | 199 | 5.57k | if (this->croppingRegion.x != 0 || | 200 | 5.57k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 201 | 0 | JDIMENSION crop_x = this->croppingRegion.x; | 202 | 0 | JDIMENSION crop_w = this->croppingRegion.w; | 203 | |
| 204 | 0 | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 205 | 0 | if ((int)crop_x != this->croppingRegion.x) | 206 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 207 | 0 | "actual (%d) cropping region left boundary", | 208 | 0 | this->croppingRegion.x, (int)crop_x); | 209 | 0 | if ((int)crop_w != this->croppingRegion.w) | 210 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 211 | 0 | "actual (%d) cropping region width", | 212 | 0 | this->croppingRegion.w, (int)crop_w); | 213 | 0 | } | 214 | 5.57k | #endif | 215 | | | 216 | 5.57k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 217 | | | 218 | 5.57k | croppedHeight = dinfo->output_height; | 219 | 5.57k | #if BITS_IN_JSAMPLE != 16 | 220 | 5.57k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 221 | 0 | croppedHeight = this->croppingRegion.h; | 222 | 5.57k | #endif | 223 | 5.57k | if ((row_pointer = | 224 | 5.57k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 225 | 5.57k | THROW("Memory allocation failure"); | 226 | 5.57k | if (setjmp(this->jerr.setjmp_buffer)) { | 227 | | /* If we get here, the JPEG code has signaled an error. */ | 228 | 866 | retval = -1; goto bailout; | 229 | 866 | } | 230 | 29.7M | for (i = 0; i < (int)croppedHeight; i++) { | 231 | 29.7M | if (this->bottomUp) | 232 | 27.2M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 233 | 2.46M | else | 234 | 2.46M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 235 | 29.7M | } | 236 | | | 237 | 4.70k | #if BITS_IN_JSAMPLE != 16 | 238 | 5.57k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 239 | 0 | if (this->croppingRegion.y != 0) { | 240 | 0 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 241 | |
| 242 | 0 | if ((int)lines != this->croppingRegion.y) | 243 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 244 | 0 | "actual (%d) cropping region upper boundary", | 245 | 0 | this->croppingRegion.y, (int)lines); | 246 | 0 | } | 247 | 0 | while ((int)dinfo->output_scanline < | 248 | 0 | this->croppingRegion.y + this->croppingRegion.h) | 249 | 0 | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 250 | 0 | this->croppingRegion.y], | 251 | 0 | this->croppingRegion.y + this->croppingRegion.h - | 252 | 0 | dinfo->output_scanline); | 253 | 0 | if (this->croppingRegion.y + this->croppingRegion.h != | 254 | 0 | (int)dinfo->output_height) { | 255 | 0 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 256 | 0 | this->croppingRegion.y - | 257 | 0 | this->croppingRegion.h); | 258 | |
| 259 | 0 | if (lines != dinfo->output_height - this->croppingRegion.y - | 260 | 0 | this->croppingRegion.h) | 261 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 262 | 0 | "actual (%d) cropping region lower boundary", | 263 | 0 | this->croppingRegion.y + this->croppingRegion.h, | 264 | 0 | (int)(dinfo->output_height - lines)); | 265 | 0 | } | 266 | 0 | } else | 267 | 4.70k | #endif | 268 | 4.70k | { | 269 | 13.5M | while (dinfo->output_scanline < dinfo->output_height) | 270 | 13.5M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 271 | 13.5M | dinfo->output_height - dinfo->output_scanline); | 272 | 4.70k | } | 273 | 4.70k | jpeg_finish_decompress(dinfo); | 274 | | | 275 | 7.79k | bailout: | 276 | 7.79k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 277 | 7.79k | free(row_pointer); | 278 | 7.79k | if (this->jerr.warning) retval = -1; | 279 | 7.79k | return retval; | 280 | 4.70k | } |
Line | Count | Source | 144 | 7.14k | { | 145 | 7.14k | static const char FUNCTION_NAME[] = | 146 | 7.14k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 147 | 7.14k | _JSAMPROW *row_pointer = NULL; | 148 | 7.14k | int croppedHeight, i, retval = 0; | 149 | 7.14k | #if BITS_IN_JSAMPLE != 16 | 150 | 7.14k | int scaledWidth; | 151 | 7.14k | #endif | 152 | 7.14k | struct my_progress_mgr progress; | 153 | | | 154 | 7.14k | GET_DINSTANCE(handle); | 155 | 7.14k | if ((this->init & DECOMPRESS) == 0) | 156 | 7.14k | THROW("Instance has not been initialized for decompression"); | 157 | | | 158 | 7.14k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 159 | 7.14k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 160 | 7.14k | THROW("Invalid argument"); | 161 | | | 162 | 7.14k | if (this->scanLimit) { | 163 | 7.14k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 164 | 7.14k | progress.pub.progress_monitor = my_progress_monitor; | 165 | 7.14k | progress.this = this; | 166 | 7.14k | dinfo->progress = &progress.pub; | 167 | 7.14k | } else | 168 | 0 | dinfo->progress = NULL; | 169 | | | 170 | 7.14k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 171 | | | 172 | 7.14k | if (setjmp(this->jerr.setjmp_buffer)) { | 173 | | /* If we get here, the JPEG code has signaled an error. */ | 174 | 1.63k | retval = -1; goto bailout; | 175 | 1.63k | } | 176 | | | 177 | 7.14k | if (dinfo->global_state <= DSTATE_INHEADER) { | 178 | 7.14k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 179 | 7.14k | jpeg_read_header(dinfo, TRUE); | 180 | 7.14k | } | 181 | 5.51k | setDecompParameters(this); | 182 | 5.51k | if (this->maxPixels && | 183 | 5.51k | (unsigned long long)this->jpegWidth * this->jpegHeight > | 184 | 0 | (unsigned long long)this->maxPixels) | 185 | 5.51k | THROW("Image is too large"); | 186 | 5.51k | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 187 | 5.51k | #if BITS_IN_JSAMPLE != 16 | 188 | 5.51k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 189 | 5.51k | #endif | 190 | 5.51k | dinfo->do_fancy_upsampling = !this->fastUpsample; | 191 | 5.51k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 192 | | | 193 | 5.51k | dinfo->scale_num = this->scalingFactor.num; | 194 | 5.51k | dinfo->scale_denom = this->scalingFactor.denom; | 195 | | | 196 | 5.51k | jpeg_start_decompress(dinfo); | 197 | | | 198 | 5.51k | #if BITS_IN_JSAMPLE != 16 | 199 | 5.51k | if (this->croppingRegion.x != 0 || | 200 | 5.51k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 201 | 0 | JDIMENSION crop_x = this->croppingRegion.x; | 202 | 0 | JDIMENSION crop_w = this->croppingRegion.w; | 203 | |
| 204 | 0 | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 205 | 0 | if ((int)crop_x != this->croppingRegion.x) | 206 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 207 | 0 | "actual (%d) cropping region left boundary", | 208 | 0 | this->croppingRegion.x, (int)crop_x); | 209 | 0 | if ((int)crop_w != this->croppingRegion.w) | 210 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 211 | 0 | "actual (%d) cropping region width", | 212 | 0 | this->croppingRegion.w, (int)crop_w); | 213 | 0 | } | 214 | 5.51k | #endif | 215 | | | 216 | 5.51k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 217 | | | 218 | 5.51k | croppedHeight = dinfo->output_height; | 219 | 5.51k | #if BITS_IN_JSAMPLE != 16 | 220 | 5.51k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 221 | 0 | croppedHeight = this->croppingRegion.h; | 222 | 5.51k | #endif | 223 | 5.51k | if ((row_pointer = | 224 | 5.51k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 225 | 5.51k | THROW("Memory allocation failure"); | 226 | 5.51k | if (setjmp(this->jerr.setjmp_buffer)) { | 227 | | /* If we get here, the JPEG code has signaled an error. */ | 228 | 502 | retval = -1; goto bailout; | 229 | 502 | } | 230 | 24.3M | for (i = 0; i < (int)croppedHeight; i++) { | 231 | 24.3M | if (this->bottomUp) | 232 | 19.2M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 233 | 5.04M | else | 234 | 5.04M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 235 | 24.3M | } | 236 | | | 237 | 5.00k | #if BITS_IN_JSAMPLE != 16 | 238 | 5.51k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 239 | 0 | if (this->croppingRegion.y != 0) { | 240 | 0 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 241 | |
| 242 | 0 | if ((int)lines != this->croppingRegion.y) | 243 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 244 | 0 | "actual (%d) cropping region upper boundary", | 245 | 0 | this->croppingRegion.y, (int)lines); | 246 | 0 | } | 247 | 0 | while ((int)dinfo->output_scanline < | 248 | 0 | this->croppingRegion.y + this->croppingRegion.h) | 249 | 0 | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 250 | 0 | this->croppingRegion.y], | 251 | 0 | this->croppingRegion.y + this->croppingRegion.h - | 252 | 0 | dinfo->output_scanline); | 253 | 0 | if (this->croppingRegion.y + this->croppingRegion.h != | 254 | 0 | (int)dinfo->output_height) { | 255 | 0 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 256 | 0 | this->croppingRegion.y - | 257 | 0 | this->croppingRegion.h); | 258 | |
| 259 | 0 | if (lines != dinfo->output_height - this->croppingRegion.y - | 260 | 0 | this->croppingRegion.h) | 261 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 262 | 0 | "actual (%d) cropping region lower boundary", | 263 | 0 | this->croppingRegion.y + this->croppingRegion.h, | 264 | 0 | (int)(dinfo->output_height - lines)); | 265 | 0 | } | 266 | 0 | } else | 267 | 5.00k | #endif | 268 | 5.00k | { | 269 | 10.0M | while (dinfo->output_scanline < dinfo->output_height) | 270 | 9.99M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 271 | 9.99M | dinfo->output_height - dinfo->output_scanline); | 272 | 5.00k | } | 273 | 5.00k | jpeg_finish_decompress(dinfo); | 274 | | | 275 | 7.14k | bailout: | 276 | 7.14k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 277 | 7.14k | free(row_pointer); | 278 | 7.14k | if (this->jerr.warning) retval = -1; | 279 | 7.14k | return retval; | 280 | 5.00k | } |
Line | Count | Source | 144 | 1.32k | { | 145 | 1.32k | static const char FUNCTION_NAME[] = | 146 | 1.32k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 147 | 1.32k | _JSAMPROW *row_pointer = NULL; | 148 | 1.32k | int croppedHeight, i, retval = 0; | 149 | | #if BITS_IN_JSAMPLE != 16 | 150 | | int scaledWidth; | 151 | | #endif | 152 | 1.32k | struct my_progress_mgr progress; | 153 | | | 154 | 1.32k | GET_DINSTANCE(handle); | 155 | 1.32k | if ((this->init & DECOMPRESS) == 0) | 156 | 1.32k | THROW("Instance has not been initialized for decompression"); | 157 | | | 158 | 1.32k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 159 | 1.32k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 160 | 1.32k | THROW("Invalid argument"); | 161 | | | 162 | 1.32k | if (this->scanLimit) { | 163 | 1.32k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 164 | 1.32k | progress.pub.progress_monitor = my_progress_monitor; | 165 | 1.32k | progress.this = this; | 166 | 1.32k | dinfo->progress = &progress.pub; | 167 | 1.32k | } else | 168 | 0 | dinfo->progress = NULL; | 169 | | | 170 | 1.32k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 171 | | | 172 | 1.32k | if (setjmp(this->jerr.setjmp_buffer)) { | 173 | | /* If we get here, the JPEG code has signaled an error. */ | 174 | 400 | retval = -1; goto bailout; | 175 | 400 | } | 176 | | | 177 | 1.32k | if (dinfo->global_state <= DSTATE_INHEADER) { | 178 | 1.32k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 179 | 1.32k | jpeg_read_header(dinfo, TRUE); | 180 | 1.32k | } | 181 | 925 | setDecompParameters(this); | 182 | 925 | if (this->maxPixels && | 183 | 925 | (unsigned long long)this->jpegWidth * this->jpegHeight > | 184 | 0 | (unsigned long long)this->maxPixels) | 185 | 925 | THROW("Image is too large"); | 186 | 925 | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 187 | | #if BITS_IN_JSAMPLE != 16 | 188 | | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 189 | | #endif | 190 | 925 | dinfo->do_fancy_upsampling = !this->fastUpsample; | 191 | 925 | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 192 | | | 193 | 925 | dinfo->scale_num = this->scalingFactor.num; | 194 | 925 | dinfo->scale_denom = this->scalingFactor.denom; | 195 | | | 196 | 925 | jpeg_start_decompress(dinfo); | 197 | | | 198 | | #if BITS_IN_JSAMPLE != 16 | 199 | | if (this->croppingRegion.x != 0 || | 200 | | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 201 | | JDIMENSION crop_x = this->croppingRegion.x; | 202 | | JDIMENSION crop_w = this->croppingRegion.w; | 203 | | | 204 | | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 205 | | if ((int)crop_x != this->croppingRegion.x) | 206 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 207 | | "actual (%d) cropping region left boundary", | 208 | | this->croppingRegion.x, (int)crop_x); | 209 | | if ((int)crop_w != this->croppingRegion.w) | 210 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 211 | | "actual (%d) cropping region width", | 212 | | this->croppingRegion.w, (int)crop_w); | 213 | | } | 214 | | #endif | 215 | | | 216 | 925 | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 217 | | | 218 | 925 | croppedHeight = dinfo->output_height; | 219 | | #if BITS_IN_JSAMPLE != 16 | 220 | | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 221 | | croppedHeight = this->croppingRegion.h; | 222 | | #endif | 223 | 925 | if ((row_pointer = | 224 | 925 | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 225 | 925 | THROW("Memory allocation failure"); | 226 | 925 | if (setjmp(this->jerr.setjmp_buffer)) { | 227 | | /* If we get here, the JPEG code has signaled an error. */ | 228 | 662 | retval = -1; goto bailout; | 229 | 662 | } | 230 | 6.90M | for (i = 0; i < (int)croppedHeight; i++) { | 231 | 6.90M | if (this->bottomUp) | 232 | 6.90M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 233 | 826 | else | 234 | 826 | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 235 | 6.90M | } | 236 | | | 237 | | #if BITS_IN_JSAMPLE != 16 | 238 | | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 239 | | if (this->croppingRegion.y != 0) { | 240 | | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 241 | | | 242 | | if ((int)lines != this->croppingRegion.y) | 243 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 244 | | "actual (%d) cropping region upper boundary", | 245 | | this->croppingRegion.y, (int)lines); | 246 | | } | 247 | | while ((int)dinfo->output_scanline < | 248 | | this->croppingRegion.y + this->croppingRegion.h) | 249 | | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 250 | | this->croppingRegion.y], | 251 | | this->croppingRegion.y + this->croppingRegion.h - | 252 | | dinfo->output_scanline); | 253 | | if (this->croppingRegion.y + this->croppingRegion.h != | 254 | | (int)dinfo->output_height) { | 255 | | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 256 | | this->croppingRegion.y - | 257 | | this->croppingRegion.h); | 258 | | | 259 | | if (lines != dinfo->output_height - this->croppingRegion.y - | 260 | | this->croppingRegion.h) | 261 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 262 | | "actual (%d) cropping region lower boundary", | 263 | | this->croppingRegion.y + this->croppingRegion.h, | 264 | | (int)(dinfo->output_height - lines)); | 265 | | } | 266 | | } else | 267 | | #endif | 268 | 263 | { | 269 | 436k | while (dinfo->output_scanline < dinfo->output_height) | 270 | 435k | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 271 | 435k | dinfo->output_height - dinfo->output_scanline); | 272 | 263 | } | 273 | 263 | jpeg_finish_decompress(dinfo); | 274 | | | 275 | 1.32k | bailout: | 276 | 1.32k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 277 | 1.32k | free(row_pointer); | 278 | 1.32k | if (this->jerr.warning) retval = -1; | 279 | 1.32k | return retval; | 280 | 263 | } |
|
281 | | |
282 | | |
283 | | /*************************** Packed-Pixel Image I/O **************************/ |
284 | | |
285 | | /* TurboJPEG 3+ */ |
286 | | DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE) |
287 | | (tjhandle handle, const char *filename, int *width, int align, int *height, |
288 | | int *pixelFormat) |
289 | 119k | { |
290 | 119k | static const char FUNCTION_NAME[] = |
291 | 119k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); |
292 | | |
293 | 119k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) |
294 | | |
295 | 119k | int retval = 0, tempc; |
296 | 119k | size_t pitch; |
297 | 119k | tjhandle handle2 = NULL; |
298 | 119k | tjinstance *this2; |
299 | 119k | j_compress_ptr cinfo = NULL; |
300 | 119k | cjpeg_source_ptr src; |
301 | 119k | _JSAMPLE *dstBuf = NULL; |
302 | 119k | FILE *file = NULL; |
303 | 119k | boolean invert; |
304 | | |
305 | 119k | GET_TJINSTANCE(handle, NULL) |
306 | | |
307 | 119k | if (!filename || !width || align < 1 || !height || !pixelFormat || |
308 | 119k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) |
309 | 119k | THROW("Invalid argument"); |
310 | 119k | if ((align & (align - 1)) != 0) |
311 | 119k | THROW("Alignment must be a power of 2"); |
312 | | |
313 | | /* The instance handle passed to this function is used only for parameter |
314 | | retrieval. Create a new temporary instance to avoid interfering with the |
315 | | libjpeg state of the primary instance. */ |
316 | 119k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; |
317 | 119k | this2 = (tjinstance *)handle2; |
318 | 119k | cinfo = &this2->cinfo; |
319 | | |
320 | | #ifdef _MSC_VER |
321 | | if (fopen_s(&file, filename, "rb") || file == NULL) |
322 | | #else |
323 | 119k | if ((file = fopen(filename, "rb")) == NULL) |
324 | 0 | #endif |
325 | 119k | THROW_UNIX("Cannot open input file"); |
326 | | |
327 | 119k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) |
328 | 0 | THROW_UNIX("Could not read input file") |
329 | 119k | else if (tempc == EOF) |
330 | 119k | THROW("Input file contains no data"); |
331 | | |
332 | 119k | if (setjmp(this2->jerr.setjmp_buffer)) { |
333 | | /* If we get here, the JPEG code has signaled an error. */ |
334 | 25.2k | retval = -1; goto bailout; |
335 | 25.2k | } |
336 | | |
337 | 94.1k | cinfo->data_precision = BITS_IN_JSAMPLE; |
338 | 94.1k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; |
339 | 94.1k | else cinfo->in_color_space = pf2cs[*pixelFormat]; |
340 | 94.1k | if (tempc == 'B') { |
341 | 18.7k | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) |
342 | 18.7k | THROW("Could not initialize bitmap loader"); |
343 | 18.7k | invert = !this->bottomUp; |
344 | 99.5k | } else if (tempc == 'P') { |
345 | 99.5k | if ((src = _jinit_read_ppm(cinfo)) == NULL) |
346 | 99.5k | THROW("Could not initialize PPM loader"); |
347 | 99.5k | invert = this->bottomUp; |
348 | 99.5k | } else |
349 | 18.4E | THROW("Unsupported file type"); |
350 | | |
351 | 118k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
352 | | |
353 | 118k | src->input_file = file; |
354 | | /* Refuse to load images larger than the specified size. */ |
355 | 118k | src->max_pixels = this->maxPixels; |
356 | 118k | (*src->start_input) (cinfo, src); |
357 | 118k | if (tempc == 'B') { |
358 | 5.95k | if (cinfo->X_density && cinfo->Y_density) { |
359 | 1.43k | this->xDensity = cinfo->X_density; |
360 | 1.43k | this->yDensity = cinfo->Y_density; |
361 | 1.43k | this->densityUnits = cinfo->density_unit; |
362 | 1.43k | } |
363 | 5.95k | } |
364 | 118k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); |
365 | | |
366 | 118k | *width = cinfo->image_width; *height = cinfo->image_height; |
367 | 118k | *pixelFormat = cs2pf[cinfo->in_color_space]; |
368 | | |
369 | 118k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); |
370 | 118k | if ( |
371 | | #if ULLONG_MAX > SIZE_MAX |
372 | | (unsigned long long)pitch * (unsigned long long)(*height) > |
373 | | (unsigned long long)((size_t)-1) || |
374 | | #endif |
375 | 118k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * |
376 | 118k | sizeof(_JSAMPLE))) == NULL) |
377 | 118k | THROW("Memory allocation failure"); |
378 | | |
379 | 118k | if (setjmp(this2->jerr.setjmp_buffer)) { |
380 | | /* If we get here, the JPEG code has signaled an error. */ |
381 | 32.0k | retval = -1; goto bailout; |
382 | 32.0k | } |
383 | | |
384 | 210M | while (cinfo->next_scanline < cinfo->image_height) { |
385 | 210M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); |
386 | | |
387 | 420M | for (i = 0; i < nlines; i++) { |
388 | 210M | _JSAMPLE *dstptr; |
389 | 210M | int row; |
390 | | |
391 | 210M | row = cinfo->next_scanline + i; |
392 | 210M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; |
393 | 174M | else dstptr = &dstBuf[row * pitch]; |
394 | 210M | memcpy(dstptr, src->_buffer[i], |
395 | 210M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); |
396 | 210M | } |
397 | 210M | cinfo->next_scanline += nlines; |
398 | 210M | } |
399 | | |
400 | 86.2k | (*src->finish_input) (cinfo, src); |
401 | | |
402 | 119k | bailout: |
403 | 119k | tj3Destroy(handle2); |
404 | 119k | if (file) fclose(file); |
405 | 119k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } |
406 | 119k | return dstBuf; |
407 | | |
408 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ |
409 | | |
410 | | static const char ERROR_MSG[] = |
411 | | "16-bit data precision requires lossless JPEG,\n" |
412 | | "which was disabled at build time."; |
413 | | _JSAMPLE *retval = NULL; |
414 | | |
415 | | GET_TJINSTANCE(handle, NULL) |
416 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, |
417 | | ERROR_MSG); |
418 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) |
419 | | |
420 | | bailout: |
421 | | return retval; |
422 | | |
423 | | #endif |
424 | 86.2k | } Line | Count | Source | 289 | 67.5k | { | 290 | 67.5k | static const char FUNCTION_NAME[] = | 291 | 67.5k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 292 | | | 293 | 67.5k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) | 294 | | | 295 | 67.5k | int retval = 0, tempc; | 296 | 67.5k | size_t pitch; | 297 | 67.5k | tjhandle handle2 = NULL; | 298 | 67.5k | tjinstance *this2; | 299 | 67.5k | j_compress_ptr cinfo = NULL; | 300 | 67.5k | cjpeg_source_ptr src; | 301 | 67.5k | _JSAMPLE *dstBuf = NULL; | 302 | 67.5k | FILE *file = NULL; | 303 | 67.5k | boolean invert; | 304 | | | 305 | 67.5k | GET_TJINSTANCE(handle, NULL) | 306 | | | 307 | 67.5k | if (!filename || !width || align < 1 || !height || !pixelFormat || | 308 | 67.5k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 309 | 67.5k | THROW("Invalid argument"); | 310 | 67.5k | if ((align & (align - 1)) != 0) | 311 | 67.5k | THROW("Alignment must be a power of 2"); | 312 | | | 313 | | /* The instance handle passed to this function is used only for parameter | 314 | | retrieval. Create a new temporary instance to avoid interfering with the | 315 | | libjpeg state of the primary instance. */ | 316 | 67.5k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 317 | 67.5k | this2 = (tjinstance *)handle2; | 318 | 67.5k | cinfo = &this2->cinfo; | 319 | | | 320 | | #ifdef _MSC_VER | 321 | | if (fopen_s(&file, filename, "rb") || file == NULL) | 322 | | #else | 323 | 67.5k | if ((file = fopen(filename, "rb")) == NULL) | 324 | 0 | #endif | 325 | 67.5k | THROW_UNIX("Cannot open input file"); | 326 | | | 327 | 67.5k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 328 | 0 | THROW_UNIX("Could not read input file") | 329 | 67.5k | else if (tempc == EOF) | 330 | 67.5k | THROW("Input file contains no data"); | 331 | | | 332 | 67.5k | if (setjmp(this2->jerr.setjmp_buffer)) { | 333 | | /* If we get here, the JPEG code has signaled an error. */ | 334 | 18.8k | retval = -1; goto bailout; | 335 | 18.8k | } | 336 | | | 337 | 48.7k | cinfo->data_precision = BITS_IN_JSAMPLE; | 338 | 48.7k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 339 | 48.7k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 340 | 48.7k | if (tempc == 'B') { | 341 | 18.7k | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 342 | 18.7k | THROW("Could not initialize bitmap loader"); | 343 | 18.7k | invert = !this->bottomUp; | 344 | 48.2k | } else if (tempc == 'P') { | 345 | 48.2k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 346 | 48.2k | THROW("Could not initialize PPM loader"); | 347 | 48.2k | invert = this->bottomUp; | 348 | 48.2k | } else | 349 | 18.4E | THROW("Unsupported file type"); | 350 | | | 351 | 67.0k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 352 | | | 353 | 67.0k | src->input_file = file; | 354 | | /* Refuse to load images larger than the specified size. */ | 355 | 67.0k | src->max_pixels = this->maxPixels; | 356 | 67.0k | (*src->start_input) (cinfo, src); | 357 | 67.0k | if (tempc == 'B') { | 358 | 5.95k | if (cinfo->X_density && cinfo->Y_density) { | 359 | 1.43k | this->xDensity = cinfo->X_density; | 360 | 1.43k | this->yDensity = cinfo->Y_density; | 361 | 1.43k | this->densityUnits = cinfo->density_unit; | 362 | 1.43k | } | 363 | 5.95k | } | 364 | 67.0k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 365 | | | 366 | 67.0k | *width = cinfo->image_width; *height = cinfo->image_height; | 367 | 67.0k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 368 | | | 369 | 67.0k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 370 | 67.0k | if ( | 371 | | #if ULLONG_MAX > SIZE_MAX | 372 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 373 | | (unsigned long long)((size_t)-1) || | 374 | | #endif | 375 | 67.0k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 376 | 67.0k | sizeof(_JSAMPLE))) == NULL) | 377 | 67.0k | THROW("Memory allocation failure"); | 378 | | | 379 | 67.0k | if (setjmp(this2->jerr.setjmp_buffer)) { | 380 | | /* If we get here, the JPEG code has signaled an error. */ | 381 | 18.5k | retval = -1; goto bailout; | 382 | 18.5k | } | 383 | | | 384 | 98.0M | while (cinfo->next_scanline < cinfo->image_height) { | 385 | 98.0M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 386 | | | 387 | 195M | for (i = 0; i < nlines; i++) { | 388 | 97.9M | _JSAMPLE *dstptr; | 389 | 97.9M | int row; | 390 | | | 391 | 97.9M | row = cinfo->next_scanline + i; | 392 | 97.9M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 393 | 78.1M | else dstptr = &dstBuf[row * pitch]; | 394 | 97.9M | memcpy(dstptr, src->_buffer[i], | 395 | 97.9M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 396 | 97.9M | } | 397 | 98.0M | cinfo->next_scanline += nlines; | 398 | 98.0M | } | 399 | | | 400 | 48.5k | (*src->finish_input) (cinfo, src); | 401 | | | 402 | 67.5k | bailout: | 403 | 67.5k | tj3Destroy(handle2); | 404 | 67.5k | if (file) fclose(file); | 405 | 67.5k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 406 | 67.5k | return dstBuf; | 407 | | | 408 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ | 409 | | | 410 | | static const char ERROR_MSG[] = | 411 | | "16-bit data precision requires lossless JPEG,\n" | 412 | | "which was disabled at build time."; | 413 | | _JSAMPLE *retval = NULL; | 414 | | | 415 | | GET_TJINSTANCE(handle, NULL) | 416 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, | 417 | | ERROR_MSG); | 418 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) | 419 | | | 420 | | bailout: | 421 | | return retval; | 422 | | | 423 | | #endif | 424 | 48.5k | } |
Line | Count | Source | 289 | 40.5k | { | 290 | 40.5k | static const char FUNCTION_NAME[] = | 291 | 40.5k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 292 | | | 293 | 40.5k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) | 294 | | | 295 | 40.5k | int retval = 0, tempc; | 296 | 40.5k | size_t pitch; | 297 | 40.5k | tjhandle handle2 = NULL; | 298 | 40.5k | tjinstance *this2; | 299 | 40.5k | j_compress_ptr cinfo = NULL; | 300 | 40.5k | cjpeg_source_ptr src; | 301 | 40.5k | _JSAMPLE *dstBuf = NULL; | 302 | 40.5k | FILE *file = NULL; | 303 | 40.5k | boolean invert; | 304 | | | 305 | 40.5k | GET_TJINSTANCE(handle, NULL) | 306 | | | 307 | 40.5k | if (!filename || !width || align < 1 || !height || !pixelFormat || | 308 | 40.5k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 309 | 40.5k | THROW("Invalid argument"); | 310 | 40.5k | if ((align & (align - 1)) != 0) | 311 | 40.5k | THROW("Alignment must be a power of 2"); | 312 | | | 313 | | /* The instance handle passed to this function is used only for parameter | 314 | | retrieval. Create a new temporary instance to avoid interfering with the | 315 | | libjpeg state of the primary instance. */ | 316 | 40.5k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 317 | 40.5k | this2 = (tjinstance *)handle2; | 318 | 40.5k | cinfo = &this2->cinfo; | 319 | | | 320 | | #ifdef _MSC_VER | 321 | | if (fopen_s(&file, filename, "rb") || file == NULL) | 322 | | #else | 323 | 40.5k | if ((file = fopen(filename, "rb")) == NULL) | 324 | 0 | #endif | 325 | 40.5k | THROW_UNIX("Cannot open input file"); | 326 | | | 327 | 40.5k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 328 | 0 | THROW_UNIX("Could not read input file") | 329 | 40.5k | else if (tempc == EOF) | 330 | 40.5k | THROW("Input file contains no data"); | 331 | | | 332 | 40.5k | if (setjmp(this2->jerr.setjmp_buffer)) { | 333 | | /* If we get here, the JPEG code has signaled an error. */ | 334 | 4.43k | retval = -1; goto bailout; | 335 | 4.43k | } | 336 | | | 337 | 36.0k | cinfo->data_precision = BITS_IN_JSAMPLE; | 338 | 36.0k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 339 | 36.0k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 340 | 36.0k | if (tempc == 'B') { | 341 | 14 | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 342 | 14 | THROW("Could not initialize bitmap loader"); | 343 | 14 | invert = !this->bottomUp; | 344 | 40.1k | } else if (tempc == 'P') { | 345 | 40.1k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 346 | 40.1k | THROW("Could not initialize PPM loader"); | 347 | 40.1k | invert = this->bottomUp; | 348 | 40.1k | } else | 349 | 18.4E | THROW("Unsupported file type"); | 350 | | | 351 | 40.1k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 352 | | | 353 | 40.1k | src->input_file = file; | 354 | | /* Refuse to load images larger than the specified size. */ | 355 | 40.1k | src->max_pixels = this->maxPixels; | 356 | 40.1k | (*src->start_input) (cinfo, src); | 357 | 40.1k | if (tempc == 'B') { | 358 | 0 | if (cinfo->X_density && cinfo->Y_density) { | 359 | 0 | this->xDensity = cinfo->X_density; | 360 | 0 | this->yDensity = cinfo->Y_density; | 361 | 0 | this->densityUnits = cinfo->density_unit; | 362 | 0 | } | 363 | 0 | } | 364 | 40.1k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 365 | | | 366 | 40.1k | *width = cinfo->image_width; *height = cinfo->image_height; | 367 | 40.1k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 368 | | | 369 | 40.1k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 370 | 40.1k | if ( | 371 | | #if ULLONG_MAX > SIZE_MAX | 372 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 373 | | (unsigned long long)((size_t)-1) || | 374 | | #endif | 375 | 40.1k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 376 | 40.1k | sizeof(_JSAMPLE))) == NULL) | 377 | 40.1k | THROW("Memory allocation failure"); | 378 | | | 379 | 40.1k | if (setjmp(this2->jerr.setjmp_buffer)) { | 380 | | /* If we get here, the JPEG code has signaled an error. */ | 381 | 8.93k | retval = -1; goto bailout; | 382 | 8.93k | } | 383 | | | 384 | 98.0M | while (cinfo->next_scanline < cinfo->image_height) { | 385 | 97.9M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 386 | | | 387 | 195M | for (i = 0; i < nlines; i++) { | 388 | 97.9M | _JSAMPLE *dstptr; | 389 | 97.9M | int row; | 390 | | | 391 | 97.9M | row = cinfo->next_scanline + i; | 392 | 97.9M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 393 | 83.9M | else dstptr = &dstBuf[row * pitch]; | 394 | 97.9M | memcpy(dstptr, src->_buffer[i], | 395 | 97.9M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 396 | 97.9M | } | 397 | 97.9M | cinfo->next_scanline += nlines; | 398 | 97.9M | } | 399 | | | 400 | 31.2k | (*src->finish_input) (cinfo, src); | 401 | | | 402 | 40.5k | bailout: | 403 | 40.5k | tj3Destroy(handle2); | 404 | 40.5k | if (file) fclose(file); | 405 | 40.5k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 406 | 40.5k | return dstBuf; | 407 | | | 408 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ | 409 | | | 410 | | static const char ERROR_MSG[] = | 411 | | "16-bit data precision requires lossless JPEG,\n" | 412 | | "which was disabled at build time."; | 413 | | _JSAMPLE *retval = NULL; | 414 | | | 415 | | GET_TJINSTANCE(handle, NULL) | 416 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, | 417 | | ERROR_MSG); | 418 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) | 419 | | | 420 | | bailout: | 421 | | return retval; | 422 | | | 423 | | #endif | 424 | 31.2k | } |
Line | Count | Source | 289 | 11.3k | { | 290 | 11.3k | static const char FUNCTION_NAME[] = | 291 | 11.3k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 292 | | | 293 | 11.3k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) | 294 | | | 295 | 11.3k | int retval = 0, tempc; | 296 | 11.3k | size_t pitch; | 297 | 11.3k | tjhandle handle2 = NULL; | 298 | 11.3k | tjinstance *this2; | 299 | 11.3k | j_compress_ptr cinfo = NULL; | 300 | 11.3k | cjpeg_source_ptr src; | 301 | 11.3k | _JSAMPLE *dstBuf = NULL; | 302 | 11.3k | FILE *file = NULL; | 303 | 11.3k | boolean invert; | 304 | | | 305 | 11.3k | GET_TJINSTANCE(handle, NULL) | 306 | | | 307 | 11.3k | if (!filename || !width || align < 1 || !height || !pixelFormat || | 308 | 11.3k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 309 | 11.3k | THROW("Invalid argument"); | 310 | 11.3k | if ((align & (align - 1)) != 0) | 311 | 11.3k | THROW("Alignment must be a power of 2"); | 312 | | | 313 | | /* The instance handle passed to this function is used only for parameter | 314 | | retrieval. Create a new temporary instance to avoid interfering with the | 315 | | libjpeg state of the primary instance. */ | 316 | 11.3k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 317 | 11.3k | this2 = (tjinstance *)handle2; | 318 | 11.3k | cinfo = &this2->cinfo; | 319 | | | 320 | | #ifdef _MSC_VER | 321 | | if (fopen_s(&file, filename, "rb") || file == NULL) | 322 | | #else | 323 | 11.3k | if ((file = fopen(filename, "rb")) == NULL) | 324 | 0 | #endif | 325 | 11.3k | THROW_UNIX("Cannot open input file"); | 326 | | | 327 | 11.3k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 328 | 0 | THROW_UNIX("Could not read input file") | 329 | 11.3k | else if (tempc == EOF) | 330 | 11.3k | THROW("Input file contains no data"); | 331 | | | 332 | 11.3k | if (setjmp(this2->jerr.setjmp_buffer)) { | 333 | | /* If we get here, the JPEG code has signaled an error. */ | 334 | 1.96k | retval = -1; goto bailout; | 335 | 1.96k | } | 336 | | | 337 | 9.36k | cinfo->data_precision = BITS_IN_JSAMPLE; | 338 | 9.36k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 339 | 9.36k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 340 | 9.36k | if (tempc == 'B') { | 341 | 7 | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 342 | 7 | THROW("Could not initialize bitmap loader"); | 343 | 7 | invert = !this->bottomUp; | 344 | 11.1k | } else if (tempc == 'P') { | 345 | 11.1k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 346 | 11.1k | THROW("Could not initialize PPM loader"); | 347 | 11.1k | invert = this->bottomUp; | 348 | 11.1k | } else | 349 | 18.4E | THROW("Unsupported file type"); | 350 | | | 351 | 11.1k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 352 | | | 353 | 11.1k | src->input_file = file; | 354 | | /* Refuse to load images larger than the specified size. */ | 355 | 11.1k | src->max_pixels = this->maxPixels; | 356 | 11.1k | (*src->start_input) (cinfo, src); | 357 | 11.1k | if (tempc == 'B') { | 358 | 0 | if (cinfo->X_density && cinfo->Y_density) { | 359 | 0 | this->xDensity = cinfo->X_density; | 360 | 0 | this->yDensity = cinfo->Y_density; | 361 | 0 | this->densityUnits = cinfo->density_unit; | 362 | 0 | } | 363 | 0 | } | 364 | 11.1k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 365 | | | 366 | 11.1k | *width = cinfo->image_width; *height = cinfo->image_height; | 367 | 11.1k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 368 | | | 369 | 11.1k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 370 | 11.1k | if ( | 371 | | #if ULLONG_MAX > SIZE_MAX | 372 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 373 | | (unsigned long long)((size_t)-1) || | 374 | | #endif | 375 | 11.1k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 376 | 11.1k | sizeof(_JSAMPLE))) == NULL) | 377 | 11.1k | THROW("Memory allocation failure"); | 378 | | | 379 | 11.1k | if (setjmp(this2->jerr.setjmp_buffer)) { | 380 | | /* If we get here, the JPEG code has signaled an error. */ | 381 | 4.59k | retval = -1; goto bailout; | 382 | 4.59k | } | 383 | | | 384 | 14.2M | while (cinfo->next_scanline < cinfo->image_height) { | 385 | 14.2M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 386 | | | 387 | 28.4M | for (i = 0; i < nlines; i++) { | 388 | 14.2M | _JSAMPLE *dstptr; | 389 | 14.2M | int row; | 390 | | | 391 | 14.2M | row = cinfo->next_scanline + i; | 392 | 14.2M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 393 | 12.1M | else dstptr = &dstBuf[row * pitch]; | 394 | 14.2M | memcpy(dstptr, src->_buffer[i], | 395 | 14.2M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 396 | 14.2M | } | 397 | 14.2M | cinfo->next_scanline += nlines; | 398 | 14.2M | } | 399 | | | 400 | 6.55k | (*src->finish_input) (cinfo, src); | 401 | | | 402 | 11.3k | bailout: | 403 | 11.3k | tj3Destroy(handle2); | 404 | 11.3k | if (file) fclose(file); | 405 | 11.3k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 406 | 11.3k | return dstBuf; | 407 | | | 408 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ | 409 | | | 410 | | static const char ERROR_MSG[] = | 411 | | "16-bit data precision requires lossless JPEG,\n" | 412 | | "which was disabled at build time."; | 413 | | _JSAMPLE *retval = NULL; | 414 | | | 415 | | GET_TJINSTANCE(handle, NULL) | 416 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, | 417 | | ERROR_MSG); | 418 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) | 419 | | | 420 | | bailout: | 421 | | return retval; | 422 | | | 423 | | #endif | 424 | 6.55k | } |
|
425 | | |
426 | | |
427 | | /* TurboJPEG 3+ */ |
428 | | DLLEXPORT int GET_NAME(tj3SaveImage, BITS_IN_JSAMPLE) |
429 | | (tjhandle handle, const char *filename, const _JSAMPLE *buffer, int width, |
430 | | int pitch, int height, int pixelFormat) |
431 | 0 | { |
432 | 0 | static const char FUNCTION_NAME[] = |
433 | 0 | GET_STRING(tj3SaveImage, BITS_IN_JSAMPLE); |
434 | 0 | int retval = 0; |
435 | |
|
436 | 0 | #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) |
437 | |
|
438 | 0 | tjhandle handle2 = NULL; |
439 | 0 | tjinstance *this2; |
440 | 0 | j_decompress_ptr dinfo = NULL; |
441 | 0 | djpeg_dest_ptr dst; |
442 | 0 | FILE *file = NULL; |
443 | 0 | char *ptr = NULL; |
444 | 0 | boolean invert; |
445 | |
|
446 | 0 | GET_TJINSTANCE(handle, -1) |
447 | |
|
448 | 0 | if (!filename || !buffer || width < 1 || pitch < 0 || height < 1 || |
449 | 0 | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) |
450 | 0 | THROW("Invalid argument"); |
451 | | |
452 | | /* The instance handle passed to this function is used only for parameter |
453 | | retrieval. Create a new temporary instance to avoid interfering with the |
454 | | libjpeg state of the primary instance. */ |
455 | 0 | if ((handle2 = tj3Init(TJINIT_DECOMPRESS)) == NULL) |
456 | 0 | return -1; |
457 | 0 | this2 = (tjinstance *)handle2; |
458 | 0 | dinfo = &this2->dinfo; |
459 | |
|
460 | | #ifdef _MSC_VER |
461 | | if (fopen_s(&file, filename, "wb") || file == NULL) |
462 | | #else |
463 | 0 | if ((file = fopen(filename, "wb")) == NULL) |
464 | 0 | #endif |
465 | 0 | THROW_UNIX("Cannot open output file"); |
466 | |
|
467 | 0 | if (setjmp(this2->jerr.setjmp_buffer)) { |
468 | | /* If we get here, the JPEG code has signaled an error. */ |
469 | 0 | retval = -1; goto bailout; |
470 | 0 | } |
471 | | |
472 | 0 | this2->dinfo.out_color_space = pf2cs[pixelFormat]; |
473 | 0 | dinfo->image_width = width; dinfo->image_height = height; |
474 | 0 | dinfo->global_state = DSTATE_READY; |
475 | 0 | dinfo->scale_num = dinfo->scale_denom = 1; |
476 | 0 | dinfo->data_precision = BITS_IN_JSAMPLE; |
477 | |
|
478 | 0 | ptr = strrchr(filename, '.'); |
479 | 0 | if (ptr && !strcasecmp(ptr, ".bmp")) { |
480 | 0 | if ((dst = jinit_write_bmp(dinfo, FALSE, FALSE)) == NULL) |
481 | 0 | THROW("Could not initialize bitmap writer"); |
482 | 0 | invert = !this->bottomUp; |
483 | 0 | dinfo->X_density = (UINT16)this->xDensity; |
484 | 0 | dinfo->Y_density = (UINT16)this->yDensity; |
485 | 0 | dinfo->density_unit = (UINT8)this->densityUnits; |
486 | 0 | } else { |
487 | 0 | if ((dst = _jinit_write_ppm(dinfo)) == NULL) |
488 | 0 | THROW("Could not initialize PPM writer"); |
489 | 0 | invert = this->bottomUp; |
490 | 0 | } |
491 | | |
492 | 0 | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
493 | |
|
494 | 0 | dst->output_file = file; |
495 | 0 | (*dst->start_output) (dinfo, dst); |
496 | 0 | (*dinfo->mem->realize_virt_arrays) ((j_common_ptr)dinfo); |
497 | |
|
498 | 0 | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; |
499 | |
|
500 | 0 | while (dinfo->output_scanline < dinfo->output_height) { |
501 | 0 | _JSAMPLE *rowptr; |
502 | |
|
503 | 0 | if (invert) |
504 | 0 | rowptr = |
505 | 0 | (_JSAMPLE *)&buffer[(height - dinfo->output_scanline - 1) * pitch]; |
506 | 0 | else |
507 | 0 | rowptr = (_JSAMPLE *)&buffer[dinfo->output_scanline * pitch]; |
508 | 0 | memcpy(dst->_buffer[0], rowptr, |
509 | 0 | width * tjPixelSize[pixelFormat] * sizeof(_JSAMPLE)); |
510 | 0 | (*dst->put_pixel_rows) (dinfo, dst, 1); |
511 | 0 | dinfo->output_scanline++; |
512 | 0 | } |
513 | |
|
514 | 0 | (*dst->finish_output) (dinfo, dst); |
515 | |
|
516 | 0 | bailout: |
517 | 0 | tj3Destroy(handle2); |
518 | 0 | if (file) fclose(file); |
519 | 0 | return retval; |
520 | |
|
521 | | #else /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */ |
522 | | |
523 | | GET_TJINSTANCE(handle, -1) |
524 | | THROW("16-bit data precision requires lossless JPEG,\n" |
525 | | "which was disabled at build time.") |
526 | | bailout: |
527 | | return retval; |
528 | | |
529 | | #endif |
530 | 0 | } Unexecuted instantiation: tj3SaveImage8 Unexecuted instantiation: tj3SaveImage12 Unexecuted instantiation: tj3SaveImage16 |
531 | | |
532 | | |
533 | | #undef _JSAMPLE |
534 | | #undef _JSAMPROW |
535 | | #undef _buffer |
536 | | #undef _jinit_read_ppm |
537 | | #undef _jinit_write_ppm |
538 | | #undef _jpeg_crop_scanline |
539 | | #undef _jpeg_read_scanlines |
540 | | #undef _jpeg_skip_scanlines |
541 | | #undef _jpeg_write_scanlines |