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