/src/libjpeg-turbo.dev/src/turbojpeg-mp.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2009-2026 D. R. Commander |
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 | 201M | #define _JSAMPLE JSAMPLE |
34 | 84.1k | #define _JSAMPROW JSAMPROW |
35 | 201M | #define _buffer buffer |
36 | 88.6k | #define _jinit_read_ppm jinit_read_ppm |
37 | 0 | #define _jinit_write_ppm jinit_write_ppm |
38 | 1.93k | #define _jpeg_crop_scanline jpeg_crop_scanline |
39 | 35.7M | #define _jpeg_read_scanlines jpeg_read_scanlines |
40 | 3.75k | #define _jpeg_skip_scanlines jpeg_skip_scanlines |
41 | 40.6k | #define _jpeg_write_scanlines jpeg_write_scanlines |
42 | | #elif BITS_IN_JSAMPLE == 12 |
43 | 129M | #define _JSAMPLE J12SAMPLE |
44 | 48.0k | #define _JSAMPROW J12SAMPROW |
45 | 128M | #define _buffer buffer12 |
46 | 65.4k | #define _jinit_read_ppm j12init_read_ppm |
47 | 0 | #define _jinit_write_ppm j12init_write_ppm |
48 | 586 | #define _jpeg_crop_scanline jpeg12_crop_scanline |
49 | 7.96M | #define _jpeg_read_scanlines jpeg12_read_scanlines |
50 | 1.08k | #define _jpeg_skip_scanlines jpeg12_skip_scanlines |
51 | 37.5k | #define _jpeg_write_scanlines jpeg12_write_scanlines |
52 | | #elif BITS_IN_JSAMPLE == 16 |
53 | 34.1M | #define _JSAMPLE J16SAMPLE |
54 | 20.8k | #define _JSAMPROW J16SAMPROW |
55 | 34.0M | #define _buffer buffer16 |
56 | 25.4k | #define _jinit_read_ppm j16init_read_ppm |
57 | 0 | #define _jinit_write_ppm j16init_write_ppm |
58 | 2.32M | #define _jpeg_read_scanlines jpeg16_read_scanlines |
59 | 11.3k | #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 | 375k | #define _GET_STRING(name, suffix) #name #suffix |
65 | 375k | #define GET_STRING(name, suffix) _GET_STRING(name, suffix) |
66 | | |
67 | | |
68 | | /******************************** Compressor *********************************/ |
69 | | |
70 | | /* TurboJPEG 3.0+ */ |
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 | 90.0k | { |
75 | 90.0k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); |
76 | 90.0k | int i, retval = 0; |
77 | 90.0k | boolean alloc = TRUE; |
78 | 90.0k | _JSAMPROW *row_pointer = NULL; |
79 | | |
80 | 90.0k | GET_CINSTANCE(handle) |
81 | 90.0k | if ((this->init & COMPRESS) == 0) |
82 | 90.0k | THROW("Instance has not been initialized for compression"); |
83 | | |
84 | 90.0k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || |
85 | 90.0k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || |
86 | 90.0k | jpegSize == NULL) |
87 | 90.0k | THROW("Invalid argument"); |
88 | | |
89 | 90.0k | if (!this->lossless && this->quality == -1) |
90 | 90.0k | THROW("TJPARAM_QUALITY must be specified"); |
91 | 90.0k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) |
92 | 90.0k | THROW("TJPARAM_SUBSAMP must be specified"); |
93 | | |
94 | 90.0k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; |
95 | | |
96 | 90.0k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) |
97 | 90.0k | THROW("Memory allocation failure"); |
98 | | |
99 | 90.0k | if (setjmp(this->jerr.setjmp_buffer)) { |
100 | | /* If we get here, the JPEG code has signaled an error. */ |
101 | 658 | retval = -1; goto bailout; |
102 | 658 | } |
103 | | |
104 | 89.3k | cinfo->image_width = width; |
105 | 89.3k | cinfo->image_height = height; |
106 | 89.3k | cinfo->data_precision = BITS_IN_JSAMPLE; |
107 | | #if BITS_IN_JSAMPLE == 8 |
108 | 40.6k | if (this->lossless && this->precision >= 2 && |
109 | 13.0k | this->precision <= BITS_IN_JSAMPLE) |
110 | | #else |
111 | 48.7k | if (this->lossless && this->precision >= BITS_IN_JSAMPLE - 3 && |
112 | 22.5k | this->precision <= BITS_IN_JSAMPLE) |
113 | 22.5k | #endif |
114 | 35.5k | cinfo->data_precision = this->precision; |
115 | | |
116 | 89.3k | setCompDefaults(this, pixelFormat, FALSE); |
117 | 89.3k | if (this->noRealloc) alloc = FALSE; |
118 | 89.3k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); |
119 | | |
120 | 89.3k | jpeg_start_compress(cinfo, TRUE); |
121 | 89.3k | if (this->iccBuf != NULL && this->iccSize != 0) |
122 | 69.8k | jpeg_write_icc_profile(cinfo, this->iccBuf, (unsigned int)this->iccSize); |
123 | 263M | for (i = 0; i < height; i++) { |
124 | 263M | if (this->bottomUp) |
125 | 38.8M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; |
126 | 224M | else |
127 | 224M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; |
128 | 263M | } |
129 | 178k | while (cinfo->next_scanline < cinfo->image_height) |
130 | 89.5k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], |
131 | 89.5k | cinfo->image_height - cinfo->next_scanline); |
132 | 89.3k | jpeg_finish_compress(cinfo); |
133 | | |
134 | 90.0k | bailout: |
135 | 90.0k | if (cinfo->global_state > CSTATE_START && alloc) |
136 | 125 | (*cinfo->dest->term_destination) (cinfo); |
137 | 90.0k | if (cinfo->global_state > CSTATE_START || retval == -1) |
138 | 658 | jpeg_abort_compress(cinfo); |
139 | 90.0k | free(row_pointer); |
140 | 90.0k | if (this->jerr.warning) retval = -1; |
141 | 90.0k | return retval; |
142 | 89.3k | } Line | Count | Source | 74 | 40.8k | { | 75 | 40.8k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 40.8k | int i, retval = 0; | 77 | 40.8k | boolean alloc = TRUE; | 78 | 40.8k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 40.8k | GET_CINSTANCE(handle) | 81 | 40.8k | if ((this->init & COMPRESS) == 0) | 82 | 40.8k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 40.8k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 40.8k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 40.8k | jpegSize == NULL) | 87 | 40.8k | THROW("Invalid argument"); | 88 | | | 89 | 40.8k | if (!this->lossless && this->quality == -1) | 90 | 40.8k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 40.8k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 40.8k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 40.8k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 40.8k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 40.8k | THROW("Memory allocation failure"); | 98 | | | 99 | 40.8k | if (setjmp(this->jerr.setjmp_buffer)) { | 100 | | /* If we get here, the JPEG code has signaled an error. */ | 101 | 252 | retval = -1; goto bailout; | 102 | 252 | } | 103 | | | 104 | 40.6k | cinfo->image_width = width; | 105 | 40.6k | cinfo->image_height = height; | 106 | 40.6k | cinfo->data_precision = BITS_IN_JSAMPLE; | 107 | 40.6k | #if BITS_IN_JSAMPLE == 8 | 108 | 40.6k | if (this->lossless && this->precision >= 2 && | 109 | 13.0k | this->precision <= BITS_IN_JSAMPLE) | 110 | | #else | 111 | | if (this->lossless && this->precision >= BITS_IN_JSAMPLE - 3 && | 112 | | this->precision <= BITS_IN_JSAMPLE) | 113 | | #endif | 114 | 13.0k | cinfo->data_precision = this->precision; | 115 | | | 116 | 40.6k | setCompDefaults(this, pixelFormat, FALSE); | 117 | 40.6k | if (this->noRealloc) alloc = FALSE; | 118 | 40.6k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 119 | | | 120 | 40.6k | jpeg_start_compress(cinfo, TRUE); | 121 | 40.6k | if (this->iccBuf != NULL && this->iccSize != 0) | 122 | 32.0k | jpeg_write_icc_profile(cinfo, this->iccBuf, (unsigned int)this->iccSize); | 123 | 109M | for (i = 0; i < height; i++) { | 124 | 109M | if (this->bottomUp) | 125 | 16.6M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 126 | 92.9M | else | 127 | 92.9M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 128 | 109M | } | 129 | 81.2k | while (cinfo->next_scanline < cinfo->image_height) | 130 | 40.6k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 131 | 40.6k | cinfo->image_height - cinfo->next_scanline); | 132 | 40.6k | jpeg_finish_compress(cinfo); | 133 | | | 134 | 40.8k | bailout: | 135 | 40.8k | if (cinfo->global_state > CSTATE_START && alloc) | 136 | 0 | (*cinfo->dest->term_destination) (cinfo); | 137 | 40.8k | if (cinfo->global_state > CSTATE_START || retval == -1) | 138 | 252 | jpeg_abort_compress(cinfo); | 139 | 40.8k | free(row_pointer); | 140 | 40.8k | if (this->jerr.warning) retval = -1; | 141 | 40.8k | return retval; | 142 | 40.6k | } |
Line | Count | Source | 74 | 37.7k | { | 75 | 37.7k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 37.7k | int i, retval = 0; | 77 | 37.7k | boolean alloc = TRUE; | 78 | 37.7k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 37.7k | GET_CINSTANCE(handle) | 81 | 37.7k | if ((this->init & COMPRESS) == 0) | 82 | 37.7k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 37.7k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 37.7k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 37.7k | jpegSize == NULL) | 87 | 37.7k | THROW("Invalid argument"); | 88 | | | 89 | 37.7k | if (!this->lossless && this->quality == -1) | 90 | 37.7k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 37.7k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 37.7k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 37.7k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 37.7k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 37.7k | THROW("Memory allocation failure"); | 98 | | | 99 | 37.7k | if (setjmp(this->jerr.setjmp_buffer)) { | 100 | | /* If we get here, the JPEG code has signaled an error. */ | 101 | 227 | retval = -1; goto bailout; | 102 | 227 | } | 103 | | | 104 | 37.4k | cinfo->image_width = width; | 105 | 37.4k | cinfo->image_height = height; | 106 | 37.4k | cinfo->data_precision = BITS_IN_JSAMPLE; | 107 | | #if BITS_IN_JSAMPLE == 8 | 108 | | if (this->lossless && this->precision >= 2 && | 109 | | this->precision <= BITS_IN_JSAMPLE) | 110 | | #else | 111 | 37.4k | if (this->lossless && this->precision >= BITS_IN_JSAMPLE - 3 && | 112 | 11.0k | this->precision <= BITS_IN_JSAMPLE) | 113 | 11.0k | #endif | 114 | 11.0k | cinfo->data_precision = this->precision; | 115 | | | 116 | 37.4k | setCompDefaults(this, pixelFormat, FALSE); | 117 | 37.4k | if (this->noRealloc) alloc = FALSE; | 118 | 37.4k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 119 | | | 120 | 37.4k | jpeg_start_compress(cinfo, TRUE); | 121 | 37.4k | if (this->iccBuf != NULL && this->iccSize != 0) | 122 | 29.1k | jpeg_write_icc_profile(cinfo, this->iccBuf, (unsigned int)this->iccSize); | 123 | 122M | for (i = 0; i < height; i++) { | 124 | 122M | if (this->bottomUp) | 125 | 17.7M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 126 | 104M | else | 127 | 104M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 128 | 122M | } | 129 | 75.0k | while (cinfo->next_scanline < cinfo->image_height) | 130 | 37.5k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 131 | 37.5k | cinfo->image_height - cinfo->next_scanline); | 132 | 37.4k | jpeg_finish_compress(cinfo); | 133 | | | 134 | 37.7k | bailout: | 135 | 37.7k | if (cinfo->global_state > CSTATE_START && alloc) | 136 | 49 | (*cinfo->dest->term_destination) (cinfo); | 137 | 37.7k | if (cinfo->global_state > CSTATE_START || retval == -1) | 138 | 227 | jpeg_abort_compress(cinfo); | 139 | 37.7k | free(row_pointer); | 140 | 37.7k | if (this->jerr.warning) retval = -1; | 141 | 37.7k | return retval; | 142 | 37.4k | } |
Line | Count | Source | 74 | 11.4k | { | 75 | 11.4k | static const char FUNCTION_NAME[] = GET_STRING(tj3Compress, BITS_IN_JSAMPLE); | 76 | 11.4k | int i, retval = 0; | 77 | 11.4k | boolean alloc = TRUE; | 78 | 11.4k | _JSAMPROW *row_pointer = NULL; | 79 | | | 80 | 11.4k | GET_CINSTANCE(handle) | 81 | 11.4k | if ((this->init & COMPRESS) == 0) | 82 | 11.4k | THROW("Instance has not been initialized for compression"); | 83 | | | 84 | 11.4k | if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || | 85 | 11.4k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || | 86 | 11.4k | jpegSize == NULL) | 87 | 11.4k | THROW("Invalid argument"); | 88 | | | 89 | 11.4k | if (!this->lossless && this->quality == -1) | 90 | 11.4k | THROW("TJPARAM_QUALITY must be specified"); | 91 | 11.4k | if (!this->lossless && this->subsamp == TJSAMP_UNKNOWN) | 92 | 11.4k | THROW("TJPARAM_SUBSAMP must be specified"); | 93 | | | 94 | 11.4k | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; | 95 | | | 96 | 11.4k | if ((row_pointer = (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * height)) == NULL) | 97 | 11.4k | THROW("Memory allocation failure"); | 98 | | | 99 | 11.4k | if (setjmp(this->jerr.setjmp_buffer)) { | 100 | | /* If we get here, the JPEG code has signaled an error. */ | 101 | 179 | retval = -1; goto bailout; | 102 | 179 | } | 103 | | | 104 | 11.2k | cinfo->image_width = width; | 105 | 11.2k | cinfo->image_height = height; | 106 | 11.2k | cinfo->data_precision = BITS_IN_JSAMPLE; | 107 | | #if BITS_IN_JSAMPLE == 8 | 108 | | if (this->lossless && this->precision >= 2 && | 109 | | this->precision <= BITS_IN_JSAMPLE) | 110 | | #else | 111 | 11.4k | if (this->lossless && this->precision >= BITS_IN_JSAMPLE - 3 && | 112 | 11.4k | this->precision <= BITS_IN_JSAMPLE) | 113 | 11.4k | #endif | 114 | 11.4k | cinfo->data_precision = this->precision; | 115 | | | 116 | 11.2k | setCompDefaults(this, pixelFormat, FALSE); | 117 | 11.2k | if (this->noRealloc) alloc = FALSE; | 118 | 11.2k | jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); | 119 | | | 120 | 11.2k | jpeg_start_compress(cinfo, TRUE); | 121 | 11.2k | if (this->iccBuf != NULL && this->iccSize != 0) | 122 | 8.60k | jpeg_write_icc_profile(cinfo, this->iccBuf, (unsigned int)this->iccSize); | 123 | 31.6M | for (i = 0; i < height; i++) { | 124 | 31.6M | if (this->bottomUp) | 125 | 4.51M | row_pointer[i] = (_JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; | 126 | 27.0M | else | 127 | 27.0M | row_pointer[i] = (_JSAMPROW)&srcBuf[i * (size_t)pitch]; | 128 | 31.6M | } | 129 | 22.5k | while (cinfo->next_scanline < cinfo->image_height) | 130 | 11.3k | _jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], | 131 | 11.3k | cinfo->image_height - cinfo->next_scanline); | 132 | 11.2k | jpeg_finish_compress(cinfo); | 133 | | | 134 | 11.4k | bailout: | 135 | 11.4k | if (cinfo->global_state > CSTATE_START && alloc) | 136 | 76 | (*cinfo->dest->term_destination) (cinfo); | 137 | 11.4k | if (cinfo->global_state > CSTATE_START || retval == -1) | 138 | 179 | jpeg_abort_compress(cinfo); | 139 | 11.4k | free(row_pointer); | 140 | 11.4k | if (this->jerr.warning) retval = -1; | 141 | 11.4k | return retval; | 142 | 11.2k | } |
|
143 | | |
144 | | |
145 | | /******************************* Decompressor ********************************/ |
146 | | |
147 | | /* TurboJPEG 3.0+ */ |
148 | | DLLEXPORT int GET_NAME(tj3Decompress, BITS_IN_JSAMPLE) |
149 | | (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, |
150 | | _JSAMPLE *dstBuf, int pitch, int pixelFormat) |
151 | 62.9k | { |
152 | 62.9k | static const char FUNCTION_NAME[] = |
153 | 62.9k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); |
154 | 62.9k | _JSAMPROW *row_pointer = NULL; |
155 | 62.9k | int croppedHeight, i, retval = 0; |
156 | | #if BITS_IN_JSAMPLE != 16 |
157 | | int scaledWidth; |
158 | | #endif |
159 | 62.9k | struct my_progress_mgr progress; |
160 | | |
161 | 62.9k | GET_DINSTANCE(handle); |
162 | 62.9k | if ((this->init & DECOMPRESS) == 0) |
163 | 62.9k | THROW("Instance has not been initialized for decompression"); |
164 | | |
165 | 62.9k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || |
166 | 62.9k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) |
167 | 62.9k | THROW("Invalid argument"); |
168 | | |
169 | 62.9k | if (this->scanLimit) { |
170 | 62.9k | memset(&progress, 0, sizeof(struct my_progress_mgr)); |
171 | 62.9k | progress.pub.progress_monitor = my_progress_monitor; |
172 | 62.9k | progress.this = this; |
173 | 62.9k | dinfo->progress = &progress.pub; |
174 | 62.9k | } else |
175 | 0 | dinfo->progress = NULL; |
176 | | |
177 | 62.9k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
178 | | |
179 | 62.9k | if (setjmp(this->jerr.setjmp_buffer)) { |
180 | | /* If we get here, the JPEG code has signaled an error. */ |
181 | 33.8k | retval = -1; goto bailout; |
182 | 33.8k | } |
183 | | |
184 | 62.9k | if (dinfo->global_state <= DSTATE_INHEADER) { |
185 | 62.9k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); |
186 | 62.9k | jpeg_read_header(dinfo, TRUE); |
187 | 62.9k | } |
188 | 29.1k | setDecompParameters(this); |
189 | | #if BITS_IN_JSAMPLE == 12 |
190 | 5.77k | if (this->precision == 8 && !this->lossless) |
191 | 0 | dinfo->data_precision = 12; |
192 | | #endif |
193 | 29.1k | if (this->maxPixels && |
194 | 0 | (unsigned long long)this->jpegWidth * this->jpegHeight > |
195 | 0 | (unsigned long long)this->maxPixels) |
196 | 29.1k | THROW("Image is too large"); |
197 | 29.1k | this->dinfo.out_color_space = pf2cs[pixelFormat]; |
198 | | #if BITS_IN_JSAMPLE != 16 |
199 | 25.9k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); |
200 | | #endif |
201 | 29.1k | dinfo->do_fancy_upsampling = !this->fastUpsample; |
202 | 29.1k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; |
203 | | |
204 | 29.1k | dinfo->scale_num = this->scalingFactor.num; |
205 | 29.1k | dinfo->scale_denom = this->scalingFactor.denom; |
206 | | |
207 | 29.1k | jpeg_start_decompress(dinfo); |
208 | | |
209 | | #if BITS_IN_JSAMPLE != 16 |
210 | 25.9k | if (this->croppingRegion.x != 0 || |
211 | 23.3k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { |
212 | 2.52k | JDIMENSION crop_x = this->croppingRegion.x; |
213 | 2.52k | JDIMENSION crop_w = this->croppingRegion.w; |
214 | | |
215 | 2.52k | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); |
216 | 2.52k | if ((int)crop_x != this->croppingRegion.x) |
217 | 9 | THROWI("Unexplained mismatch between specified (%d) and\n" |
218 | 2.52k | "actual (%d) cropping region left boundary", |
219 | 2.52k | this->croppingRegion.x, (int)crop_x); |
220 | 2.51k | if ((int)crop_w != this->croppingRegion.w) |
221 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
222 | 2.51k | "actual (%d) cropping region width", |
223 | 2.51k | this->croppingRegion.w, (int)crop_w); |
224 | 2.51k | } |
225 | 25.9k | #endif |
226 | | |
227 | 29.1k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; |
228 | | |
229 | 25.9k | croppedHeight = dinfo->output_height; |
230 | | #if BITS_IN_JSAMPLE != 16 |
231 | 25.9k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) |
232 | 2.51k | croppedHeight = this->croppingRegion.h; |
233 | | #endif |
234 | 29.1k | if ((row_pointer = |
235 | 29.1k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) |
236 | 29.1k | THROW("Memory allocation failure"); |
237 | 29.1k | if (setjmp(this->jerr.setjmp_buffer)) { |
238 | | /* If we get here, the JPEG code has signaled an error. */ |
239 | 6.78k | retval = -1; goto bailout; |
240 | 6.78k | } |
241 | 120M | for (i = 0; i < (int)croppedHeight; i++) { |
242 | 120M | if (this->bottomUp) |
243 | 44.7M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; |
244 | 75.5M | else |
245 | 75.5M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; |
246 | 120M | } |
247 | | |
248 | | #if BITS_IN_JSAMPLE != 16 |
249 | 23.3k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { |
250 | 2.51k | if (this->croppingRegion.y != 0) { |
251 | 2.51k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); |
252 | | |
253 | 2.51k | if ((int)lines != this->croppingRegion.y) |
254 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
255 | | "actual (%d) cropping region upper boundary", |
256 | 2.51k | this->croppingRegion.y, (int)lines); |
257 | 2.51k | } |
258 | 103k | while ((int)dinfo->output_scanline < |
259 | 103k | this->croppingRegion.y + this->croppingRegion.h) |
260 | 100k | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - |
261 | 100k | this->croppingRegion.y], |
262 | 100k | this->croppingRegion.y + this->croppingRegion.h - |
263 | 100k | dinfo->output_scanline); |
264 | 2.51k | if (this->croppingRegion.y + this->croppingRegion.h != |
265 | 2.51k | (int)dinfo->output_height) { |
266 | 2.31k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - |
267 | | this->croppingRegion.y - |
268 | | this->croppingRegion.h); |
269 | | |
270 | 2.31k | if (lines != dinfo->output_height - this->croppingRegion.y - |
271 | 2.31k | this->croppingRegion.h) |
272 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" |
273 | 2.31k | "actual (%d) cropping region lower boundary", |
274 | 2.31k | this->croppingRegion.y + this->croppingRegion.h, |
275 | 2.31k | (int)(dinfo->output_height - lines)); |
276 | 2.31k | } |
277 | 2.51k | } else |
278 | 19.0k | #endif |
279 | 19.0k | { |
280 | 45.9M | while (dinfo->output_scanline < dinfo->output_height) |
281 | 45.9M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], |
282 | 45.9M | dinfo->output_height - dinfo->output_scanline); |
283 | 19.0k | } |
284 | 21.5k | jpeg_finish_decompress(dinfo); |
285 | | |
286 | 62.9k | bailout: |
287 | 62.9k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); |
288 | 62.9k | free(row_pointer); |
289 | 62.9k | if (this->jerr.warning) retval = -1; |
290 | 62.9k | return retval; |
291 | 21.5k | } Line | Count | Source | 151 | 43.2k | { | 152 | 43.2k | static const char FUNCTION_NAME[] = | 153 | 43.2k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 154 | 43.2k | _JSAMPROW *row_pointer = NULL; | 155 | 43.2k | int croppedHeight, i, retval = 0; | 156 | 43.2k | #if BITS_IN_JSAMPLE != 16 | 157 | 43.2k | int scaledWidth; | 158 | 43.2k | #endif | 159 | 43.2k | struct my_progress_mgr progress; | 160 | | | 161 | 43.2k | GET_DINSTANCE(handle); | 162 | 43.2k | if ((this->init & DECOMPRESS) == 0) | 163 | 43.2k | THROW("Instance has not been initialized for decompression"); | 164 | | | 165 | 43.2k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 166 | 43.2k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 167 | 43.2k | THROW("Invalid argument"); | 168 | | | 169 | 43.2k | if (this->scanLimit) { | 170 | 43.2k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 171 | 43.2k | progress.pub.progress_monitor = my_progress_monitor; | 172 | 43.2k | progress.this = this; | 173 | 43.2k | dinfo->progress = &progress.pub; | 174 | 43.2k | } else | 175 | 0 | dinfo->progress = NULL; | 176 | | | 177 | 43.2k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 178 | | | 179 | 43.2k | if (setjmp(this->jerr.setjmp_buffer)) { | 180 | | /* If we get here, the JPEG code has signaled an error. */ | 181 | 23.0k | retval = -1; goto bailout; | 182 | 23.0k | } | 183 | | | 184 | 43.2k | if (dinfo->global_state <= DSTATE_INHEADER) { | 185 | 43.2k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 186 | 43.2k | jpeg_read_header(dinfo, TRUE); | 187 | 43.2k | } | 188 | 20.1k | setDecompParameters(this); | 189 | | #if BITS_IN_JSAMPLE == 12 | 190 | | if (this->precision == 8 && !this->lossless) | 191 | | dinfo->data_precision = 12; | 192 | | #endif | 193 | 20.1k | if (this->maxPixels && | 194 | 0 | (unsigned long long)this->jpegWidth * this->jpegHeight > | 195 | 0 | (unsigned long long)this->maxPixels) | 196 | 20.1k | THROW("Image is too large"); | 197 | 20.1k | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 198 | 20.1k | #if BITS_IN_JSAMPLE != 16 | 199 | 20.1k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 200 | 20.1k | #endif | 201 | 20.1k | dinfo->do_fancy_upsampling = !this->fastUpsample; | 202 | 20.1k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 203 | | | 204 | 20.1k | dinfo->scale_num = this->scalingFactor.num; | 205 | 20.1k | dinfo->scale_denom = this->scalingFactor.denom; | 206 | | | 207 | 20.1k | jpeg_start_decompress(dinfo); | 208 | | | 209 | 20.1k | #if BITS_IN_JSAMPLE != 16 | 210 | 20.1k | if (this->croppingRegion.x != 0 || | 211 | 18.1k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 212 | 1.93k | JDIMENSION crop_x = this->croppingRegion.x; | 213 | 1.93k | JDIMENSION crop_w = this->croppingRegion.w; | 214 | | | 215 | 1.93k | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 216 | 1.93k | if ((int)crop_x != this->croppingRegion.x) | 217 | 6 | THROWI("Unexplained mismatch between specified (%d) and\n" | 218 | 1.93k | "actual (%d) cropping region left boundary", | 219 | 1.93k | this->croppingRegion.x, (int)crop_x); | 220 | 1.93k | if ((int)crop_w != this->croppingRegion.w) | 221 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 222 | 1.93k | "actual (%d) cropping region width", | 223 | 1.93k | this->croppingRegion.w, (int)crop_w); | 224 | 1.93k | } | 225 | 20.1k | #endif | 226 | | | 227 | 20.1k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 228 | | | 229 | 20.1k | croppedHeight = dinfo->output_height; | 230 | 20.1k | #if BITS_IN_JSAMPLE != 16 | 231 | 20.1k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 232 | 1.93k | croppedHeight = this->croppingRegion.h; | 233 | 20.1k | #endif | 234 | 20.1k | if ((row_pointer = | 235 | 20.1k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 236 | 20.1k | THROW("Memory allocation failure"); | 237 | 20.1k | if (setjmp(this->jerr.setjmp_buffer)) { | 238 | | /* If we get here, the JPEG code has signaled an error. */ | 239 | 3.47k | retval = -1; goto bailout; | 240 | 3.47k | } | 241 | 80.3M | for (i = 0; i < (int)croppedHeight; i++) { | 242 | 80.2M | if (this->bottomUp) | 243 | 30.3M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 244 | 49.9M | else | 245 | 49.9M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 246 | 80.2M | } | 247 | | | 248 | 16.6k | #if BITS_IN_JSAMPLE != 16 | 249 | 18.1k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 250 | 1.93k | if (this->croppingRegion.y != 0) { | 251 | 1.93k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 252 | | | 253 | 1.93k | if ((int)lines != this->croppingRegion.y) | 254 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 255 | 1.93k | "actual (%d) cropping region upper boundary", | 256 | 1.93k | this->croppingRegion.y, (int)lines); | 257 | 1.93k | } | 258 | 78.7k | while ((int)dinfo->output_scanline < | 259 | 78.7k | this->croppingRegion.y + this->croppingRegion.h) | 260 | 76.8k | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 261 | 76.8k | this->croppingRegion.y], | 262 | 76.8k | this->croppingRegion.y + this->croppingRegion.h - | 263 | 76.8k | dinfo->output_scanline); | 264 | 1.93k | if (this->croppingRegion.y + this->croppingRegion.h != | 265 | 1.93k | (int)dinfo->output_height) { | 266 | 1.81k | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 267 | 1.81k | this->croppingRegion.y - | 268 | 1.81k | this->croppingRegion.h); | 269 | | | 270 | 1.81k | if (lines != dinfo->output_height - this->croppingRegion.y - | 271 | 1.81k | this->croppingRegion.h) | 272 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 273 | 1.81k | "actual (%d) cropping region lower boundary", | 274 | 1.81k | this->croppingRegion.y + this->croppingRegion.h, | 275 | 1.81k | (int)(dinfo->output_height - lines)); | 276 | 1.81k | } | 277 | 1.93k | } else | 278 | 14.7k | #endif | 279 | 14.7k | { | 280 | 35.6M | while (dinfo->output_scanline < dinfo->output_height) | 281 | 35.6M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 282 | 35.6M | dinfo->output_height - dinfo->output_scanline); | 283 | 14.7k | } | 284 | 16.6k | jpeg_finish_decompress(dinfo); | 285 | | | 286 | 43.2k | bailout: | 287 | 43.2k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 288 | 43.2k | free(row_pointer); | 289 | 43.2k | if (this->jerr.warning) retval = -1; | 290 | 43.2k | return retval; | 291 | 16.6k | } |
Line | Count | Source | 151 | 10.3k | { | 152 | 10.3k | static const char FUNCTION_NAME[] = | 153 | 10.3k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 154 | 10.3k | _JSAMPROW *row_pointer = NULL; | 155 | 10.3k | int croppedHeight, i, retval = 0; | 156 | 10.3k | #if BITS_IN_JSAMPLE != 16 | 157 | 10.3k | int scaledWidth; | 158 | 10.3k | #endif | 159 | 10.3k | struct my_progress_mgr progress; | 160 | | | 161 | 10.3k | GET_DINSTANCE(handle); | 162 | 10.3k | if ((this->init & DECOMPRESS) == 0) | 163 | 10.3k | THROW("Instance has not been initialized for decompression"); | 164 | | | 165 | 10.3k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 166 | 10.3k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 167 | 10.3k | THROW("Invalid argument"); | 168 | | | 169 | 10.3k | if (this->scanLimit) { | 170 | 10.3k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 171 | 10.3k | progress.pub.progress_monitor = my_progress_monitor; | 172 | 10.3k | progress.this = this; | 173 | 10.3k | dinfo->progress = &progress.pub; | 174 | 10.3k | } else | 175 | 0 | dinfo->progress = NULL; | 176 | | | 177 | 10.3k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 178 | | | 179 | 10.3k | if (setjmp(this->jerr.setjmp_buffer)) { | 180 | | /* If we get here, the JPEG code has signaled an error. */ | 181 | 4.60k | retval = -1; goto bailout; | 182 | 4.60k | } | 183 | | | 184 | 10.3k | if (dinfo->global_state <= DSTATE_INHEADER) { | 185 | 10.3k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 186 | 10.3k | jpeg_read_header(dinfo, TRUE); | 187 | 10.3k | } | 188 | 5.77k | setDecompParameters(this); | 189 | 5.77k | #if BITS_IN_JSAMPLE == 12 | 190 | 5.77k | if (this->precision == 8 && !this->lossless) | 191 | 0 | dinfo->data_precision = 12; | 192 | 5.77k | #endif | 193 | 5.77k | if (this->maxPixels && | 194 | 0 | (unsigned long long)this->jpegWidth * this->jpegHeight > | 195 | 0 | (unsigned long long)this->maxPixels) | 196 | 5.77k | THROW("Image is too large"); | 197 | 5.77k | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 198 | 5.77k | #if BITS_IN_JSAMPLE != 16 | 199 | 5.77k | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 200 | 5.77k | #endif | 201 | 5.77k | dinfo->do_fancy_upsampling = !this->fastUpsample; | 202 | 5.77k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 203 | | | 204 | 5.77k | dinfo->scale_num = this->scalingFactor.num; | 205 | 5.77k | dinfo->scale_denom = this->scalingFactor.denom; | 206 | | | 207 | 5.77k | jpeg_start_decompress(dinfo); | 208 | | | 209 | 5.77k | #if BITS_IN_JSAMPLE != 16 | 210 | 5.77k | if (this->croppingRegion.x != 0 || | 211 | 5.19k | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 212 | 586 | JDIMENSION crop_x = this->croppingRegion.x; | 213 | 586 | JDIMENSION crop_w = this->croppingRegion.w; | 214 | | | 215 | 586 | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 216 | 586 | if ((int)crop_x != this->croppingRegion.x) | 217 | 3 | THROWI("Unexplained mismatch between specified (%d) and\n" | 218 | 586 | "actual (%d) cropping region left boundary", | 219 | 586 | this->croppingRegion.x, (int)crop_x); | 220 | 583 | if ((int)crop_w != this->croppingRegion.w) | 221 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 222 | 583 | "actual (%d) cropping region width", | 223 | 583 | this->croppingRegion.w, (int)crop_w); | 224 | 583 | } | 225 | 5.77k | #endif | 226 | | | 227 | 5.77k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 228 | | | 229 | 5.77k | croppedHeight = dinfo->output_height; | 230 | 5.77k | #if BITS_IN_JSAMPLE != 16 | 231 | 5.77k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 232 | 583 | croppedHeight = this->croppingRegion.h; | 233 | 5.77k | #endif | 234 | 5.77k | if ((row_pointer = | 235 | 5.77k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 236 | 5.77k | THROW("Memory allocation failure"); | 237 | 5.77k | if (setjmp(this->jerr.setjmp_buffer)) { | 238 | | /* If we get here, the JPEG code has signaled an error. */ | 239 | 882 | retval = -1; goto bailout; | 240 | 882 | } | 241 | 16.4M | for (i = 0; i < (int)croppedHeight; i++) { | 242 | 16.4M | if (this->bottomUp) | 243 | 5.99M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 244 | 10.4M | else | 245 | 10.4M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 246 | 16.4M | } | 247 | | | 248 | 4.89k | #if BITS_IN_JSAMPLE != 16 | 249 | 5.19k | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 250 | 583 | if (this->croppingRegion.y != 0) { | 251 | 583 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 252 | | | 253 | 583 | if ((int)lines != this->croppingRegion.y) | 254 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 255 | 583 | "actual (%d) cropping region upper boundary", | 256 | 583 | this->croppingRegion.y, (int)lines); | 257 | 583 | } | 258 | 24.3k | while ((int)dinfo->output_scanline < | 259 | 24.3k | this->croppingRegion.y + this->croppingRegion.h) | 260 | 23.7k | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 261 | 23.7k | this->croppingRegion.y], | 262 | 23.7k | this->croppingRegion.y + this->croppingRegion.h - | 263 | 23.7k | dinfo->output_scanline); | 264 | 583 | if (this->croppingRegion.y + this->croppingRegion.h != | 265 | 583 | (int)dinfo->output_height) { | 266 | 499 | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 267 | 499 | this->croppingRegion.y - | 268 | 499 | this->croppingRegion.h); | 269 | | | 270 | 499 | if (lines != dinfo->output_height - this->croppingRegion.y - | 271 | 499 | this->croppingRegion.h) | 272 | 0 | THROWI("Unexplained mismatch between specified (%d) and\n" | 273 | 499 | "actual (%d) cropping region lower boundary", | 274 | 499 | this->croppingRegion.y + this->croppingRegion.h, | 275 | 499 | (int)(dinfo->output_height - lines)); | 276 | 499 | } | 277 | 583 | } else | 278 | 4.31k | #endif | 279 | 4.31k | { | 280 | 7.94M | while (dinfo->output_scanline < dinfo->output_height) | 281 | 7.93M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 282 | 7.93M | dinfo->output_height - dinfo->output_scanline); | 283 | 4.31k | } | 284 | 4.89k | jpeg_finish_decompress(dinfo); | 285 | | | 286 | 10.3k | bailout: | 287 | 10.3k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 288 | 10.3k | free(row_pointer); | 289 | 10.3k | if (this->jerr.warning) retval = -1; | 290 | 10.3k | return retval; | 291 | 4.89k | } |
Line | Count | Source | 151 | 9.36k | { | 152 | 9.36k | static const char FUNCTION_NAME[] = | 153 | 9.36k | GET_STRING(tj3Decompress, BITS_IN_JSAMPLE); | 154 | 9.36k | _JSAMPROW *row_pointer = NULL; | 155 | 9.36k | int croppedHeight, i, retval = 0; | 156 | | #if BITS_IN_JSAMPLE != 16 | 157 | | int scaledWidth; | 158 | | #endif | 159 | 9.36k | struct my_progress_mgr progress; | 160 | | | 161 | 9.36k | GET_DINSTANCE(handle); | 162 | 9.36k | if ((this->init & DECOMPRESS) == 0) | 163 | 9.36k | THROW("Instance has not been initialized for decompression"); | 164 | | | 165 | 9.36k | if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || pitch < 0 || | 166 | 9.36k | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) | 167 | 9.36k | THROW("Invalid argument"); | 168 | | | 169 | 9.36k | if (this->scanLimit) { | 170 | 9.36k | memset(&progress, 0, sizeof(struct my_progress_mgr)); | 171 | 9.36k | progress.pub.progress_monitor = my_progress_monitor; | 172 | 9.36k | progress.this = this; | 173 | 9.36k | dinfo->progress = &progress.pub; | 174 | 9.36k | } else | 175 | 0 | dinfo->progress = NULL; | 176 | | | 177 | 9.36k | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 178 | | | 179 | 9.36k | if (setjmp(this->jerr.setjmp_buffer)) { | 180 | | /* If we get here, the JPEG code has signaled an error. */ | 181 | 6.15k | retval = -1; goto bailout; | 182 | 6.15k | } | 183 | | | 184 | 9.36k | if (dinfo->global_state <= DSTATE_INHEADER) { | 185 | 9.36k | jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); | 186 | 9.36k | jpeg_read_header(dinfo, TRUE); | 187 | 9.36k | } | 188 | 3.21k | setDecompParameters(this); | 189 | | #if BITS_IN_JSAMPLE == 12 | 190 | | if (this->precision == 8 && !this->lossless) | 191 | | dinfo->data_precision = 12; | 192 | | #endif | 193 | 3.21k | if (this->maxPixels && | 194 | 0 | (unsigned long long)this->jpegWidth * this->jpegHeight > | 195 | 0 | (unsigned long long)this->maxPixels) | 196 | 3.21k | THROW("Image is too large"); | 197 | 3.21k | this->dinfo.out_color_space = pf2cs[pixelFormat]; | 198 | | #if BITS_IN_JSAMPLE != 16 | 199 | | scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); | 200 | | #endif | 201 | 3.21k | dinfo->do_fancy_upsampling = !this->fastUpsample; | 202 | 3.21k | this->dinfo.dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; | 203 | | | 204 | 3.21k | dinfo->scale_num = this->scalingFactor.num; | 205 | 3.21k | dinfo->scale_denom = this->scalingFactor.denom; | 206 | | | 207 | 3.21k | jpeg_start_decompress(dinfo); | 208 | | | 209 | | #if BITS_IN_JSAMPLE != 16 | 210 | | if (this->croppingRegion.x != 0 || | 211 | | (this->croppingRegion.w != 0 && this->croppingRegion.w != scaledWidth)) { | 212 | | JDIMENSION crop_x = this->croppingRegion.x; | 213 | | JDIMENSION crop_w = this->croppingRegion.w; | 214 | | | 215 | | _jpeg_crop_scanline(dinfo, &crop_x, &crop_w); | 216 | | if ((int)crop_x != this->croppingRegion.x) | 217 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 218 | | "actual (%d) cropping region left boundary", | 219 | | this->croppingRegion.x, (int)crop_x); | 220 | | if ((int)crop_w != this->croppingRegion.w) | 221 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 222 | | "actual (%d) cropping region width", | 223 | | this->croppingRegion.w, (int)crop_w); | 224 | | } | 225 | | #endif | 226 | | | 227 | 3.21k | if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; | 228 | | | 229 | 3.21k | croppedHeight = dinfo->output_height; | 230 | | #if BITS_IN_JSAMPLE != 16 | 231 | | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) | 232 | | croppedHeight = this->croppingRegion.h; | 233 | | #endif | 234 | 3.21k | if ((row_pointer = | 235 | 3.21k | (_JSAMPROW *)malloc(sizeof(_JSAMPROW) * croppedHeight)) == NULL) | 236 | 3.21k | THROW("Memory allocation failure"); | 237 | 3.21k | if (setjmp(this->jerr.setjmp_buffer)) { | 238 | | /* If we get here, the JPEG code has signaled an error. */ | 239 | 2.43k | retval = -1; goto bailout; | 240 | 2.43k | } | 241 | 23.5M | for (i = 0; i < (int)croppedHeight; i++) { | 242 | 23.5M | if (this->bottomUp) | 243 | 8.37M | row_pointer[i] = &dstBuf[(croppedHeight - i - 1) * (size_t)pitch]; | 244 | 15.1M | else | 245 | 15.1M | row_pointer[i] = &dstBuf[i * (size_t)pitch]; | 246 | 23.5M | } | 247 | | | 248 | | #if BITS_IN_JSAMPLE != 16 | 249 | | if (this->croppingRegion.y != 0 || this->croppingRegion.h != 0) { | 250 | | if (this->croppingRegion.y != 0) { | 251 | | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, this->croppingRegion.y); | 252 | | | 253 | | if ((int)lines != this->croppingRegion.y) | 254 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 255 | | "actual (%d) cropping region upper boundary", | 256 | | this->croppingRegion.y, (int)lines); | 257 | | } | 258 | | while ((int)dinfo->output_scanline < | 259 | | this->croppingRegion.y + this->croppingRegion.h) | 260 | | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline - | 261 | | this->croppingRegion.y], | 262 | | this->croppingRegion.y + this->croppingRegion.h - | 263 | | dinfo->output_scanline); | 264 | | if (this->croppingRegion.y + this->croppingRegion.h != | 265 | | (int)dinfo->output_height) { | 266 | | JDIMENSION lines = _jpeg_skip_scanlines(dinfo, dinfo->output_height - | 267 | | this->croppingRegion.y - | 268 | | this->croppingRegion.h); | 269 | | | 270 | | if (lines != dinfo->output_height - this->croppingRegion.y - | 271 | | this->croppingRegion.h) | 272 | | THROWI("Unexplained mismatch between specified (%d) and\n" | 273 | | "actual (%d) cropping region lower boundary", | 274 | | this->croppingRegion.y + this->croppingRegion.h, | 275 | | (int)(dinfo->output_height - lines)); | 276 | | } | 277 | | } else | 278 | | #endif | 279 | 784 | { | 280 | 2.32M | while (dinfo->output_scanline < dinfo->output_height) | 281 | 2.32M | _jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], | 282 | 2.32M | dinfo->output_height - dinfo->output_scanline); | 283 | 784 | } | 284 | 784 | jpeg_finish_decompress(dinfo); | 285 | | | 286 | 9.36k | bailout: | 287 | 9.36k | if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); | 288 | 9.36k | free(row_pointer); | 289 | 9.36k | if (this->jerr.warning) retval = -1; | 290 | 9.36k | return retval; | 291 | 784 | } |
|
292 | | |
293 | | |
294 | | /*************************** Packed-Pixel Image I/O **************************/ |
295 | | |
296 | | /* TurboJPEG 3.0+ */ |
297 | | #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
298 | | static |
299 | | #endif |
300 | | _JSAMPLE *GET_NAME(_tj3LoadImageFromFileHandle, BITS_IN_JSAMPLE) |
301 | | (tjhandle handle, FILE *file, int *width, int align, int *height, |
302 | | int *pixelFormat) |
303 | 222k | { |
304 | 222k | static const char FUNCTION_NAME[] = |
305 | 222k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); |
306 | | |
307 | 222k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) |
308 | | |
309 | 222k | int retval = 0, tempc; |
310 | 222k | size_t pitch; |
311 | 222k | tjhandle handle2 = NULL; |
312 | 222k | tjinstance *this2; |
313 | 222k | j_compress_ptr cinfo = NULL; |
314 | 222k | cjpeg_source_ptr src; |
315 | 222k | _JSAMPLE *dstBuf = NULL; |
316 | 222k | boolean invert; |
317 | | |
318 | 222k | GET_TJINSTANCE(handle, NULL) |
319 | | |
320 | 222k | if (!file || !width || align < 1 || !height || !pixelFormat || |
321 | 222k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) |
322 | 222k | THROW("Invalid argument"); |
323 | 222k | if ((align & (align - 1)) != 0) |
324 | 222k | THROW("Alignment must be a power of 2"); |
325 | | |
326 | | /* The instance handle passed to this function is used only for parameter |
327 | | retrieval. Create a new temporary instance to avoid interfering with the |
328 | | libjpeg state of the primary instance. */ |
329 | 222k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; |
330 | 222k | this2 = (tjinstance *)handle2; |
331 | 222k | cinfo = &this2->cinfo; |
332 | | |
333 | 222k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) |
334 | 0 | THROW_UNIX("Could not read input file") |
335 | 222k | else if (tempc == EOF) |
336 | 222k | THROW("Input file contains no data"); |
337 | | |
338 | 222k | if (setjmp(this2->jerr.setjmp_buffer)) { |
339 | | /* If we get here, the JPEG code has signaled an error. */ |
340 | 49.5k | retval = -1; goto bailout; |
341 | 49.5k | } |
342 | | |
343 | 172k | cinfo->data_precision = BITS_IN_JSAMPLE; |
344 | 172k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; |
345 | 172k | else cinfo->in_color_space = pf2cs[*pixelFormat]; |
346 | 172k | if (tempc == 'B') { |
347 | 36.6k | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) |
348 | 36.6k | THROW("Could not initialize bitmap loader"); |
349 | 36.6k | invert = !this->bottomUp; |
350 | 179k | } else if (tempc == 'P') { |
351 | | #if BITS_IN_JSAMPLE == 8 |
352 | 88.6k | if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE) |
353 | | #else |
354 | 90.9k | if (this->precision >= BITS_IN_JSAMPLE - 3 && |
355 | 51.0k | this->precision <= BITS_IN_JSAMPLE) |
356 | 51.0k | #endif |
357 | 139k | cinfo->data_precision = this->precision; |
358 | 179k | if ((src = _jinit_read_ppm(cinfo)) == NULL) |
359 | 179k | THROW("Could not initialize PPM loader"); |
360 | 179k | invert = this->bottomUp; |
361 | 179k | } else |
362 | 18.4E | THROW("Unsupported file type"); |
363 | | |
364 | 216k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
365 | | |
366 | 216k | src->input_file = file; |
367 | | /* Refuse to load images larger than the specified size. */ |
368 | 216k | src->max_pixels = this->maxPixels; |
369 | 216k | (*src->start_input) (cinfo, src); |
370 | 216k | if (tempc == 'B') { |
371 | 12.3k | if (cinfo->X_density && cinfo->Y_density) { |
372 | 2.14k | this->xDensity = cinfo->X_density; |
373 | 2.14k | this->yDensity = cinfo->Y_density; |
374 | 2.14k | this->densityUnits = cinfo->density_unit; |
375 | 2.14k | } |
376 | 12.3k | } |
377 | 216k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); |
378 | | |
379 | 216k | *width = cinfo->image_width; *height = cinfo->image_height; |
380 | 216k | *pixelFormat = cs2pf[cinfo->in_color_space]; |
381 | | |
382 | 216k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); |
383 | 216k | if ( |
384 | | #if ULLONG_MAX > SIZE_MAX |
385 | | (unsigned long long)pitch * (unsigned long long)(*height) > |
386 | | (unsigned long long)((size_t)-1) || |
387 | | #endif |
388 | 216k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * |
389 | 216k | sizeof(_JSAMPLE))) == NULL) |
390 | 216k | THROW("Memory allocation failure"); |
391 | | |
392 | 216k | if (setjmp(this2->jerr.setjmp_buffer)) { |
393 | | /* If we get here, the JPEG code has signaled an error. */ |
394 | 73.4k | retval = -1; goto bailout; |
395 | 73.4k | } |
396 | | |
397 | 365M | while (cinfo->next_scanline < cinfo->image_height) { |
398 | 364M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); |
399 | | |
400 | 729M | for (i = 0; i < nlines; i++) { |
401 | 364M | _JSAMPLE *dstptr; |
402 | 364M | int row; |
403 | | |
404 | 364M | row = cinfo->next_scanline + i; |
405 | 364M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; |
406 | 279M | else dstptr = &dstBuf[row * pitch]; |
407 | 364M | memcpy(dstptr, src->_buffer[i], |
408 | 364M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); |
409 | 364M | } |
410 | 364M | cinfo->next_scanline += nlines; |
411 | 364M | } |
412 | | |
413 | 142k | (*src->finish_input) (cinfo, src); |
414 | | |
415 | 222k | bailout: |
416 | 222k | tj3Destroy(handle2); |
417 | 222k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } |
418 | 222k | return dstBuf; |
419 | | |
420 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ |
421 | | |
422 | | static const char ERROR_MSG[] = |
423 | | "16-bit data precision requires lossless JPEG,\n" |
424 | | "which was disabled at build time."; |
425 | | _JSAMPLE *retval = NULL; |
426 | | |
427 | | GET_TJINSTANCE(handle, NULL) |
428 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, |
429 | | ERROR_MSG); |
430 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) |
431 | | |
432 | | bailout: |
433 | | return retval; |
434 | | |
435 | | #endif |
436 | 142k | } _tj3LoadImageFromFileHandle8 Line | Count | Source | 303 | 127k | { | 304 | 127k | static const char FUNCTION_NAME[] = | 305 | 127k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 306 | | | 307 | 127k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) | 308 | | | 309 | 127k | int retval = 0, tempc; | 310 | 127k | size_t pitch; | 311 | 127k | tjhandle handle2 = NULL; | 312 | 127k | tjinstance *this2; | 313 | 127k | j_compress_ptr cinfo = NULL; | 314 | 127k | cjpeg_source_ptr src; | 315 | 127k | _JSAMPLE *dstBuf = NULL; | 316 | 127k | boolean invert; | 317 | | | 318 | 127k | GET_TJINSTANCE(handle, NULL) | 319 | | | 320 | 127k | if (!file || !width || align < 1 || !height || !pixelFormat || | 321 | 127k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 322 | 127k | THROW("Invalid argument"); | 323 | 127k | if ((align & (align - 1)) != 0) | 324 | 127k | THROW("Alignment must be a power of 2"); | 325 | | | 326 | | /* The instance handle passed to this function is used only for parameter | 327 | | retrieval. Create a new temporary instance to avoid interfering with the | 328 | | libjpeg state of the primary instance. */ | 329 | 127k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 330 | 127k | this2 = (tjinstance *)handle2; | 331 | 127k | cinfo = &this2->cinfo; | 332 | | | 333 | 127k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 334 | 0 | THROW_UNIX("Could not read input file") | 335 | 127k | else if (tempc == EOF) | 336 | 127k | THROW("Input file contains no data"); | 337 | | | 338 | 127k | if (setjmp(this2->jerr.setjmp_buffer)) { | 339 | | /* If we get here, the JPEG code has signaled an error. */ | 340 | 35.8k | retval = -1; goto bailout; | 341 | 35.8k | } | 342 | | | 343 | 91.5k | cinfo->data_precision = BITS_IN_JSAMPLE; | 344 | 91.5k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 345 | 91.5k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 346 | 91.5k | if (tempc == 'B') { | 347 | 36.2k | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 348 | 36.2k | THROW("Could not initialize bitmap loader"); | 349 | 36.2k | invert = !this->bottomUp; | 350 | 88.6k | } else if (tempc == 'P') { | 351 | 88.6k | #if BITS_IN_JSAMPLE == 8 | 352 | 88.6k | if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE) | 353 | | #else | 354 | | if (this->precision >= BITS_IN_JSAMPLE - 3 && | 355 | | this->precision <= BITS_IN_JSAMPLE) | 356 | | #endif | 357 | 88.6k | cinfo->data_precision = this->precision; | 358 | 88.6k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 359 | 88.6k | THROW("Could not initialize PPM loader"); | 360 | 88.6k | invert = this->bottomUp; | 361 | 88.6k | } else | 362 | 18.4E | THROW("Unsupported file type"); | 363 | | | 364 | 124k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 365 | | | 366 | 124k | src->input_file = file; | 367 | | /* Refuse to load images larger than the specified size. */ | 368 | 124k | src->max_pixels = this->maxPixels; | 369 | 124k | (*src->start_input) (cinfo, src); | 370 | 124k | if (tempc == 'B') { | 371 | 12.3k | if (cinfo->X_density && cinfo->Y_density) { | 372 | 2.14k | this->xDensity = cinfo->X_density; | 373 | 2.14k | this->yDensity = cinfo->Y_density; | 374 | 2.14k | this->densityUnits = cinfo->density_unit; | 375 | 2.14k | } | 376 | 12.3k | } | 377 | 124k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 378 | | | 379 | 124k | *width = cinfo->image_width; *height = cinfo->image_height; | 380 | 124k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 381 | | | 382 | 124k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 383 | 124k | if ( | 384 | | #if ULLONG_MAX > SIZE_MAX | 385 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 386 | | (unsigned long long)((size_t)-1) || | 387 | | #endif | 388 | 124k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 389 | 124k | sizeof(_JSAMPLE))) == NULL) | 390 | 124k | THROW("Memory allocation failure"); | 391 | | | 392 | 124k | if (setjmp(this2->jerr.setjmp_buffer)) { | 393 | | /* If we get here, the JPEG code has signaled an error. */ | 394 | 37.6k | retval = -1; goto bailout; | 395 | 37.6k | } | 396 | | | 397 | 201M | while (cinfo->next_scanline < cinfo->image_height) { | 398 | 201M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 399 | | | 400 | 403M | for (i = 0; i < nlines; i++) { | 401 | 201M | _JSAMPLE *dstptr; | 402 | 201M | int row; | 403 | | | 404 | 201M | row = cinfo->next_scanline + i; | 405 | 201M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 406 | 140M | else dstptr = &dstBuf[row * pitch]; | 407 | 201M | memcpy(dstptr, src->_buffer[i], | 408 | 201M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 409 | 201M | } | 410 | 201M | cinfo->next_scanline += nlines; | 411 | 201M | } | 412 | | | 413 | 87.2k | (*src->finish_input) (cinfo, src); | 414 | | | 415 | 127k | bailout: | 416 | 127k | tj3Destroy(handle2); | 417 | 127k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 418 | 127k | return dstBuf; | 419 | | | 420 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ | 421 | | | 422 | | static const char ERROR_MSG[] = | 423 | | "16-bit data precision requires lossless JPEG,\n" | 424 | | "which was disabled at build time."; | 425 | | _JSAMPLE *retval = NULL; | 426 | | | 427 | | GET_TJINSTANCE(handle, NULL) | 428 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, | 429 | | ERROR_MSG); | 430 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) | 431 | | | 432 | | bailout: | 433 | | return retval; | 434 | | | 435 | | #endif | 436 | 87.2k | } |
_tj3LoadImageFromFileHandle12 Line | Count | Source | 303 | 68.3k | { | 304 | 68.3k | static const char FUNCTION_NAME[] = | 305 | 68.3k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 306 | | | 307 | 68.3k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) | 308 | | | 309 | 68.3k | int retval = 0, tempc; | 310 | 68.3k | size_t pitch; | 311 | 68.3k | tjhandle handle2 = NULL; | 312 | 68.3k | tjinstance *this2; | 313 | 68.3k | j_compress_ptr cinfo = NULL; | 314 | 68.3k | cjpeg_source_ptr src; | 315 | 68.3k | _JSAMPLE *dstBuf = NULL; | 316 | 68.3k | boolean invert; | 317 | | | 318 | 68.3k | GET_TJINSTANCE(handle, NULL) | 319 | | | 320 | 68.3k | if (!file || !width || align < 1 || !height || !pixelFormat || | 321 | 68.3k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 322 | 68.3k | THROW("Invalid argument"); | 323 | 68.3k | if ((align & (align - 1)) != 0) | 324 | 68.3k | THROW("Alignment must be a power of 2"); | 325 | | | 326 | | /* The instance handle passed to this function is used only for parameter | 327 | | retrieval. Create a new temporary instance to avoid interfering with the | 328 | | libjpeg state of the primary instance. */ | 329 | 68.3k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 330 | 68.3k | this2 = (tjinstance *)handle2; | 331 | 68.3k | cinfo = &this2->cinfo; | 332 | | | 333 | 68.3k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 334 | 0 | THROW_UNIX("Could not read input file") | 335 | 68.3k | else if (tempc == EOF) | 336 | 68.3k | THROW("Input file contains no data"); | 337 | | | 338 | 68.3k | if (setjmp(this2->jerr.setjmp_buffer)) { | 339 | | /* If we get here, the JPEG code has signaled an error. */ | 340 | 9.39k | retval = -1; goto bailout; | 341 | 9.39k | } | 342 | | | 343 | 58.9k | cinfo->data_precision = BITS_IN_JSAMPLE; | 344 | 58.9k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 345 | 58.9k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 346 | 58.9k | if (tempc == 'B') { | 347 | 224 | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 348 | 224 | THROW("Could not initialize bitmap loader"); | 349 | 224 | invert = !this->bottomUp; | 350 | 65.4k | } else if (tempc == 'P') { | 351 | | #if BITS_IN_JSAMPLE == 8 | 352 | | if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE) | 353 | | #else | 354 | 65.4k | if (this->precision >= BITS_IN_JSAMPLE - 3 && | 355 | 25.5k | this->precision <= BITS_IN_JSAMPLE) | 356 | 25.5k | #endif | 357 | 25.5k | cinfo->data_precision = this->precision; | 358 | 65.4k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 359 | 65.4k | THROW("Could not initialize PPM loader"); | 360 | 65.4k | invert = this->bottomUp; | 361 | 65.4k | } else | 362 | 18.4E | THROW("Unsupported file type"); | 363 | | | 364 | 65.6k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 365 | | | 366 | 65.6k | src->input_file = file; | 367 | | /* Refuse to load images larger than the specified size. */ | 368 | 65.6k | src->max_pixels = this->maxPixels; | 369 | 65.6k | (*src->start_input) (cinfo, src); | 370 | 65.6k | if (tempc == 'B') { | 371 | 0 | if (cinfo->X_density && cinfo->Y_density) { | 372 | 0 | this->xDensity = cinfo->X_density; | 373 | 0 | this->yDensity = cinfo->Y_density; | 374 | 0 | this->densityUnits = cinfo->density_unit; | 375 | 0 | } | 376 | 0 | } | 377 | 65.6k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 378 | | | 379 | 65.6k | *width = cinfo->image_width; *height = cinfo->image_height; | 380 | 65.6k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 381 | | | 382 | 65.6k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 383 | 65.6k | if ( | 384 | | #if ULLONG_MAX > SIZE_MAX | 385 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 386 | | (unsigned long long)((size_t)-1) || | 387 | | #endif | 388 | 65.6k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 389 | 65.6k | sizeof(_JSAMPLE))) == NULL) | 390 | 65.6k | THROW("Memory allocation failure"); | 391 | | | 392 | 65.6k | if (setjmp(this2->jerr.setjmp_buffer)) { | 393 | | /* If we get here, the JPEG code has signaled an error. */ | 394 | 24.0k | retval = -1; goto bailout; | 395 | 24.0k | } | 396 | | | 397 | 129M | while (cinfo->next_scanline < cinfo->image_height) { | 398 | 129M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 399 | | | 400 | 258M | for (i = 0; i < nlines; i++) { | 401 | 128M | _JSAMPLE *dstptr; | 402 | 128M | int row; | 403 | | | 404 | 128M | row = cinfo->next_scanline + i; | 405 | 128M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 406 | 110M | else dstptr = &dstBuf[row * pitch]; | 407 | 128M | memcpy(dstptr, src->_buffer[i], | 408 | 128M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 409 | 128M | } | 410 | 129M | cinfo->next_scanline += nlines; | 411 | 129M | } | 412 | | | 413 | 41.6k | (*src->finish_input) (cinfo, src); | 414 | | | 415 | 68.3k | bailout: | 416 | 68.3k | tj3Destroy(handle2); | 417 | 68.3k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 418 | 68.3k | return dstBuf; | 419 | | | 420 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ | 421 | | | 422 | | static const char ERROR_MSG[] = | 423 | | "16-bit data precision requires lossless JPEG,\n" | 424 | | "which was disabled at build time."; | 425 | | _JSAMPLE *retval = NULL; | 426 | | | 427 | | GET_TJINSTANCE(handle, NULL) | 428 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, | 429 | | ERROR_MSG); | 430 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) | 431 | | | 432 | | bailout: | 433 | | return retval; | 434 | | | 435 | | #endif | 436 | 41.6k | } |
_tj3LoadImageFromFileHandle16 Line | Count | Source | 303 | 26.4k | { | 304 | 26.4k | static const char FUNCTION_NAME[] = | 305 | 26.4k | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); | 306 | | | 307 | 26.4k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) | 308 | | | 309 | 26.4k | int retval = 0, tempc; | 310 | 26.4k | size_t pitch; | 311 | 26.4k | tjhandle handle2 = NULL; | 312 | 26.4k | tjinstance *this2; | 313 | 26.4k | j_compress_ptr cinfo = NULL; | 314 | 26.4k | cjpeg_source_ptr src; | 315 | 26.4k | _JSAMPLE *dstBuf = NULL; | 316 | 26.4k | boolean invert; | 317 | | | 318 | 26.4k | GET_TJINSTANCE(handle, NULL) | 319 | | | 320 | 26.4k | if (!file || !width || align < 1 || !height || !pixelFormat || | 321 | 26.4k | *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) | 322 | 26.4k | THROW("Invalid argument"); | 323 | 26.4k | if ((align & (align - 1)) != 0) | 324 | 26.4k | THROW("Alignment must be a power of 2"); | 325 | | | 326 | | /* The instance handle passed to this function is used only for parameter | 327 | | retrieval. Create a new temporary instance to avoid interfering with the | 328 | | libjpeg state of the primary instance. */ | 329 | 26.4k | if ((handle2 = tj3Init(TJINIT_COMPRESS)) == NULL) return NULL; | 330 | 26.4k | this2 = (tjinstance *)handle2; | 331 | 26.4k | cinfo = &this2->cinfo; | 332 | | | 333 | 26.4k | if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) | 334 | 0 | THROW_UNIX("Could not read input file") | 335 | 26.4k | else if (tempc == EOF) | 336 | 26.4k | THROW("Input file contains no data"); | 337 | | | 338 | 26.4k | if (setjmp(this2->jerr.setjmp_buffer)) { | 339 | | /* If we get here, the JPEG code has signaled an error. */ | 340 | 4.37k | retval = -1; goto bailout; | 341 | 4.37k | } | 342 | | | 343 | 22.0k | cinfo->data_precision = BITS_IN_JSAMPLE; | 344 | 22.0k | if (*pixelFormat == TJPF_UNKNOWN) cinfo->in_color_space = JCS_UNKNOWN; | 345 | 22.0k | else cinfo->in_color_space = pf2cs[*pixelFormat]; | 346 | 22.0k | if (tempc == 'B') { | 347 | 105 | if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) | 348 | 105 | THROW("Could not initialize bitmap loader"); | 349 | 105 | invert = !this->bottomUp; | 350 | 25.4k | } else if (tempc == 'P') { | 351 | | #if BITS_IN_JSAMPLE == 8 | 352 | | if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE) | 353 | | #else | 354 | 25.4k | if (this->precision >= BITS_IN_JSAMPLE - 3 && | 355 | 25.4k | this->precision <= BITS_IN_JSAMPLE) | 356 | 25.4k | #endif | 357 | 25.4k | cinfo->data_precision = this->precision; | 358 | 25.4k | if ((src = _jinit_read_ppm(cinfo)) == NULL) | 359 | 25.4k | THROW("Could not initialize PPM loader"); | 360 | 25.4k | invert = this->bottomUp; | 361 | 25.4k | } else | 362 | 18.4E | THROW("Unsupported file type"); | 363 | | | 364 | 25.5k | cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; | 365 | | | 366 | 25.5k | src->input_file = file; | 367 | | /* Refuse to load images larger than the specified size. */ | 368 | 25.5k | src->max_pixels = this->maxPixels; | 369 | 25.5k | (*src->start_input) (cinfo, src); | 370 | 25.5k | if (tempc == 'B') { | 371 | 0 | if (cinfo->X_density && cinfo->Y_density) { | 372 | 0 | this->xDensity = cinfo->X_density; | 373 | 0 | this->yDensity = cinfo->Y_density; | 374 | 0 | this->densityUnits = cinfo->density_unit; | 375 | 0 | } | 376 | 0 | } | 377 | 25.5k | (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo); | 378 | | | 379 | 25.5k | *width = cinfo->image_width; *height = cinfo->image_height; | 380 | 25.5k | *pixelFormat = cs2pf[cinfo->in_color_space]; | 381 | | | 382 | 25.5k | pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); | 383 | 25.5k | if ( | 384 | | #if ULLONG_MAX > SIZE_MAX | 385 | | (unsigned long long)pitch * (unsigned long long)(*height) > | 386 | | (unsigned long long)((size_t)-1) || | 387 | | #endif | 388 | 25.5k | (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * | 389 | 25.5k | sizeof(_JSAMPLE))) == NULL) | 390 | 25.5k | THROW("Memory allocation failure"); | 391 | | | 392 | 25.5k | if (setjmp(this2->jerr.setjmp_buffer)) { | 393 | | /* If we get here, the JPEG code has signaled an error. */ | 394 | 11.8k | retval = -1; goto bailout; | 395 | 11.8k | } | 396 | | | 397 | 34.0M | while (cinfo->next_scanline < cinfo->image_height) { | 398 | 34.0M | int i, nlines = (*src->get_pixel_rows) (cinfo, src); | 399 | | | 400 | 68.1M | for (i = 0; i < nlines; i++) { | 401 | 34.0M | _JSAMPLE *dstptr; | 402 | 34.0M | int row; | 403 | | | 404 | 34.0M | row = cinfo->next_scanline + i; | 405 | 34.0M | if (invert) dstptr = &dstBuf[((*height) - row - 1) * pitch]; | 406 | 29.2M | else dstptr = &dstBuf[row * pitch]; | 407 | 34.0M | memcpy(dstptr, src->_buffer[i], | 408 | 34.0M | (*width) * tjPixelSize[*pixelFormat] * sizeof(_JSAMPLE)); | 409 | 34.0M | } | 410 | 34.0M | cinfo->next_scanline += nlines; | 411 | 34.0M | } | 412 | | | 413 | 13.7k | (*src->finish_input) (cinfo, src); | 414 | | | 415 | 26.4k | bailout: | 416 | 26.4k | tj3Destroy(handle2); | 417 | 26.4k | if (retval < 0) { free(dstBuf); dstBuf = NULL; } | 418 | 26.4k | return dstBuf; | 419 | | | 420 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ | 421 | | | 422 | | static const char ERROR_MSG[] = | 423 | | "16-bit data precision requires lossless JPEG,\n" | 424 | | "which was disabled at build time."; | 425 | | _JSAMPLE *retval = NULL; | 426 | | | 427 | | GET_TJINSTANCE(handle, NULL) | 428 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, | 429 | | ERROR_MSG); | 430 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) | 431 | | | 432 | | bailout: | 433 | | return retval; | 434 | | | 435 | | #endif | 436 | 13.7k | } |
|
437 | | |
438 | | DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE) |
439 | | (tjhandle handle, const char *filename, int *width, int align, int *height, |
440 | | int *pixelFormat) |
441 | 0 | { |
442 | 0 | static const char FUNCTION_NAME[] = |
443 | 0 | GET_STRING(tj3LoadImage, BITS_IN_JSAMPLE); |
444 | |
|
445 | 0 | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) |
446 | |
|
447 | 0 | int retval = 0; |
448 | 0 | _JSAMPLE *dstBuf = NULL; |
449 | 0 | FILE *file = NULL; |
450 | |
|
451 | 0 | GET_TJINSTANCE(handle, NULL) |
452 | |
|
453 | 0 | if (!filename) |
454 | 0 | THROW("Invalid argument"); |
455 | |
|
456 | | #ifdef _MSC_VER |
457 | | if (fopen_s(&file, filename, "rb") || file == NULL) |
458 | | #else |
459 | 0 | if ((file = fopen(filename, "rb")) == NULL) |
460 | 0 | #endif |
461 | 0 | THROW_UNIX("Cannot open input file"); |
462 | |
|
463 | 0 | dstBuf = GET_NAME(_tj3LoadImageFromFileHandle, BITS_IN_JSAMPLE) |
464 | 0 | (handle, file, width, align, height, pixelFormat); |
465 | |
|
466 | 0 | bailout: |
467 | 0 | if (file) fclose(file); |
468 | 0 | if (retval < 0) { free(dstBuf); dstBuf = NULL; } |
469 | 0 | return dstBuf; |
470 | |
|
471 | | #else /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */ |
472 | | |
473 | | static const char ERROR_MSG[] = |
474 | | "16-bit data precision requires lossless JPEG,\n" |
475 | | "which was disabled at build time."; |
476 | | _JSAMPLE *retval = NULL; |
477 | | |
478 | | GET_TJINSTANCE(handle, NULL) |
479 | | SNPRINTF(this->errStr, JMSG_LENGTH_MAX, "%s(): %s", FUNCTION_NAME, |
480 | | ERROR_MSG); |
481 | | this->isInstanceError = TRUE; THROWG(ERROR_MSG, NULL) |
482 | | |
483 | | bailout: |
484 | | return retval; |
485 | | |
486 | | #endif |
487 | 0 | } Unexecuted instantiation: tj3LoadImage8 Unexecuted instantiation: tj3LoadImage12 Unexecuted instantiation: tj3LoadImage16 |
488 | | |
489 | | |
490 | | /* TurboJPEG 3.0+ */ |
491 | | DLLEXPORT int GET_NAME(tj3SaveImage, BITS_IN_JSAMPLE) |
492 | | (tjhandle handle, const char *filename, const _JSAMPLE *buffer, int width, |
493 | | int pitch, int height, int pixelFormat) |
494 | 0 | { |
495 | 0 | static const char FUNCTION_NAME[] = |
496 | 0 | GET_STRING(tj3SaveImage, BITS_IN_JSAMPLE); |
497 | 0 | int retval = 0; |
498 | |
|
499 | 0 | #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) |
500 | |
|
501 | 0 | tjhandle handle2 = NULL; |
502 | 0 | tjinstance *this2; |
503 | 0 | j_decompress_ptr dinfo = NULL; |
504 | 0 | djpeg_dest_ptr dst; |
505 | 0 | FILE *file = NULL; |
506 | 0 | const char *ptr = NULL; |
507 | 0 | boolean invert; |
508 | |
|
509 | 0 | GET_TJINSTANCE(handle, -1) |
510 | |
|
511 | 0 | if (!filename || !buffer || width < 1 || pitch < 0 || height < 1 || |
512 | 0 | pixelFormat < 0 || pixelFormat >= TJ_NUMPF) |
513 | 0 | THROW("Invalid argument"); |
514 | | |
515 | | /* The instance handle passed to this function is used only for parameter |
516 | | retrieval. Create a new temporary instance to avoid interfering with the |
517 | | libjpeg state of the primary instance. */ |
518 | 0 | if ((handle2 = tj3Init(TJINIT_DECOMPRESS)) == NULL) |
519 | 0 | return -1; |
520 | 0 | this2 = (tjinstance *)handle2; |
521 | 0 | dinfo = &this2->dinfo; |
522 | |
|
523 | | #ifdef _MSC_VER |
524 | | if (fopen_s(&file, filename, "wb") || file == NULL) |
525 | | #else |
526 | 0 | if ((file = fopen(filename, "wb")) == NULL) |
527 | 0 | #endif |
528 | 0 | THROW_UNIX("Cannot open output file"); |
529 | |
|
530 | 0 | if (setjmp(this2->jerr.setjmp_buffer)) { |
531 | | /* If we get here, the JPEG code has signaled an error. */ |
532 | 0 | retval = -1; goto bailout; |
533 | 0 | } |
534 | | |
535 | 0 | this2->dinfo.out_color_space = pf2cs[pixelFormat]; |
536 | 0 | dinfo->image_width = width; dinfo->image_height = height; |
537 | 0 | dinfo->global_state = DSTATE_READY; |
538 | 0 | dinfo->scale_num = dinfo->scale_denom = 1; |
539 | 0 | dinfo->data_precision = BITS_IN_JSAMPLE; |
540 | |
|
541 | 0 | ptr = strrchr(filename, '.'); |
542 | 0 | if (ptr && !strcasecmp(ptr, ".bmp")) { |
543 | 0 | if ((dst = jinit_write_bmp(dinfo, FALSE, FALSE)) == NULL) |
544 | 0 | THROW("Could not initialize bitmap writer"); |
545 | 0 | invert = !this->bottomUp; |
546 | 0 | dinfo->X_density = (UINT16)this->xDensity; |
547 | 0 | dinfo->Y_density = (UINT16)this->yDensity; |
548 | 0 | dinfo->density_unit = (UINT8)this->densityUnits; |
549 | 0 | } else { |
550 | | #if BITS_IN_JSAMPLE == 8 |
551 | 0 | if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE) |
552 | | #else |
553 | 0 | if (this->precision >= BITS_IN_JSAMPLE - 3 && |
554 | 0 | this->precision <= BITS_IN_JSAMPLE) |
555 | 0 | #endif |
556 | 0 | dinfo->data_precision = this->precision; |
557 | 0 | if ((dst = _jinit_write_ppm(dinfo)) == NULL) |
558 | 0 | THROW("Could not initialize PPM writer"); |
559 | 0 | invert = this->bottomUp; |
560 | 0 | } |
561 | | |
562 | 0 | dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; |
563 | |
|
564 | 0 | dst->output_file = file; |
565 | 0 | (*dst->start_output) (dinfo, dst); |
566 | 0 | (*dinfo->mem->realize_virt_arrays) ((j_common_ptr)dinfo); |
567 | |
|
568 | 0 | if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; |
569 | |
|
570 | 0 | while (dinfo->output_scanline < dinfo->output_height) { |
571 | 0 | _JSAMPLE *rowptr; |
572 | |
|
573 | 0 | if (invert) |
574 | 0 | rowptr = |
575 | 0 | (_JSAMPLE *)&buffer[(height - dinfo->output_scanline - 1) * pitch]; |
576 | 0 | else |
577 | 0 | rowptr = (_JSAMPLE *)&buffer[dinfo->output_scanline * pitch]; |
578 | 0 | memcpy(dst->_buffer[0], rowptr, |
579 | 0 | width * tjPixelSize[pixelFormat] * sizeof(_JSAMPLE)); |
580 | 0 | (*dst->put_pixel_rows) (dinfo, dst, 1); |
581 | 0 | dinfo->output_scanline++; |
582 | 0 | } |
583 | |
|
584 | 0 | (*dst->finish_output) (dinfo, dst); |
585 | |
|
586 | 0 | bailout: |
587 | 0 | tj3Destroy(handle2); |
588 | 0 | if (file) fclose(file); |
589 | 0 | return retval; |
590 | |
|
591 | | #else /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */ |
592 | | |
593 | | GET_TJINSTANCE(handle, -1) |
594 | | THROW("16-bit data precision requires lossless JPEG,\n" |
595 | | "which was disabled at build time.") |
596 | | bailout: |
597 | | return retval; |
598 | | |
599 | | #endif |
600 | 0 | } Unexecuted instantiation: tj3SaveImage8 Unexecuted instantiation: tj3SaveImage12 Unexecuted instantiation: tj3SaveImage16 |
601 | | |
602 | | |
603 | | #undef _JSAMPLE |
604 | | #undef _JSAMPROW |
605 | | #undef _buffer |
606 | | #undef _jinit_read_ppm |
607 | | #undef _jinit_write_ppm |
608 | | #undef _jpeg_crop_scanline |
609 | | #undef _jpeg_read_scanlines |
610 | | #undef _jpeg_skip_scanlines |
611 | | #undef _jpeg_write_scanlines |