Mercurial > hg > forks > libbpg
annotate bpgenc.c @ 26:a6e11adda0be
The format of JPEG EXIF data converted to BPG had an extraneous zero byte at
front .. this is probably not intentional. Fixed. Programs reading BPG files
may wish to compensate by checking for 0 before the "II" "TIFF" EXIF header.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 10 May 2017 14:26:20 +0300 |
parents | a6e6f87414ea |
children | 4aa0611ad85a |
rev | line source |
---|---|
0 | 1 /* |
2 * BPG encoder | |
3 * | |
4 * Copyright (c) 2014 Fabrice Bellard | |
5 * | |
6 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 * of this software and associated documentation files (the "Software"), to deal | |
8 * in the Software without restriction, including without limitation the rights | |
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 * copies of the Software, and to permit persons to whom the Software is | |
11 * furnished to do so, subject to the following conditions: | |
12 * | |
13 * The above copyright notice and this permission notice shall be included in | |
14 * all copies or substantial portions of the Software. | |
15 * | |
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 * THE SOFTWARE. | |
23 */ | |
24 #include <stdlib.h> | |
25 #include <stdio.h> | |
26 #include <string.h> | |
27 #include <inttypes.h> | |
28 #include <getopt.h> | |
29 #include <math.h> | |
30 #include <assert.h> | |
31 | |
32 #include <png.h> | |
33 #include <jpeglib.h> | |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
34 #include <tiffio.h> |
24
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
35 #ifdef HAVE_LIBEXIF |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
36 #include <exif-data.h> |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
37 #endif |
0 | 38 |
39 #include "bpgenc.h" | |
40 | |
41 typedef uint16_t PIXEL; | |
42 | |
43 static void put_ue(uint8_t **pp, uint32_t v); | |
44 | |
45 static inline int clamp_pix(int a, int pixel_max) | |
46 { | |
47 if (a < 0) | |
48 return 0; | |
49 else if (a > pixel_max) | |
50 return pixel_max; | |
51 else | |
52 return a; | |
53 } | |
54 | |
55 static inline int sub_mod_int(int a, int b, int m) | |
56 { | |
57 a -= b; | |
58 if (a < 0) | |
59 a += m; | |
60 return a; | |
61 } | |
62 | |
63 static inline int add_mod_int(int a, int b, int m) | |
64 { | |
65 a += b; | |
66 if (a >= m) | |
67 a -= m; | |
68 return a; | |
69 } | |
70 | |
71 typedef struct { | |
72 int c_shift; | |
73 int c_rnd; | |
74 int c_0_25, c_0_5, c_one; | |
75 int rgb_to_ycc[3 * 3]; | |
76 int y_one; | |
77 int y_offset; | |
78 int bit_depth; | |
79 int pixel_max; | |
80 int c_center; | |
81 } ColorConvertState; | |
82 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
83 static void convert_init(ColorConvertState *s, int in_bit_depth, |
0 | 84 int out_bit_depth, BPGColorSpaceEnum color_space, |
85 int limited_range) | |
86 { | |
87 double k_r, k_b, mult, mult_y, mult_c; | |
88 int in_pixel_max, out_pixel_max, c_shift, i; | |
89 double rgb_to_ycc[3 * 3]; | |
90 | |
91 /* XXX: could use one more bit */ | |
92 c_shift = 31 - out_bit_depth; | |
93 in_pixel_max = (1 << in_bit_depth) - 1; | |
94 out_pixel_max = (1 << out_bit_depth) - 1; | |
95 mult = (double)out_pixel_max * (1 << c_shift) / (double)in_pixel_max; | |
96 // printf("mult=%f c_shift=%d\n", mult, c_shift); | |
97 if (limited_range) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
98 mult_y = (double)(219 << (out_bit_depth - 8)) * (1 << c_shift) / |
0 | 99 (double)in_pixel_max; |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
100 mult_c = (double)(224 << (out_bit_depth - 8)) * (1 << c_shift) / |
0 | 101 (double)in_pixel_max; |
102 } else { | |
103 mult_y = mult; | |
104 mult_c = mult; | |
105 } | |
106 switch(color_space) { | |
107 case BPG_CS_YCbCr: | |
108 k_r = 0.299; | |
109 k_b = 0.114; | |
110 goto convert_ycc; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
111 |
0 | 112 case BPG_CS_YCbCr_BT709: |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
113 k_r = 0.2126; |
0 | 114 k_b = 0.0722; |
115 goto convert_ycc; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
116 |
0 | 117 case BPG_CS_YCbCr_BT2020: |
118 k_r = 0.2627; | |
119 k_b = 0.0593; | |
120 convert_ycc: | |
121 rgb_to_ycc[0] = k_r; | |
122 rgb_to_ycc[1] = 1 - k_r - k_b; | |
123 rgb_to_ycc[2] = k_b; | |
124 rgb_to_ycc[3] = -0.5 * k_r / (1 - k_b); | |
125 rgb_to_ycc[4] = -0.5 * (1 - k_r - k_b) / (1 - k_b); | |
126 rgb_to_ycc[5] = 0.5; | |
127 rgb_to_ycc[6] = 0.5; | |
128 rgb_to_ycc[7] = -0.5 * (1 - k_r - k_b) / (1 - k_r); | |
129 rgb_to_ycc[8] = -0.5 * k_b / (1 - k_r); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
130 |
0 | 131 for(i = 0; i < 3; i++) |
132 s->rgb_to_ycc[i] = lrint(rgb_to_ycc[i] * mult_y); | |
133 for(i = 3; i < 9; i++) | |
134 s->rgb_to_ycc[i] = lrint(rgb_to_ycc[i] * mult_c); | |
135 break; | |
136 case BPG_CS_YCgCo: | |
137 s->c_0_25 = lrint(0.25 * mult_y); | |
138 s->c_0_5 = lrint(0.5 * mult_y); | |
139 break; | |
140 default: | |
141 break; | |
142 } | |
143 | |
144 s->c_one = lrint(mult); | |
145 s->c_shift = c_shift; | |
146 s->c_rnd = (1 << (c_shift - 1)); | |
147 if (limited_range) { | |
148 s->y_offset = s->c_rnd + (16 << (c_shift + out_bit_depth - 8)); | |
149 s->y_one = lrint(mult_y); | |
150 } else { | |
151 s->y_offset = s->c_rnd; | |
152 s->y_one = s->c_one; | |
153 } | |
154 | |
155 s->bit_depth = out_bit_depth; | |
156 s->c_center = 1 << (out_bit_depth - 1); | |
157 s->pixel_max = out_pixel_max; | |
158 } | |
159 | |
160 /* 8 bit input */ | |
161 static void rgb24_to_ycc(ColorConvertState *s, | |
162 PIXEL *y_ptr, PIXEL *cb_ptr, PIXEL *cr_ptr, | |
163 const void *src1, int n, int incr) | |
164 { | |
165 const uint8_t *src = src1; | |
166 int i, r, g, b, c0, c1, c2, c3, c4, c5, c6, c7, c8, shift, rnd, center; | |
167 int pixel_max, y_offset; | |
168 | |
169 c0 = s->rgb_to_ycc[0]; | |
170 c1 = s->rgb_to_ycc[1]; | |
171 c2 = s->rgb_to_ycc[2]; | |
172 c3 = s->rgb_to_ycc[3]; | |
173 c4 = s->rgb_to_ycc[4]; | |
174 c5 = s->rgb_to_ycc[5]; | |
175 c6 = s->rgb_to_ycc[6]; | |
176 c7 = s->rgb_to_ycc[7]; | |
177 c8 = s->rgb_to_ycc[8]; | |
178 shift = s->c_shift; | |
179 rnd = s->c_rnd; | |
180 y_offset = s->y_offset; | |
181 center = s->c_center; | |
182 pixel_max = s->pixel_max; | |
183 for(i = 0; i < n; i++) { | |
184 r = src[0]; | |
185 g = src[1]; | |
186 b = src[2]; | |
187 y_ptr[i] = clamp_pix((c0 * r + c1 * g + c2 * b + | |
188 y_offset) >> shift, pixel_max); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
189 cb_ptr[i] = clamp_pix(((c3 * r + c4 * g + c5 * b + |
0 | 190 rnd) >> shift) + center, pixel_max); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
191 cr_ptr[i] = clamp_pix(((c6 * r + c7 * g + c8 * b + |
0 | 192 rnd) >> shift) + center, pixel_max); |
193 src += incr; | |
194 } | |
195 } | |
196 | |
197 static void rgb24_to_rgb(ColorConvertState *s, | |
198 PIXEL *y_ptr, PIXEL *cb_ptr, PIXEL *cr_ptr, | |
199 const void *src1, int n, int incr) | |
200 { | |
201 const uint8_t *src = src1; | |
202 int i, r, g, b, c, shift, rnd; | |
203 | |
204 c = s->y_one; | |
205 shift = s->c_shift; | |
206 rnd = s->y_offset; | |
207 for(i = 0; i < n; i++) { | |
208 r = src[0]; | |
209 g = src[1]; | |
210 b = src[2]; | |
211 y_ptr[i] = (c * g + rnd) >> shift; | |
212 cb_ptr[i] = (c * b + rnd) >> shift; | |
213 cr_ptr[i] = (c * r + rnd) >> shift; | |
214 src += incr; | |
215 } | |
216 } | |
217 | |
218 static void rgb24_to_ycgco(ColorConvertState *s, | |
219 PIXEL *y_ptr, PIXEL *cb_ptr, PIXEL *cr_ptr, | |
220 const void *src1, int n, int incr) | |
221 { | |
222 const uint8_t *src = src1; | |
223 int i, r, g, b, t1, t2, pixel_max, c_0_5, c_0_25, rnd, shift, center; | |
224 int y_offset; | |
225 | |
226 c_0_25 = s->c_0_25; | |
227 c_0_5 = s->c_0_5; | |
228 rnd = s->c_rnd; | |
229 shift = s->c_shift; | |
230 pixel_max = s->pixel_max; | |
231 center = s->c_center; | |
232 y_offset = s->y_offset; | |
233 for(i = 0; i < n; i++) { | |
234 r = src[0]; | |
235 g = src[1]; | |
236 b = src[2]; | |
237 t1 = c_0_5 * g; | |
238 t2 = c_0_25 * (r + b); | |
239 y_ptr[i] = clamp_pix((t1 + t2 + y_offset) >> shift, pixel_max); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
240 cb_ptr[i] = clamp_pix(((t1 - t2 + rnd) >> shift) + center, |
0 | 241 pixel_max); |
242 cr_ptr[i] = clamp_pix(((c_0_5 * (r - b) + | |
243 rnd) >> shift) + center, pixel_max); | |
244 src += incr; | |
245 } | |
246 } | |
247 | |
248 /* Note: used for alpha/W so no limited range */ | |
249 static void gray8_to_gray(ColorConvertState *s, | |
250 PIXEL *y_ptr, const uint8_t *src, int n, int incr) | |
251 { | |
252 int i, g, c, shift, rnd; | |
253 | |
254 c = s->c_one; | |
255 shift = s->c_shift; | |
256 rnd = s->c_rnd; | |
257 for(i = 0; i < n; i++) { | |
258 g = src[0]; | |
259 y_ptr[i] = (c * g + rnd) >> shift; | |
260 src += incr; | |
261 } | |
262 } | |
263 | |
264 static void luma8_to_gray(ColorConvertState *s, | |
265 PIXEL *y_ptr, const uint8_t *src, int n, int incr) | |
266 { | |
267 int i, g, c, shift, rnd; | |
268 | |
269 c = s->y_one; | |
270 shift = s->c_shift; | |
271 rnd = s->y_offset; | |
272 for(i = 0; i < n; i++) { | |
273 g = src[0]; | |
274 y_ptr[i] = (c * g + rnd) >> shift; | |
275 src += incr; | |
276 } | |
277 } | |
278 | |
279 /* 16 bit input */ | |
280 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
281 static void rgb48_to_ycc(ColorConvertState *s, |
0 | 282 PIXEL *y_ptr, PIXEL *cb_ptr, PIXEL *cr_ptr, |
283 const void *src1, int n, int incr) | |
284 { | |
285 const uint16_t *src = src1; | |
286 int i, r, g, b, c0, c1, c2, c3, c4, c5, c6, c7, c8, shift, rnd, center; | |
287 int pixel_max, y_offset; | |
288 | |
289 c0 = s->rgb_to_ycc[0]; | |
290 c1 = s->rgb_to_ycc[1]; | |
291 c2 = s->rgb_to_ycc[2]; | |
292 c3 = s->rgb_to_ycc[3]; | |
293 c4 = s->rgb_to_ycc[4]; | |
294 c5 = s->rgb_to_ycc[5]; | |
295 c6 = s->rgb_to_ycc[6]; | |
296 c7 = s->rgb_to_ycc[7]; | |
297 c8 = s->rgb_to_ycc[8]; | |
298 shift = s->c_shift; | |
299 rnd = s->c_rnd; | |
300 y_offset = s->y_offset; | |
301 center = s->c_center; | |
302 pixel_max = s->pixel_max; | |
303 for(i = 0; i < n; i++) { | |
304 r = src[0]; | |
305 g = src[1]; | |
306 b = src[2]; | |
307 y_ptr[i] = clamp_pix((c0 * r + c1 * g + c2 * b + | |
308 y_offset) >> shift, pixel_max); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
309 cb_ptr[i] = clamp_pix(((c3 * r + c4 * g + c5 * b + |
0 | 310 rnd) >> shift) + center, pixel_max); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
311 cr_ptr[i] = clamp_pix(((c6 * r + c7 * g + c8 * b + |
0 | 312 rnd) >> shift) + center, pixel_max); |
313 src += incr; | |
314 } | |
315 } | |
316 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
317 static void rgb48_to_ycgco(ColorConvertState *s, |
0 | 318 PIXEL *y_ptr, PIXEL *cb_ptr, PIXEL *cr_ptr, |
319 const void *src1, int n, int incr) | |
320 { | |
321 const uint16_t *src = src1; | |
322 int i, r, g, b, t1, t2, pixel_max, c_0_5, c_0_25, rnd, shift, center; | |
323 int y_offset; | |
324 | |
325 c_0_25 = s->c_0_25; | |
326 c_0_5 = s->c_0_5; | |
327 rnd = s->c_rnd; | |
328 y_offset = s->y_offset; | |
329 shift = s->c_shift; | |
330 pixel_max = s->pixel_max; | |
331 center = s->c_center; | |
332 for(i = 0; i < n; i++) { | |
333 r = src[0]; | |
334 g = src[1]; | |
335 b = src[2]; | |
336 t1 = c_0_5 * g; | |
337 t2 = c_0_25 * (r + b); | |
338 y_ptr[i] = clamp_pix((t1 + t2 + y_offset) >> shift, pixel_max); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
339 cb_ptr[i] = clamp_pix(((t1 - t2 + rnd) >> shift) + center, |
0 | 340 pixel_max); |
341 cr_ptr[i] = clamp_pix(((c_0_5 * (r - b) + | |
342 rnd) >> shift) + center, pixel_max); | |
343 src += incr; | |
344 } | |
345 } | |
346 | |
347 /* Note: use for alpha/W so no limited range */ | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
348 static void gray16_to_gray(ColorConvertState *s, |
0 | 349 PIXEL *y_ptr, const uint16_t *src, int n, int incr) |
350 { | |
351 int i, g, c, shift, rnd; | |
352 | |
353 c = s->c_one; | |
354 shift = s->c_shift; | |
355 rnd = s->c_rnd; | |
356 for(i = 0; i < n; i++) { | |
357 g = src[0]; | |
358 y_ptr[i] = (c * g + rnd) >> shift; | |
359 src += incr; | |
360 } | |
361 } | |
362 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
363 static void luma16_to_gray(ColorConvertState *s, |
0 | 364 PIXEL *y_ptr, const uint16_t *src, int n, int incr) |
365 { | |
366 int i, g, c, shift, rnd; | |
367 | |
368 c = s->y_one; | |
369 shift = s->c_shift; | |
370 rnd = s->y_offset; | |
371 for(i = 0; i < n; i++) { | |
372 g = src[0]; | |
373 y_ptr[i] = (c * g + rnd) >> shift; | |
374 src += incr; | |
375 } | |
376 } | |
377 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
378 static void rgb48_to_rgb(ColorConvertState *s, |
0 | 379 PIXEL *y_ptr, PIXEL *cb_ptr, PIXEL *cr_ptr, |
380 const void *src1, int n, int incr) | |
381 { | |
382 const uint16_t *src = src1; | |
383 | |
384 luma16_to_gray(s, y_ptr, src + 1, n, incr); | |
385 luma16_to_gray(s, cb_ptr, src + 2, n, incr); | |
386 luma16_to_gray(s, cr_ptr, src + 0, n, incr); | |
387 } | |
388 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
389 typedef void RGBConvertFunc(ColorConvertState *s, |
0 | 390 PIXEL *y_ptr, PIXEL *cb_ptr, PIXEL *cr_ptr, |
391 const void *src, int n, int incr); | |
392 | |
393 static RGBConvertFunc *rgb_to_cs[2][BPG_CS_COUNT] = { | |
394 { | |
395 rgb24_to_ycc, | |
396 rgb24_to_rgb, | |
397 rgb24_to_ycgco, | |
398 rgb24_to_ycc, | |
399 rgb24_to_ycc, | |
400 }, | |
401 { | |
402 rgb48_to_ycc, | |
403 rgb48_to_rgb, | |
404 rgb48_to_ycgco, | |
405 rgb48_to_ycc, | |
406 rgb48_to_ycc, | |
407 } | |
408 }; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
409 |
0 | 410 /* val = 1.0 - val */ |
411 static void gray_one_minus(ColorConvertState *s, PIXEL *y_ptr, int n) | |
412 { | |
413 int pixel_max = s->pixel_max; | |
414 int i; | |
415 | |
416 for(i = 0; i < n; i++) { | |
417 y_ptr[i] = pixel_max - y_ptr[i]; | |
418 } | |
419 } | |
420 | |
421 /* val = -val for chroma */ | |
422 static void gray_neg_c(ColorConvertState *s, PIXEL *y_ptr, int n) | |
423 { | |
424 int pixel_max = s->pixel_max; | |
425 int i, v; | |
426 | |
427 for(i = 0; i < n; i++) { | |
428 v = y_ptr[i]; | |
429 if (v == 0) | |
430 v = pixel_max; | |
431 else | |
432 v = pixel_max + 1 - v; | |
433 y_ptr[i] = v; | |
434 } | |
435 } | |
436 | |
437 | |
438 /* decimation */ | |
439 | |
440 /* phase = 0 */ | |
441 #define DP0TAPS2 7 | |
442 #define DP0TAPS (2 * DP0TAPS + 1) | |
443 #define DP0C0 64 | |
444 #define DP0C1 40 | |
445 #define DP0C3 (-11) | |
446 #define DP0C5 4 | |
447 #define DP0C7 (-1) | |
448 | |
449 /* phase = 0.5 */ | |
450 #define DP1TAPS2 5 | |
451 #define DP1TAPS (2 * DP1TAPS2) | |
452 #define DP1C0 57 | |
453 #define DP1C1 17 | |
454 #define DP1C2 (-8) | |
455 #define DP1C3 (-4) | |
456 #define DP1C4 2 | |
457 | |
458 #define DTAPS_MAX 7 | |
459 | |
460 /* chroma aligned with luma samples */ | |
461 static void decimate2p0_simple(PIXEL *dst, PIXEL *src, int n, int bit_depth) | |
462 { | |
463 int n2, i, pixel_max; | |
464 pixel_max = (1 << bit_depth) - 1; | |
465 n2 = (n + 1) / 2; | |
466 for(i = 0; i < n2; i++) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
467 dst[i] = clamp_pix(((src[-7] + src[7]) * DP0C7 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
468 (src[-5] + src[5]) * DP0C5 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
469 (src[-3] + src[3]) * DP0C3 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
470 (src[-1] + src[1]) * DP0C1 + |
0 | 471 src[0] * DP0C0 + 64) >> 7, pixel_max); |
472 src += 2; | |
473 } | |
474 } | |
475 | |
476 /* same with more precision and no saturation */ | |
477 static void decimate2p0_simple16(int16_t *dst, PIXEL *src, int n, int bit_depth) | |
478 { | |
479 int n2, i, shift, rnd; | |
480 shift = bit_depth - 7; | |
481 rnd = 1 << (shift - 1); | |
482 n2 = (n + 1) / 2; | |
483 for(i = 0; i < n2; i++) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
484 dst[i] = ((src[-7] + src[7]) * DP0C7 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
485 (src[-5] + src[5]) * DP0C5 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
486 (src[-3] + src[3]) * DP0C3 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
487 (src[-1] + src[1]) * DP0C1 + |
0 | 488 src[0] * DP0C0 + rnd) >> shift; |
489 src += 2; | |
490 } | |
491 } | |
492 | |
493 | |
494 /* chroma half way between luma samples */ | |
495 static void decimate2p1_simple(PIXEL *dst, PIXEL *src, int n, int bit_depth) | |
496 { | |
497 int n2, i, pixel_max; | |
498 pixel_max = (1 << bit_depth) - 1; | |
499 n2 = (n + 1) / 2; | |
500 for(i = 0; i < n2; i++) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
501 dst[i] = clamp_pix(((src[-4] + src[5]) * DP1C4 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
502 (src[-3] + src[4]) * DP1C3 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
503 (src[-2] + src[3]) * DP1C2 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
504 (src[-1] + src[2]) * DP1C1 + |
0 | 505 (src[0] + src[1]) * DP1C0 + 64) >> 7, pixel_max); |
506 src += 2; | |
507 } | |
508 } | |
509 | |
510 /* same with more precision and no saturation */ | |
511 static void decimate2p1_simple16(int16_t *dst, PIXEL *src, int n, int bit_depth) | |
512 { | |
513 int n2, i, shift, rnd; | |
514 shift = bit_depth - 7; | |
515 rnd = 1 << (shift - 1); | |
516 n2 = (n + 1) / 2; | |
517 for(i = 0; i < n2; i++) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
518 dst[i] = ((src[-4] + src[5]) * DP1C4 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
519 (src[-3] + src[4]) * DP1C3 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
520 (src[-2] + src[3]) * DP1C2 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
521 (src[-1] + src[2]) * DP1C1 + |
0 | 522 (src[0] + src[1]) * DP1C0 + rnd) >> shift; |
523 src += 2; | |
524 } | |
525 } | |
526 | |
527 static void decimate2_h(PIXEL *dst, PIXEL *src, int n, int bit_depth, int phase) | |
528 { | |
529 PIXEL *src1, v; | |
530 int d, i; | |
531 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
532 if (phase == 0) |
0 | 533 d = DP0TAPS2; |
534 else | |
535 d = DP1TAPS2; | |
536 /* add edge pixels */ | |
537 src1 = malloc(sizeof(PIXEL) * (n + 2 * d)); | |
538 v = src[0]; | |
539 for(i = 0; i < d; i++) | |
540 src1[i] = v; | |
541 memcpy(src1 + d, src, n * sizeof(PIXEL)); | |
542 v = src[n - 1]; | |
543 for(i = 0; i < d; i++) | |
544 src1[d + n + i] = v; | |
545 if (phase == 0) | |
546 decimate2p0_simple(dst, src1 + d, n, bit_depth); | |
547 else | |
548 decimate2p1_simple(dst, src1 + d, n, bit_depth); | |
549 free(src1); | |
550 } | |
551 | |
552 /* src1 is a temporary buffer of length n + 2 * DTAPS */ | |
553 static void decimate2_h16(int16_t *dst, PIXEL *src, int n, PIXEL *src1, | |
554 int bit_depth, int phase) | |
555 { | |
556 PIXEL v; | |
557 int d, i; | |
558 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
559 if (phase == 0) |
0 | 560 d = DP0TAPS2; |
561 else | |
562 d = DP1TAPS2; | |
563 /* add edge pixels */ | |
564 v = src[0]; | |
565 for(i = 0; i < d; i++) | |
566 src1[i] = v; | |
567 memcpy(src1 + d, src, n * sizeof(PIXEL)); | |
568 v = src[n - 1]; | |
569 for(i = 0; i < d; i++) | |
570 src1[d + n + i] = v; | |
571 if (phase == 0) | |
572 decimate2p0_simple16(dst, src1 + d, n, bit_depth); | |
573 else | |
574 decimate2p1_simple16(dst, src1 + d, n, bit_depth); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
575 |
0 | 576 } |
577 | |
578 static void decimate2_v(PIXEL *dst, int16_t **src, int pos, int n, | |
579 int bit_depth) | |
580 { | |
581 int16_t *src0, *src1, *src2, *src3, *src4, *src5, *srcm1, *srcm2, *srcm3, *srcm4; | |
582 int i, shift, offset, pixel_max; | |
583 | |
584 pos = sub_mod_int(pos, 4, DP1TAPS); | |
585 srcm4 = src[pos]; | |
586 pos = add_mod_int(pos, 1, DP1TAPS); | |
587 srcm3 = src[pos]; | |
588 pos = add_mod_int(pos, 1, DP1TAPS); | |
589 srcm2 = src[pos]; | |
590 pos = add_mod_int(pos, 1, DP1TAPS); | |
591 srcm1 = src[pos]; | |
592 pos = add_mod_int(pos, 1, DP1TAPS); | |
593 src0 = src[pos]; | |
594 pos = add_mod_int(pos, 1, DP1TAPS); | |
595 src1 = src[pos]; | |
596 pos = add_mod_int(pos, 1, DP1TAPS); | |
597 src2 = src[pos]; | |
598 pos = add_mod_int(pos, 1, DP1TAPS); | |
599 src3 = src[pos]; | |
600 pos = add_mod_int(pos, 1, DP1TAPS); | |
601 src4 = src[pos]; | |
602 pos = add_mod_int(pos, 1, DP1TAPS); | |
603 src5 = src[pos]; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
604 |
0 | 605 shift = 21 - bit_depth; |
606 offset = 1 << (shift - 1); | |
607 pixel_max = (1 << bit_depth) - 1; | |
608 for(i = 0; i < n; i++) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
609 dst[i] = clamp_pix(((srcm4[i] + src5[i]) * DP1C4 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
610 (srcm3[i] + src4[i]) * DP1C3 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
611 (srcm2[i] + src3[i]) * DP1C2 + |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
612 (srcm1[i] + src2[i]) * DP1C1 + |
0 | 613 (src0[i] + src1[i]) * DP1C0 + offset) >> shift, pixel_max); |
614 } | |
615 } | |
616 | |
617 /* Note: we do the horizontal decimation first to use less CPU cache */ | |
618 static void decimate2_hv(uint8_t *dst, int dst_linesize, | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
619 uint8_t *src, int src_linesize, |
0 | 620 int w, int h, int bit_depth, int h_phase) |
621 { | |
622 PIXEL *buf1; | |
623 int16_t *buf2[DP1TAPS]; | |
624 int w2, pos, i, y, y1, y2; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
625 |
0 | 626 w2 = (w + 1) / 2; |
627 | |
628 buf1 = malloc(sizeof(PIXEL) * (w + 2 * DTAPS_MAX)); | |
629 /* init line buffer */ | |
630 for(i = 0; i < DP1TAPS; i++) { | |
631 buf2[i] = malloc(sizeof(int16_t) * w2); | |
632 y = i; | |
633 if (y > DP1TAPS2) | |
634 y -= DP1TAPS; | |
635 if (y < 0) { | |
636 /* copy from first line */ | |
637 memcpy(buf2[i], buf2[0], sizeof(int16_t) * w2); | |
638 } else if (y >= h) { | |
639 /* copy from last line (only happens for small height) */ | |
640 memcpy(buf2[i], buf2[h - 1], sizeof(int16_t) * w2); | |
641 } else { | |
642 decimate2_h16(buf2[i], (PIXEL *)(src + src_linesize * y), w, | |
643 buf1, bit_depth, h_phase); | |
644 } | |
645 } | |
646 | |
647 for(y = 0; y < h; y++) { | |
648 pos = y % DP1TAPS; | |
649 if ((y & 1) == 0) { | |
650 /* filter one line */ | |
651 y2 = y >> 1; | |
652 decimate2_v((PIXEL *)(dst + y2 * dst_linesize), buf2, | |
653 pos, w2, bit_depth); | |
654 } | |
655 /* add a new line in the buffer */ | |
656 y1 = y + DP1TAPS2 + 1; | |
657 pos = add_mod_int(pos, DP1TAPS2 + 1, DP1TAPS); | |
658 if (y1 >= h) { | |
659 /* copy last line */ | |
660 memcpy(buf2[pos], buf2[sub_mod_int(pos, 1, DP1TAPS)], | |
661 sizeof(int16_t) * w2); | |
662 } else { | |
663 /* horizontally decimate new line */ | |
664 decimate2_h16(buf2[pos], (PIXEL *)(src + src_linesize * y1), w, | |
665 buf1, bit_depth, h_phase); | |
666 } | |
667 } | |
668 | |
669 for(i = 0; i < DP1TAPS; i++) | |
670 free(buf2[i]); | |
671 free(buf1); | |
672 } | |
673 | |
674 static void get_plane_res(Image *img, int *pw, int *ph, int i) | |
675 { | |
676 if (img->format == BPG_FORMAT_420 && (i == 1 || i == 2)) { | |
677 *pw = (img->w + 1) / 2; | |
678 *ph = (img->h + 1) / 2; | |
679 } else if (img->format == BPG_FORMAT_422 && (i == 1 || i == 2)) { | |
680 *pw = (img->w + 1) / 2; | |
681 *ph = img->h; | |
682 } else { | |
683 *pw = img->w; | |
684 *ph = img->h; | |
685 } | |
686 } | |
687 | |
688 #define W_PAD 16 | |
689 | |
690 Image *image_alloc(int w, int h, BPGImageFormatEnum format, int has_alpha, | |
691 BPGColorSpaceEnum color_space, int bit_depth) | |
692 { | |
693 Image *img; | |
694 int i, linesize, w1, h1, c_count; | |
695 | |
696 img = malloc(sizeof(Image)); | |
697 memset(img, 0, sizeof(*img)); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
698 |
0 | 699 img->w = w; |
700 img->h = h; | |
701 img->format = format; | |
702 img->has_alpha = has_alpha; | |
703 img->bit_depth = bit_depth; | |
704 img->color_space = color_space; | |
705 img->pixel_shift = 1; | |
706 img->c_h_phase = 1; | |
707 | |
708 if (img->format == BPG_FORMAT_GRAY) | |
709 c_count = 1; | |
710 else | |
711 c_count = 3; | |
712 if (has_alpha) | |
713 c_count++; | |
714 for(i = 0; i < c_count; i++) { | |
715 get_plane_res(img, &w1, &h1, i); | |
716 /* multiple of 16 pixels to add borders */ | |
717 w1 = (w1 + (W_PAD - 1)) & ~(W_PAD - 1); | |
718 h1 = (h1 + (W_PAD - 1)) & ~(W_PAD - 1); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
719 |
0 | 720 linesize = w1 << img->pixel_shift; |
721 img->data[i] = malloc(linesize * h1); | |
722 img->linesize[i] = linesize; | |
723 } | |
724 return img; | |
725 } | |
726 | |
727 void image_free(Image *img) | |
728 { | |
729 int i, c_count; | |
730 if (img->format == BPG_FORMAT_GRAY) | |
731 c_count = 1; | |
732 else | |
733 c_count = 3; | |
734 if (img->has_alpha) | |
735 c_count++; | |
736 for(i = 0; i < c_count; i++) | |
737 free(img->data[i]); | |
738 free(img); | |
739 } | |
740 | |
741 int image_ycc444_to_ycc422(Image *img, int h_phase) | |
742 { | |
743 uint8_t *data1; | |
744 int w1, h1, bpp, linesize1, i, y; | |
745 | |
746 if (img->format != BPG_FORMAT_444 || img->pixel_shift != 1) | |
747 return -1; | |
748 bpp = 2; | |
749 w1 = (img->w + 1) / 2; | |
750 w1 = (w1 + (W_PAD - 1)) & ~(W_PAD - 1); | |
751 h1 = (img->h + (W_PAD - 1)) & ~(W_PAD - 1); | |
752 linesize1 = bpp * w1; | |
753 for(i = 1; i <= 2; i++) { | |
754 data1 = malloc(linesize1 * h1); | |
755 for(y = 0; y < img->h; y++) { | |
756 decimate2_h((PIXEL *)(data1 + y * linesize1), | |
757 (PIXEL *)(img->data[i] + y * img->linesize[i]), | |
758 img->w, img->bit_depth, h_phase); | |
759 } | |
760 free(img->data[i]); | |
761 img->data[i] = data1; | |
762 img->linesize[i] = linesize1; | |
763 } | |
764 img->format = BPG_FORMAT_422; | |
765 img->c_h_phase = h_phase; | |
766 return 0; | |
767 } | |
768 | |
769 int image_ycc444_to_ycc420(Image *img, int h_phase) | |
770 { | |
771 uint8_t *data1; | |
772 int w1, h1, bpp, linesize1, i; | |
773 | |
774 if (img->format != BPG_FORMAT_444 || img->pixel_shift != 1) | |
775 return -1; | |
776 bpp = 2; | |
777 w1 = (img->w + 1) / 2; | |
778 h1 = (img->h + 1) / 2; | |
779 w1 = (w1 + (W_PAD - 1)) & ~(W_PAD - 1); | |
780 h1 = (h1 + (W_PAD - 1)) & ~(W_PAD - 1); | |
781 linesize1 = bpp * w1; | |
782 for(i = 1; i <= 2; i++) { | |
783 data1 = malloc(linesize1 * h1); | |
784 decimate2_hv(data1, linesize1, | |
785 img->data[i], img->linesize[i], | |
786 img->w, img->h, img->bit_depth, h_phase); | |
787 free(img->data[i]); | |
788 img->data[i] = data1; | |
789 img->linesize[i] = linesize1; | |
790 } | |
791 img->format = BPG_FORMAT_420; | |
792 img->c_h_phase = h_phase; | |
793 return 0; | |
794 } | |
795 | |
796 /* duplicate right and bottom samples so that the image has a width | |
797 and height multiple of cb_size (power of two) */ | |
798 void image_pad(Image *img, int cb_size) | |
799 { | |
800 int w1, h1, x, y, c_count, c_w, c_h, c_w1, c_h1, h_shift, v_shift, c_idx; | |
801 PIXEL *ptr, v, *ptr1; | |
802 | |
803 assert(img->pixel_shift == 1); | |
804 if (cb_size <= 1) | |
805 return; | |
806 w1 = (img->w + cb_size - 1) & ~(cb_size - 1); | |
807 h1 = (img->h + cb_size - 1) & ~(cb_size - 1); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
808 |
0 | 809 if (img->format == BPG_FORMAT_GRAY) |
810 c_count = 1; | |
811 else | |
812 c_count = 3; | |
813 if (img->has_alpha) | |
814 c_count++; | |
815 for(c_idx = 0; c_idx < c_count; c_idx++) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
816 if (img->format == BPG_FORMAT_420 && |
0 | 817 (c_idx == 1 || c_idx == 2)) { |
818 h_shift = 1; | |
819 v_shift = 1; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
820 } else if (img->format == BPG_FORMAT_422 && |
0 | 821 (c_idx == 1 || c_idx == 2)) { |
822 h_shift = 1; | |
823 v_shift = 0; | |
824 } else { | |
825 h_shift = 0; | |
826 v_shift = 0; | |
827 } | |
828 | |
829 c_w = (img->w + h_shift) >> h_shift; | |
830 c_h = (img->h + v_shift) >> v_shift; | |
831 c_w1 = w1 >> h_shift; | |
832 c_h1 = h1 >> v_shift; | |
833 | |
834 /* pad horizontally */ | |
835 for(y = 0; y < c_h; y++) { | |
836 ptr = (PIXEL *)(img->data[c_idx] + img->linesize[c_idx] * y); | |
837 v = ptr[c_w - 1]; | |
838 for(x = c_w; x < c_w1; x++) { | |
839 ptr[x] = v; | |
840 } | |
841 } | |
842 | |
843 /* pad vertically */ | |
844 ptr1 = (PIXEL *)(img->data[c_idx] + img->linesize[c_idx] * (c_h - 1)); | |
845 for(y = c_h; y < c_h1; y++) { | |
846 ptr = (PIXEL *)(img->data[c_idx] + img->linesize[c_idx] * y); | |
847 memcpy(ptr, ptr1, c_w1 * sizeof(PIXEL)); | |
848 } | |
849 } | |
850 img->w = w1; | |
851 img->h = h1; | |
852 } | |
853 | |
854 /* convert the 16 bit components to 8 bits */ | |
855 void image_convert16to8(Image *img) | |
856 { | |
857 int w, h, stride, y, x, c_count, i; | |
858 uint8_t *plane; | |
859 | |
860 if (img->bit_depth > 8 || img->pixel_shift != 1) | |
861 return; | |
862 if (img->format == BPG_FORMAT_GRAY) | |
863 c_count = 1; | |
864 else | |
865 c_count = 3; | |
866 if (img->has_alpha) | |
867 c_count++; | |
868 for(i = 0; i < c_count; i++) { | |
869 get_plane_res(img, &w, &h, i); | |
870 stride = w; | |
871 plane = malloc(stride * h); | |
872 for(y = 0; y < h; y++) { | |
873 const uint16_t *src; | |
874 uint8_t *dst; | |
875 dst = plane + stride * y; | |
876 src = (uint16_t *)(img->data[i] + img->linesize[i] * y); | |
877 for(x = 0; x < w; x++) | |
878 dst[x] = src[x]; | |
879 } | |
880 free(img->data[i]); | |
881 img->data[i] = plane; | |
882 img->linesize[i] = stride; | |
883 } | |
884 img->pixel_shift = 0; | |
885 } | |
886 | |
887 typedef struct BPGMetaData { | |
888 uint32_t tag; | |
889 uint8_t *buf; | |
890 int buf_len; | |
891 struct BPGMetaData *next; | |
892 } BPGMetaData; | |
893 | |
894 BPGMetaData *bpg_md_alloc(uint32_t tag) | |
895 { | |
896 BPGMetaData *md; | |
897 md = malloc(sizeof(BPGMetaData)); | |
898 memset(md, 0, sizeof(*md)); | |
899 md->tag = tag; | |
900 return md; | |
901 } | |
902 | |
903 void bpg_md_free(BPGMetaData *md) | |
904 { | |
905 BPGMetaData *md_next; | |
906 | |
907 while (md != NULL) { | |
908 md_next = md->next; | |
909 free(md->buf); | |
910 free(md); | |
911 md = md_next; | |
912 } | |
913 } | |
914 | |
17
91f27e9fdb60
Rename insert_md() and add_md_contents() to bpg_insert_md() and
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
915 void bpg_insert_md(BPGMetaData **list, BPGMetaData *node) |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
916 { |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
917 if (*list == NULL) |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
918 { |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
919 *list = node; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
920 node->next = NULL; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
921 } |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
922 else |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
923 { |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
924 node->next = *list; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
925 *list = node; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
926 } |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
927 } |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
928 |
17
91f27e9fdb60
Rename insert_md() and add_md_contents() to bpg_insert_md() and
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
929 int bpg_add_md_contents(BPGMetaData **list, const int tag, const size_t len, const void *buf) |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
930 { |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
931 BPGMetaData *md; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
932 |
19
a9a60da06ae3
Check for NULL buffer and 0 length of data in bpg_add_md_contents().
Matti Hamalainen <ccr@tnsp.org>
parents:
18
diff
changeset
|
933 if (buf == NULL || len == 0) |
a9a60da06ae3
Check for NULL buffer and 0 length of data in bpg_add_md_contents().
Matti Hamalainen <ccr@tnsp.org>
parents:
18
diff
changeset
|
934 return -2; |
a9a60da06ae3
Check for NULL buffer and 0 length of data in bpg_add_md_contents().
Matti Hamalainen <ccr@tnsp.org>
parents:
18
diff
changeset
|
935 |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
936 if ((md = bpg_md_alloc(tag)) == NULL) |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
937 goto err; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
938 |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
939 if ((md->buf = malloc(len)) == NULL) |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
940 goto err; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
941 |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
942 md->buf_len = len; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
943 memcpy(md->buf, buf, len); |
17
91f27e9fdb60
Rename insert_md() and add_md_contents() to bpg_insert_md() and
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
944 bpg_insert_md(list, md); |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
945 return 0; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
946 |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
947 err: |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
948 bpg_md_free(md); |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
949 return -1; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
950 } |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
951 |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
952 |
24
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
953 #ifdef HAVE_LIBEXIF |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
954 typedef struct |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
955 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
956 int tag; // Note: libtiff TIFF tags for EXIF are same as EXIF tags themselves |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
957 char *name; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
958 int ifd; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
959 } TIFFTagConvertInfo; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
960 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
961 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
962 static const TIFFTagConvertInfo tiff_tag_convert_table[] = |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
963 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
964 { TIFFTAG_ORIENTATION , "Orientation" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
965 { TIFFTAG_XRESOLUTION , "XResolution" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
966 { TIFFTAG_YRESOLUTION , "YResolution" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
967 { TIFFTAG_RESOLUTIONUNIT , "ResolutionUnit" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
968 { TIFFTAG_IMAGEDESCRIPTION , "ImageDescription" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
969 { TIFFTAG_MAKE , "Make" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
970 { TIFFTAG_MODEL , "Model" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
971 { TIFFTAG_SOFTWARE , "Software" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
972 { TIFFTAG_ARTIST , "Artist" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
973 { TIFFTAG_COPYRIGHT , "Copyright" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
974 { TIFFTAG_DATETIME , "DateTime" , EXIF_IFD_0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
975 { 0 , NULL , 0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
976 }; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
977 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
978 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
979 static const TIFFTagConvertInfo exif_tag_convert_table[] = |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
980 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
981 { EXIFTAG_EXPOSURETIME , "ExposureTime" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
982 { EXIFTAG_FNUMBER , "FNumber" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
983 { EXIFTAG_EXPOSUREPROGRAM , "ExposureProgram" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
984 { EXIFTAG_SPECTRALSENSITIVITY , "Spectralsensitivity" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
985 { EXIFTAG_DATETIMEORIGINAL , "DateTimeOriginal" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
986 { EXIFTAG_DATETIMEDIGITIZED , "DateTimeDigitized" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
987 { EXIFTAG_SHUTTERSPEEDVALUE , "ShutterSpeed" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
988 { EXIFTAG_APERTUREVALUE , "Aperture" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
989 { EXIFTAG_BRIGHTNESSVALUE , "Brightness" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
990 { EXIFTAG_EXPOSUREBIASVALUE , "ExposureBias" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
991 { EXIFTAG_MAXAPERTUREVALUE , "MaxAperture" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
992 { EXIFTAG_SUBJECTDISTANCE , "SubjectDistance" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
993 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
994 { EXIFTAG_METERINGMODE , "MeteringMode" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
995 { EXIFTAG_LIGHTSOURCE , "Lightsource" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
996 { EXIFTAG_FLASH , "Flash" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
997 { EXIFTAG_FOCALLENGTH , "FocalLength" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
998 { EXIFTAG_SUBJECTAREA , "SubjectArea" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
999 { EXIFTAG_USERCOMMENT , "UserComment" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1000 { EXIFTAG_SUBSECTIME , "SubSecTime" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1001 { EXIFTAG_SUBSECTIMEORIGINAL , "SubSecTimeOriginal" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1002 { EXIFTAG_SUBSECTIMEDIGITIZED , "SubSecTimeDigitized" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1003 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1004 { EXIFTAG_COLORSPACE , "Colorspace" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1005 { EXIFTAG_PIXELXDIMENSION , "Validimage" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1006 { EXIFTAG_PIXELYDIMENSION , "Validimage" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1007 { EXIFTAG_RELATEDSOUNDFILE , "Relatedaudio" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1008 { EXIFTAG_FLASHENERGY , "Flashenergy" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1009 { EXIFTAG_SPATIALFREQUENCYRESPONSE , "SpatialFrequency" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1010 { EXIFTAG_FOCALPLANEXRESOLUTION , "XResolution" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1011 { EXIFTAG_FOCALPLANEYRESOLUTION , "YResolution" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1012 { EXIFTAG_FOCALPLANERESOLUTIONUNIT , "ResolutionUnit" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1013 { EXIFTAG_SUBJECTLOCATION , "SubjectLocation" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1014 { EXIFTAG_EXPOSUREINDEX , "ExposureIndex" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1015 { EXIFTAG_SENSINGMETHOD , "SensingMethod" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1016 { EXIFTAG_FILESOURCE , "FileSource" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1017 { EXIFTAG_SCENETYPE , "SceneType" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1018 { EXIFTAG_CUSTOMRENDERED , "CustomRendered" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1019 { EXIFTAG_EXPOSUREMODE , "ExposureMode" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1020 { EXIFTAG_WHITEBALANCE , "WhiteBalance" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1021 { EXIFTAG_DIGITALZOOMRATIO , "DigitalZoom" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1022 { EXIFTAG_FOCALLENGTHIN35MMFILM , "FocalLength35mm" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1023 { EXIFTAG_SCENECAPTURETYPE , "SceneCapture" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1024 { EXIFTAG_GAINCONTROL , "GainControl" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1025 { EXIFTAG_CONTRAST , "Contrast" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1026 { EXIFTAG_SATURATION , "Saturation" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1027 { EXIFTAG_SHARPNESS , "Sharpness" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1028 { EXIFTAG_DEVICESETTINGDESCRIPTION , "DeviceSettings" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1029 { EXIFTAG_SUBJECTDISTANCERANGE , "SubjectDistance" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1030 { EXIFTAG_IMAGEUNIQUEID , "ImageUniqueID" , EXIF_IFD_EXIF }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1031 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1032 { 0 , NULL , 0 }, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1033 }; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1034 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1035 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1036 static void tiff_tags_convert(TIFF *tif, const TIFFTagConvertInfo *table, |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1037 ExifMem *mem, ExifData *exif, int *added) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1038 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1039 const TIFFTagConvertInfo *conv; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1040 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1041 for (conv = table; conv->tag != 0 && conv->name != NULL; conv++) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1042 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1043 const TIFFField *tfd = TIFFFieldWithTag(tif, conv->tag); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1044 TIFFDataType type = TIFFFieldDataType(tfd); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1045 int len = TIFFDataWidth(type); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1046 uint8_t tmp_buf[256], *data; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1047 char *tmp_str; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1048 int have; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1049 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1050 switch (type) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1051 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1052 case TIFF_ASCII: |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1053 have = TIFFGetField(tif, conv->tag, &tmp_str) && tmp_str != NULL; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1054 if (have) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1055 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1056 data = (uint8_t *) tmp_str; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1057 len = strlen(tmp_str) + 1; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1058 } |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1059 break; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1060 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1061 default: |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1062 have = TIFFGetField(tif, conv->tag, &tmp_buf); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1063 data = tmp_buf; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1064 } |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1065 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1066 if (have) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1067 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1068 ExifEntry *entry = exif_entry_new_mem(mem); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1069 if (entry == NULL) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1070 return; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1071 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1072 entry->data = exif_mem_alloc(mem, len); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1073 if (entry->data == NULL) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1074 return; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1075 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1076 memcpy(entry->data, data, len); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1077 entry->size = len; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1078 entry->tag = conv->tag; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1079 entry->components = len; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1080 entry->format = type; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1081 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1082 exif_content_add_entry(exif->ifd[conv->ifd], entry); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1083 exif_mem_unref(mem); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1084 exif_entry_unref(entry); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1085 (*added)++; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1086 } |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1087 } |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1088 } |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1089 #endif |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1090 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1091 |
22
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1092 void tiff_warning_handler(const char *module, const char *fmt, va_list ap) |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1093 { |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1094 (void) module; |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1095 (void) fmt; |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1096 (void) ap; |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1097 // ignore errors and warnings |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1098 } |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1099 |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1100 |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1101 Image *read_tiff(BPGMetaData **pmd, const char *filename, |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1102 BPGColorSpaceEnum color_space, int out_bit_depth, |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1103 int limited_range, int premultiplied_alpha) |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1104 { |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1105 TIFF *tif; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1106 Image *img = NULL; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1107 BPGImageFormatEnum img_format; |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
1108 uint8_t *buf = NULL, *tmp_buf = NULL; |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
1109 uint32_t img_width, img_height, tmp_len; |
11
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1110 uint16_t img_depth, img_spp, img_pconfig, img_pmetric, |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1111 *buf2 = NULL, *img_colormap_r, *img_colormap_g, *img_colormap_b; |
14
b0b1d299aa5d
Don't use C99 style declarations here for no reason.
Matti Hamalainen <ccr@tnsp.org>
parents:
13
diff
changeset
|
1112 int img_alpha, err_spp, offs, x, y, idx; |
24
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1113 toff_t tmp_offs; |
14
b0b1d299aa5d
Don't use C99 style declarations here for no reason.
Matti Hamalainen <ccr@tnsp.org>
parents:
13
diff
changeset
|
1114 size_t img_linesize; |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1115 ColorConvertState cvt; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1116 RGBConvertFunc *convert_func; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1117 |
22
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1118 // Set warning handler to silence dubious warnings about unknown fields |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1119 TIFFSetWarningHandler(tiff_warning_handler); |
69089d946a14
Set a dummy libtiff warning handler to silence useless warnings about
Matti Hamalainen <ccr@tnsp.org>
parents:
19
diff
changeset
|
1120 |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1121 // Open and read TIFF header etc. |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1122 if ((tif = TIFFOpen(filename, "rb")) == NULL) |
7 | 1123 { |
1124 fprintf(stderr, "Could not open TIFF image '%s'\n", filename); | |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1125 return NULL; |
7 | 1126 } |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1127 |
7 | 1128 if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img_width) || |
1129 !TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img_height) || | |
1130 !TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &img_spp) || | |
1131 !TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &img_depth)) | |
1132 { | |
25 | 1133 fprintf(stderr, "TIFF file '%s' lacks basic fields!\n", filename); |
7 | 1134 goto err; |
1135 } | |
1136 | |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1137 TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &img_pconfig); |
10
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1138 TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img_pmetric); |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1139 |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1140 // Check basics |
14
b0b1d299aa5d
Don't use C99 style declarations here for no reason.
Matti Hamalainen <ccr@tnsp.org>
parents:
13
diff
changeset
|
1141 err_spp = 0; |
10
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1142 switch (img_pmetric) |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1143 { |
12
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1144 case PHOTOMETRIC_MINISBLACK: |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1145 img_format = BPG_FORMAT_GRAY; |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1146 color_space = BPG_CS_YCbCr; |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1147 if (img_spp != 1) |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1148 err_spp = 1; |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1149 break; |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1150 |
10
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1151 case PHOTOMETRIC_RGB: |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1152 img_format = BPG_FORMAT_444; |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1153 if (img_spp < 3) |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1154 err_spp = 1; |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1155 break; |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1156 |
11
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1157 case PHOTOMETRIC_PALETTE: |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1158 img_format = BPG_FORMAT_444; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1159 if (img_spp != 1) |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1160 err_spp = 1; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1161 |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1162 if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &img_colormap_r, &img_colormap_g, &img_colormap_b)) |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1163 { |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1164 fprintf(stderr, "TIFF with palette is missing colormap entry!\n"); |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1165 goto err; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1166 } |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1167 break; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1168 |
10
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1169 default: |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1170 fprintf(stderr, "TIFF file has unsupported photometric interpretation %d!\n", img_pmetric); |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1171 goto err; |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1172 } |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1173 |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1174 if (err_spp) |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1175 { |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1176 fprintf(stderr, "TIFF file has unsupported samples per pixel %d for format %d.\n", img_spp, img_pmetric); |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1177 goto err; |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1178 } |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1179 |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1180 if (img_depth != 8 && img_depth != 16) |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1181 { |
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1182 fprintf(stderr, "TIFF file has unsupported depth %d (not 8 or 16)!\n", img_depth); |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1183 goto err; |
10
d04d9e3a77d0
Add checking TIFF photometric interpretation tag data.
Matti Hamalainen <ccr@tnsp.org>
parents:
9
diff
changeset
|
1184 } |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1185 |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1186 img_linesize = TIFFScanlineSize(tif); |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1187 |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1188 if (img_spp > 3) |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1189 { |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1190 uint16_t img_esmp, *img_esmp_types; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1191 |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1192 TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &img_esmp, &img_esmp_types); |
6
690bf78c1ce9
Initial implementation of alpha channel support for TIFF images.
Matti Hamalainen <ccr@tnsp.org>
parents:
5
diff
changeset
|
1193 img_alpha = img_esmp == 1 && img_esmp_types[0] == EXTRASAMPLE_ASSOCALPHA; |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1194 } |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1195 else |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1196 img_alpha = 0; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1197 |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1198 // Allocate temporary image space |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1199 buf = (uint8_t *) _TIFFmalloc(img_linesize * img_spp); |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1200 if (buf == NULL) |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1201 goto err; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1202 |
11
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1203 if (img_pmetric == PHOTOMETRIC_PALETTE) |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1204 { |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1205 // For indexed palette images we need a secondary RGB conversion buffer |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1206 buf2 = (uint16_t *) malloc(img_width * 3 * sizeof(uint16_t)); |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1207 if (buf2 == NULL) |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1208 goto err; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1209 |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1210 // Force 16bit depth and samples per pixel 3 as the |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1211 // TIFF colormap/palette has 16bit R, G, B entries. |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1212 img_spp = 3; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1213 img_depth = 16; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1214 } |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1215 |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1216 // Allocate target image |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1217 img = image_alloc(img_width, img_height, img_format, img_alpha, color_space, out_bit_depth); |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1218 if (img == NULL) |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1219 goto err; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1220 |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1221 img->limited_range = limited_range; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1222 img->premultiplied_alpha = premultiplied_alpha; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1223 |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1224 convert_init(&cvt, img_depth, out_bit_depth, color_space, limited_range); |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1225 |
14
b0b1d299aa5d
Don't use C99 style declarations here for no reason.
Matti Hamalainen <ccr@tnsp.org>
parents:
13
diff
changeset
|
1226 idx = img_depth == 16; |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1227 convert_func = rgb_to_cs[idx][color_space]; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1228 |
14
b0b1d299aa5d
Don't use C99 style declarations here for no reason.
Matti Hamalainen <ccr@tnsp.org>
parents:
13
diff
changeset
|
1229 for (y = 0; y < img->h; y++) |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1230 { |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1231 // Read TIFF image to raster |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1232 if (!TIFFReadScanline(tif, buf, y, 0)) |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1233 goto err; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1234 |
11
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1235 // Convert the scanline data |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1236 switch (img_pmetric) |
6
690bf78c1ce9
Initial implementation of alpha channel support for TIFF images.
Matti Hamalainen <ccr@tnsp.org>
parents:
5
diff
changeset
|
1237 { |
11
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1238 case PHOTOMETRIC_PALETTE: |
14
b0b1d299aa5d
Don't use C99 style declarations here for no reason.
Matti Hamalainen <ccr@tnsp.org>
parents:
13
diff
changeset
|
1239 for (x = 0, offs = 0; x < img->w; x++) |
11
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1240 { |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1241 buf2[offs++] = img_colormap_r[buf[x]]; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1242 buf2[offs++] = img_colormap_g[buf[x]]; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1243 buf2[offs++] = img_colormap_b[buf[x]]; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1244 } |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1245 convert_func(&cvt, |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1246 (PIXEL *)(img->data[0] + y * img->linesize[0]), |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1247 (PIXEL *)(img->data[1] + y * img->linesize[1]), |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1248 (PIXEL *)(img->data[2] + y * img->linesize[2]), |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1249 buf2, img->w, img_spp); |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1250 break; |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1251 |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1252 case PHOTOMETRIC_RGB: |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1253 convert_func(&cvt, |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1254 (PIXEL *)(img->data[0] + y * img->linesize[0]), |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1255 (PIXEL *)(img->data[1] + y * img->linesize[1]), |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1256 (PIXEL *)(img->data[2] + y * img->linesize[2]), |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1257 buf, img->w, img_spp); |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1258 |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1259 if (img_alpha) |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1260 { |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1261 if (idx) |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1262 { |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1263 gray16_to_gray(&cvt, |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1264 (PIXEL *)(img->data[3] + y * img->linesize[3]), |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1265 ((uint16_t *) buf) + 3, img->w, 4); |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1266 } |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1267 else |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1268 { |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1269 gray8_to_gray(&cvt, |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1270 (PIXEL *)(img->data[3] + y * img->linesize[3]), |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1271 ((uint8_t *) buf) + 3, img->w, 4); |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1272 } |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1273 } |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1274 break; |
12
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1275 |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1276 case PHOTOMETRIC_MINISBLACK: |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1277 if (img_depth == 16) |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1278 { |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1279 luma16_to_gray(&cvt, |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1280 (PIXEL *)(img->data[0] + y * img->linesize[0]), |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1281 (uint16_t *) buf, img->w, img_spp); |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1282 |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1283 if (img_alpha) |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1284 { |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1285 gray16_to_gray(&cvt, |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1286 (PIXEL *)(img->data[1] + y * img->linesize[1]), |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1287 ((uint16_t *) buf) + 1, img->w, 2); |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1288 } |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1289 } |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1290 else |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1291 { |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1292 luma8_to_gray(&cvt, |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1293 (PIXEL *)(img->data[0] + y * img->linesize[0]), |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1294 (uint8_t *) buf, img->w, img_spp); |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1295 |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1296 if (img_alpha) |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1297 { |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1298 gray8_to_gray(&cvt, |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1299 (PIXEL *)(img->data[1] + y * img->linesize[1]), |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1300 ((uint8_t *) buf) + 1, img->w, 2); |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1301 } |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1302 } |
9b00d4206f99
Implement support for one type of grayscale TIFF.
Matti Hamalainen <ccr@tnsp.org>
parents:
11
diff
changeset
|
1303 break; |
6
690bf78c1ce9
Initial implementation of alpha channel support for TIFF images.
Matti Hamalainen <ccr@tnsp.org>
parents:
5
diff
changeset
|
1304 } |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1305 } |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1306 |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
1307 // Get meta data |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
1308 if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &tmp_len, &tmp_buf)) |
17
91f27e9fdb60
Rename insert_md() and add_md_contents() to bpg_insert_md() and
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
1309 bpg_add_md_contents(pmd, BPG_EXTENSION_TAG_ICCP, tmp_len, tmp_buf); |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
1310 |
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
1311 if (TIFFGetField(tif, TIFFTAG_XMLPACKET, &tmp_len, &tmp_buf)) |
17
91f27e9fdb60
Rename insert_md() and add_md_contents() to bpg_insert_md() and
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
1312 bpg_add_md_contents(pmd, BPG_EXTENSION_TAG_XMP, tmp_len, tmp_buf); |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1313 |
24
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1314 #ifdef HAVE_LIBEXIF |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1315 // Due to insanity of libtiff's "API", we have to go roundabout way to |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1316 // reconstruct the EXIF data through libexif and fetching TIFF tags .. |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1317 // even though the data already supposedly exists in desired format .. :( |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1318 ExifMem *exif_mem = exif_mem_new_default(); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1319 if (exif_mem == NULL) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1320 goto err; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1321 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1322 ExifData *exif = exif_data_new_mem(exif_mem); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1323 if (exif == NULL) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1324 goto err; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1325 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1326 exif_data_set_option(exif, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1327 exif_data_set_data_type(exif, EXIF_DATA_TYPE_COMPRESSED); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1328 exif_data_set_byte_order(exif, EXIF_BYTE_ORDER_INTEL); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1329 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1330 int added = 0; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1331 tiff_tags_convert(tif, tiff_tag_convert_table, exif_mem, exif, &added); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1332 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1333 if (TIFFGetField(tif, TIFFTAG_EXIFIFD, &tmp_offs)) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1334 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1335 if (TIFFReadEXIFDirectory(tif, tmp_offs)) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1336 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1337 tiff_tags_convert(tif, exif_tag_convert_table, exif_mem, exif, &added); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1338 } |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1339 } |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1340 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1341 if (added) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1342 { |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1343 uint8_t *ex_buf = NULL; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1344 unsigned int ex_len = 0; |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1345 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1346 exif_data_save_data(exif, &ex_buf, &ex_len); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1347 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1348 // Strip off "Exif\x00\x00" from the data |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1349 if (ex_len > 6) |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1350 bpg_add_md_contents(pmd, BPG_EXTENSION_TAG_EXIF, ex_len - 6, ex_buf + 6); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1351 |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1352 exif_mem_free(exif_mem, ex_buf); |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1353 } |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1354 #endif |
377dc78a052d
Add EXIF metadata conversion from TIFF files to BPG via libexif.
Matti Hamalainen <ccr@tnsp.org>
parents:
22
diff
changeset
|
1355 |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1356 err: |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1357 if (buf != NULL) |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1358 _TIFFfree(buf); |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1359 |
11
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1360 if (buf2 != NULL) |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1361 free(buf2); |
e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
Matti Hamalainen <ccr@tnsp.org>
parents:
10
diff
changeset
|
1362 |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1363 TIFFClose(tif); |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1364 return img; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1365 } |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1366 |
25 | 1367 |
0 | 1368 Image *read_png(BPGMetaData **pmd, |
1369 FILE *f, BPGColorSpaceEnum color_space, int out_bit_depth, | |
1370 int limited_range, int premultiplied_alpha) | |
1371 { | |
1372 png_structp png_ptr; | |
1373 png_infop info_ptr; | |
1374 int bit_depth, color_type; | |
1375 Image *img; | |
1376 uint8_t **rows; | |
1377 int y, has_alpha, linesize, bpp; | |
1378 BPGImageFormatEnum format; | |
1379 ColorConvertState cvt_s, *cvt = &cvt_s; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1380 |
0 | 1381 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, |
1382 NULL, NULL, NULL); | |
1383 if (png_ptr == NULL) { | |
1384 return NULL; | |
1385 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1386 |
0 | 1387 info_ptr = png_create_info_struct(png_ptr); |
1388 if (info_ptr == NULL) { | |
1389 png_destroy_read_struct(&png_ptr, NULL, NULL); | |
1390 return NULL; | |
1391 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1392 |
0 | 1393 if (setjmp(png_jmpbuf(png_ptr))) { |
1394 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); | |
1395 return NULL; | |
1396 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1397 |
0 | 1398 png_init_io(png_ptr, f); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1399 |
0 | 1400 png_read_info(png_ptr, info_ptr); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1401 |
0 | 1402 bit_depth = png_get_bit_depth(png_ptr, info_ptr); |
1403 color_type = png_get_color_type(png_ptr, info_ptr); | |
1404 | |
1405 switch (color_type) { | |
1406 case PNG_COLOR_TYPE_PALETTE: | |
1407 png_set_palette_to_rgb(png_ptr); | |
1408 bit_depth = 8; | |
1409 break; | |
1410 case PNG_COLOR_TYPE_GRAY: | |
1411 case PNG_COLOR_TYPE_GRAY_ALPHA: | |
1412 if (bit_depth < 8) { | |
1413 png_set_expand_gray_1_2_4_to_8(png_ptr); | |
1414 bit_depth = 8; | |
1415 } | |
1416 break; | |
1417 } | |
1418 assert(bit_depth == 8 || bit_depth == 16); | |
1419 | |
1420 #if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ | |
1421 if (bit_depth == 16) { | |
1422 png_set_swap(png_ptr); | |
1423 } | |
1424 #endif | |
1425 | |
1426 if (color_type == PNG_COLOR_TYPE_GRAY || | |
1427 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { | |
1428 format = BPG_FORMAT_GRAY; | |
1429 color_space = BPG_CS_YCbCr; | |
1430 } else { | |
1431 format = BPG_FORMAT_444; | |
1432 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1433 |
0 | 1434 has_alpha = (color_type == PNG_COLOR_TYPE_GRAY_ALPHA || |
1435 color_type == PNG_COLOR_TYPE_RGB_ALPHA); | |
1436 | |
1437 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { | |
1438 png_set_tRNS_to_alpha(png_ptr); | |
1439 has_alpha = 1; | |
1440 } | |
1441 | |
1442 if (premultiplied_alpha) { | |
1443 png_set_alpha_mode(png_ptr, PNG_ALPHA_ASSOCIATED, PNG_GAMMA_LINEAR); | |
1444 } | |
1445 | |
1446 img = image_alloc(png_get_image_width(png_ptr, info_ptr), | |
1447 png_get_image_height(png_ptr, info_ptr), | |
1448 format, has_alpha, color_space, | |
1449 out_bit_depth); | |
1450 img->limited_range = limited_range; | |
1451 img->premultiplied_alpha = premultiplied_alpha; | |
1452 | |
1453 rows = malloc(sizeof(rows[0]) * img->h); | |
1454 if (format == BPG_FORMAT_GRAY) | |
1455 bpp = (1 + has_alpha) * (bit_depth / 8); | |
1456 else | |
1457 bpp = (3 + has_alpha) * (bit_depth / 8); | |
1458 linesize = bpp * img->w; | |
1459 for (y = 0; y < img->h; y++) { | |
1460 rows[y] = malloc(linesize); | |
1461 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1462 |
0 | 1463 png_read_image(png_ptr, rows); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1464 |
0 | 1465 convert_init(cvt, bit_depth, out_bit_depth, color_space, limited_range); |
1466 | |
1467 if (format != BPG_FORMAT_GRAY) { | |
1468 int idx; | |
1469 RGBConvertFunc *convert_func; | |
1470 | |
1471 idx = (bit_depth == 16); | |
1472 convert_func = rgb_to_cs[idx][color_space]; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1473 |
0 | 1474 for (y = 0; y < img->h; y++) { |
1475 convert_func(cvt, (PIXEL *)(img->data[0] + y * img->linesize[0]), | |
1476 (PIXEL *)(img->data[1] + y * img->linesize[1]), | |
1477 (PIXEL *)(img->data[2] + y * img->linesize[2]), | |
1478 rows[y], img->w, 3 + has_alpha); | |
1479 if (has_alpha) { | |
1480 if (idx) { | |
1481 gray16_to_gray(cvt, (PIXEL *)(img->data[3] + y * img->linesize[3]), | |
1482 (uint16_t *)rows[y] + 3, img->w, 4); | |
1483 } else { | |
1484 gray8_to_gray(cvt, (PIXEL *)(img->data[3] + y * img->linesize[3]), | |
1485 rows[y] + 3, img->w, 4); | |
1486 } | |
1487 } | |
1488 } | |
1489 } else { | |
1490 if (bit_depth == 16) { | |
1491 for (y = 0; y < img->h; y++) { | |
1492 luma16_to_gray(cvt, (PIXEL *)(img->data[0] + y * img->linesize[0]), | |
1493 (uint16_t *)rows[y], img->w, 1 + has_alpha); | |
1494 if (has_alpha) { | |
1495 gray16_to_gray(cvt, (PIXEL *)(img->data[1] + y * img->linesize[1]), | |
1496 (uint16_t *)rows[y] + 1, img->w, 2); | |
1497 } | |
1498 } | |
1499 } else { | |
1500 for (y = 0; y < img->h; y++) { | |
1501 luma8_to_gray(cvt, (PIXEL *)(img->data[0] + y * img->linesize[0]), | |
1502 rows[y], img->w, 1 + has_alpha); | |
1503 if (has_alpha) { | |
1504 gray8_to_gray(cvt, (PIXEL *)(img->data[1] + y * img->linesize[1]), | |
1505 rows[y] + 1, img->w, 2); | |
1506 } | |
1507 } | |
1508 } | |
1509 } | |
1510 | |
1511 for (y = 0; y < img->h; y++) { | |
1512 free(rows[y]); | |
1513 } | |
1514 free(rows); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1515 |
0 | 1516 png_read_end(png_ptr, info_ptr); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1517 |
0 | 1518 /* get the ICC profile if present */ |
1519 { | |
1520 png_charp name; | |
1521 int comp_type; | |
1522 png_bytep iccp_buf; | |
1523 png_uint_32 iccp_buf_len; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1524 |
0 | 1525 if (png_get_iCCP(png_ptr, info_ptr, |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
1526 &name, &comp_type, &iccp_buf, &iccp_buf_len) == PNG_INFO_iCCP) |
17
91f27e9fdb60
Rename insert_md() and add_md_contents() to bpg_insert_md() and
Matti Hamalainen <ccr@tnsp.org>
parents:
16
diff
changeset
|
1527 bpg_add_md_contents(pmd, BPG_EXTENSION_TAG_ICCP, iccp_buf_len, iccp_buf); |
0 | 1528 } |
1529 | |
1530 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1531 |
0 | 1532 return img; |
1533 } | |
1534 | |
1535 static BPGMetaData *jpeg_get_metadata(jpeg_saved_marker_ptr first_marker) | |
1536 { | |
26
a6e11adda0be
The format of JPEG EXIF data converted to BPG had an extraneous zero byte at
Matti Hamalainen <ccr@tnsp.org>
parents:
25
diff
changeset
|
1537 static const char app1_exif[6] = "Exif\x00\x00"; |
0 | 1538 static const char app1_xmp[] = "http://ns.adobe.com/xap/1.0/"; |
1539 static const char app2_iccp[] = "ICC_PROFILE"; | |
1540 jpeg_saved_marker_ptr marker; | |
18
403c67bcb76a
Use bpg_insert_md() and bpg_add_md_contents() in jpeg_get_metadata() also.
Matti Hamalainen <ccr@tnsp.org>
parents:
17
diff
changeset
|
1541 BPGMetaData *md_list; |
0 | 1542 int has_exif, has_xmp, l, iccp_chunk_count, i; |
1543 jpeg_saved_marker_ptr iccp_chunks[256]; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1544 |
0 | 1545 iccp_chunk_count = 0; |
1546 has_exif = 0; | |
1547 has_xmp = 0; | |
18
403c67bcb76a
Use bpg_insert_md() and bpg_add_md_contents() in jpeg_get_metadata() also.
Matti Hamalainen <ccr@tnsp.org>
parents:
17
diff
changeset
|
1548 md_list = NULL; |
0 | 1549 for (marker = first_marker; marker != NULL; marker = marker->next) { |
1550 #if 0 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1551 printf("marker=APP%d len=%d\n", |
0 | 1552 marker->marker - JPEG_APP0, marker->data_length); |
1553 #endif | |
1554 if (!has_exif && marker->marker == JPEG_APP0 + 1 && | |
1555 marker->data_length > sizeof(app1_exif) && | |
1556 !memcmp(marker->data, app1_exif, sizeof(app1_exif))) { | |
1557 l = sizeof(app1_exif); | |
18
403c67bcb76a
Use bpg_insert_md() and bpg_add_md_contents() in jpeg_get_metadata() also.
Matti Hamalainen <ccr@tnsp.org>
parents:
17
diff
changeset
|
1558 bpg_add_md_contents(&md_list, BPG_EXTENSION_TAG_EXIF, marker->data_length - l, marker->data + l); |
0 | 1559 has_exif = 1; |
1560 } else if (!has_xmp && marker->marker == JPEG_APP0 + 1 && | |
1561 marker->data_length > sizeof(app1_xmp) && | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1562 !memcmp(marker->data, app1_xmp, sizeof(app1_xmp)) && |
0 | 1563 !has_xmp) { |
1564 l = sizeof(app1_xmp); | |
18
403c67bcb76a
Use bpg_insert_md() and bpg_add_md_contents() in jpeg_get_metadata() also.
Matti Hamalainen <ccr@tnsp.org>
parents:
17
diff
changeset
|
1565 bpg_add_md_contents(&md_list, BPG_EXTENSION_TAG_XMP, marker->data_length - l, marker->data + l); |
0 | 1566 has_xmp = 1; |
1567 } else if (marker->marker == JPEG_APP0 + 2 && | |
1568 marker->data_length > (sizeof(app2_iccp) + 2) && | |
1569 !memcmp(marker->data, app2_iccp, sizeof(app2_iccp))) { | |
1570 int chunk_count, chunk_index; | |
1571 l = sizeof(app2_iccp); | |
1572 chunk_index = marker->data[l]; | |
1573 chunk_count = marker->data[l]; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1574 if (chunk_index == 0 || chunk_count == 0) |
0 | 1575 continue; |
1576 if (iccp_chunk_count == 0) { | |
1577 iccp_chunk_count = chunk_count; | |
1578 for(i = 0; i < chunk_count; i++) { | |
1579 iccp_chunks[i] = NULL; | |
1580 } | |
1581 } else { | |
1582 if (chunk_count != iccp_chunk_count) | |
1583 continue; | |
1584 } | |
1585 if (chunk_index > iccp_chunk_count) | |
1586 continue; | |
1587 iccp_chunks[chunk_index - 1] = marker; | |
1588 } | |
1589 } | |
1590 | |
1591 if (iccp_chunk_count != 0) { | |
1592 int len, hlen, idx; | |
1593 /* check that no chunk are missing */ | |
1594 len = 0; | |
1595 hlen = sizeof(app2_iccp) + 2; | |
1596 for(i = 0; i < iccp_chunk_count; i++) { | |
1597 if (!iccp_chunks[i]) | |
1598 break; | |
1599 len += iccp_chunks[i]->data_length - hlen; | |
1600 } | |
1601 if (i == iccp_chunk_count) { | |
18
403c67bcb76a
Use bpg_insert_md() and bpg_add_md_contents() in jpeg_get_metadata() also.
Matti Hamalainen <ccr@tnsp.org>
parents:
17
diff
changeset
|
1602 BPGMetaData *md = bpg_md_alloc(BPG_EXTENSION_TAG_ICCP); |
0 | 1603 md->buf_len = len; |
1604 md->buf = malloc(md->buf_len); | |
18
403c67bcb76a
Use bpg_insert_md() and bpg_add_md_contents() in jpeg_get_metadata() also.
Matti Hamalainen <ccr@tnsp.org>
parents:
17
diff
changeset
|
1605 bpg_insert_md(&md_list, md); |
403c67bcb76a
Use bpg_insert_md() and bpg_add_md_contents() in jpeg_get_metadata() also.
Matti Hamalainen <ccr@tnsp.org>
parents:
17
diff
changeset
|
1606 for(i = 0, idx = 0; i < iccp_chunk_count; i++) { |
0 | 1607 l = iccp_chunks[i]->data_length - hlen; |
1608 memcpy(md->buf + idx, iccp_chunks[i]->data + hlen, l); | |
1609 idx += l; | |
1610 } | |
1611 assert(idx == len); | |
1612 } | |
1613 } | |
18
403c67bcb76a
Use bpg_insert_md() and bpg_add_md_contents() in jpeg_get_metadata() also.
Matti Hamalainen <ccr@tnsp.org>
parents:
17
diff
changeset
|
1614 return md_list; |
0 | 1615 } |
1616 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1617 Image *read_jpeg(BPGMetaData **pmd, FILE *f, |
0 | 1618 int out_bit_depth) |
1619 { | |
1620 struct jpeg_decompress_struct cinfo; | |
1621 struct jpeg_error_mgr jerr; | |
1622 int w, h, w1, i, y_h, c_h, y, v_shift, c_w, y1, idx, c_idx, h_shift; | |
1623 int h1, plane_idx[4], has_alpha, has_w_plane; | |
1624 Image *img; | |
1625 BPGImageFormatEnum format; | |
1626 BPGColorSpaceEnum color_space; | |
1627 ColorConvertState cvt_s, *cvt = &cvt_s; | |
1628 uint32_t comp_hv; | |
1629 | |
1630 cinfo.err = jpeg_std_error(&jerr); | |
1631 jpeg_create_decompress(&cinfo); | |
1632 | |
1633 jpeg_save_markers(&cinfo, JPEG_APP0 + 1, 65535); | |
1634 jpeg_save_markers(&cinfo, JPEG_APP0 + 2, 65535); | |
1635 | |
1636 jpeg_stdio_src(&cinfo, f); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1637 |
0 | 1638 jpeg_read_header(&cinfo, TRUE); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1639 |
0 | 1640 cinfo.raw_data_out = TRUE; |
1641 cinfo.do_fancy_upsampling = TRUE; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1642 |
0 | 1643 w = cinfo.image_width; |
1644 h = cinfo.image_height; | |
1645 | |
1646 has_w_plane = 0; | |
1647 comp_hv = 0; | |
1648 if (cinfo.num_components < 1 || cinfo.num_components > 4) | |
1649 goto unsupported; | |
1650 for(i = 0; i < cinfo.num_components; i++) { | |
1651 comp_hv |= cinfo.comp_info[i].h_samp_factor << (i * 8 + 4); | |
1652 comp_hv |= cinfo.comp_info[i].v_samp_factor << (i * 8); | |
1653 } | |
1654 switch(cinfo.jpeg_color_space) { | |
1655 case JCS_GRAYSCALE: | |
1656 if (cinfo.num_components != 1 || comp_hv != 0x11) | |
1657 goto unsupported; | |
1658 format = BPG_FORMAT_GRAY; | |
1659 color_space = BPG_CS_YCbCr; | |
1660 break; | |
1661 case JCS_YCbCr: | |
1662 if (cinfo.num_components != 3) | |
1663 goto unsupported; | |
1664 switch(comp_hv) { | |
1665 case 0x111111: | |
1666 format = BPG_FORMAT_444; | |
1667 break; | |
1668 case 0x111121: | |
1669 format = BPG_FORMAT_422; | |
1670 break; | |
1671 case 0x111122: | |
1672 format = BPG_FORMAT_420; | |
1673 break; | |
1674 default: | |
1675 cinfo.raw_data_out = FALSE; | |
1676 format = BPG_FORMAT_444; | |
1677 cinfo.out_color_space = JCS_YCbCr; | |
1678 break; | |
1679 } | |
1680 color_space = BPG_CS_YCbCr; | |
1681 break; | |
1682 case JCS_RGB: | |
1683 if (cinfo.num_components != 3) | |
1684 goto unsupported; | |
1685 format = BPG_FORMAT_444; | |
1686 color_space = BPG_CS_RGB; | |
1687 cinfo.raw_data_out = FALSE; | |
1688 cinfo.out_color_space = JCS_RGB; | |
1689 break; | |
1690 case JCS_YCCK: | |
1691 if (cinfo.num_components != 4) | |
1692 goto unsupported; | |
1693 switch(comp_hv) { | |
1694 case 0x11111111: | |
1695 format = BPG_FORMAT_444; | |
1696 color_space = BPG_CS_YCbCr; | |
1697 break; | |
1698 case 0x22111121: | |
1699 format = BPG_FORMAT_422; | |
1700 color_space = BPG_CS_YCbCr; | |
1701 break; | |
1702 case 0x22111122: | |
1703 format = BPG_FORMAT_420; | |
1704 color_space = BPG_CS_YCbCr; | |
1705 break; | |
1706 default: | |
1707 cinfo.raw_data_out = FALSE; | |
1708 format = BPG_FORMAT_444; | |
1709 cinfo.out_color_space = JCS_CMYK; | |
1710 color_space = BPG_CS_RGB; | |
1711 break; | |
1712 } | |
1713 has_w_plane = 1; | |
1714 break; | |
1715 case JCS_CMYK: | |
1716 if (cinfo.num_components != 4) | |
1717 goto unsupported; | |
1718 format = BPG_FORMAT_444; | |
1719 color_space = BPG_CS_RGB; | |
1720 has_w_plane = 1; | |
1721 cinfo.raw_data_out = FALSE; | |
1722 cinfo.out_color_space = JCS_CMYK; | |
1723 break; | |
1724 default: | |
1725 unsupported: | |
1726 fprintf(stderr, "Unsupported JPEG parameters (cs=%d n_comp=%d comp_hv=%x)\n", | |
1727 cinfo.jpeg_color_space, cinfo.num_components, comp_hv); | |
1728 img = NULL; | |
1729 goto the_end; | |
1730 } | |
1731 | |
1732 v_shift = (format == BPG_FORMAT_420); | |
1733 h_shift = (format == BPG_FORMAT_422 || format == BPG_FORMAT_420); | |
1734 has_alpha = (cinfo.num_components == 4); | |
1735 img = image_alloc(w, h, format, has_alpha, color_space, out_bit_depth); | |
1736 img->has_w_plane = has_w_plane; | |
1737 | |
1738 convert_init(cvt, 8, out_bit_depth, color_space, 0); | |
1739 | |
1740 jpeg_start_decompress(&cinfo); | |
1741 | |
1742 if (color_space == BPG_CS_RGB) { | |
1743 plane_idx[0] = 2; | |
1744 plane_idx[1] = 0; | |
1745 plane_idx[2] = 1; | |
1746 } else { | |
1747 plane_idx[0] = 0; | |
1748 plane_idx[1] = 1; | |
1749 plane_idx[2] = 2; | |
1750 } | |
1751 plane_idx[3] = 3; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1752 |
0 | 1753 if (cinfo.raw_data_out) { |
1754 JSAMPROW rows[4][16]; | |
1755 JSAMPROW *plane_pointer[4]; | |
1756 | |
1757 y_h = 8 * cinfo.max_v_samp_factor; | |
1758 if (cinfo.num_components == 1) { | |
1759 c_h = 0; | |
1760 c_w = 0; | |
1761 } else { | |
1762 c_h = 8; | |
1763 if (h_shift) | |
1764 c_w = (w + 1) / 2; | |
1765 else | |
1766 c_w = w; | |
1767 } | |
1768 w1 = (w + 15) & ~15; | |
1769 for(c_idx = 0; c_idx < cinfo.num_components; c_idx++) { | |
1770 if (c_idx == 1 || c_idx == 2) { | |
1771 h1 = c_h; | |
1772 } else { | |
1773 h1 = y_h; | |
1774 } | |
1775 for(i = 0; i < h1; i++) { | |
1776 rows[c_idx][i] = malloc(w1); | |
1777 } | |
1778 plane_pointer[c_idx] = rows[c_idx]; | |
1779 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1780 |
0 | 1781 while (cinfo.output_scanline < cinfo.output_height) { |
1782 y = cinfo.output_scanline; | |
1783 jpeg_read_raw_data(&cinfo, plane_pointer, y_h); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1784 |
0 | 1785 for(c_idx = 0; c_idx < cinfo.num_components; c_idx++) { |
1786 if (c_idx == 1 || c_idx == 2) { | |
1787 h1 = c_h; | |
1788 w1 = c_w; | |
1789 y1 = (y >> v_shift); | |
1790 } else { | |
1791 h1 = y_h; | |
1792 w1 = img->w; | |
1793 y1 = y; | |
1794 } | |
1795 idx = plane_idx[c_idx]; | |
1796 for(i = 0; i < h1; i++) { | |
1797 PIXEL *ptr; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1798 ptr = (PIXEL *)(img->data[idx] + |
0 | 1799 img->linesize[idx] * (y1 + i)); |
1800 gray8_to_gray(cvt, ptr, rows[c_idx][i], w1, 1); | |
1801 if (color_space == BPG_CS_YCbCr && has_w_plane) { | |
1802 /* negate color */ | |
1803 if (c_idx == 0) { | |
1804 gray_one_minus(cvt, ptr, w1); | |
1805 } else if (c_idx <= 2) { | |
1806 gray_neg_c(cvt, ptr, w1); | |
1807 } | |
1808 } | |
1809 } | |
1810 } | |
1811 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1812 |
0 | 1813 for(c_idx = 0; c_idx < cinfo.num_components; c_idx++) { |
1814 if (c_idx == 1 || c_idx == 2) { | |
1815 h1 = c_h; | |
1816 } else { | |
1817 h1 = y_h; | |
1818 } | |
1819 for(i = 0; i < h1; i++) { | |
1820 free(rows[c_idx][i]); | |
1821 } | |
1822 } | |
1823 } else { | |
1824 JSAMPROW rows[1]; | |
1825 uint8_t *buf; | |
1826 int c_count; | |
1827 | |
1828 c_count = 3 + has_w_plane; | |
1829 buf = malloc(c_count * w); | |
1830 rows[0] = buf; | |
1831 while (cinfo.output_scanline < cinfo.output_height) { | |
1832 y = cinfo.output_scanline; | |
1833 jpeg_read_scanlines(&cinfo, rows, 1); | |
1834 | |
1835 for(c_idx = 0; c_idx < c_count; c_idx++) { | |
1836 idx = plane_idx[c_idx]; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1837 gray8_to_gray(cvt, (PIXEL *)(img->data[idx] + |
0 | 1838 img->linesize[idx] * y), |
1839 buf + c_idx, w, c_count); | |
1840 } | |
1841 } | |
1842 free(buf); | |
1843 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1844 |
9
bfd933ef38b4
Implement some metadata support in TIFF and clean up meta data handling otherwise.
Matti Hamalainen <ccr@tnsp.org>
parents:
8
diff
changeset
|
1845 *pmd = jpeg_get_metadata(cinfo.marker_list); |
0 | 1846 |
1847 the_end: | |
1848 jpeg_finish_decompress(&cinfo); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1849 |
0 | 1850 jpeg_destroy_decompress(&cinfo); |
1851 return img; | |
1852 } | |
1853 | |
25 | 1854 |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1855 static const char PROBE_TIFF_MAGIC_LE[] = { 'I', 'I', 42, 0 }; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1856 static const char PROBE_TIFF_MAGIC_BE[] = { 'M', 'M', 0, 42 }; |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1857 #define PROBE_BUF_SIZE 8 |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1858 |
0 | 1859 Image *load_image(BPGMetaData **pmd, const char *infilename, |
1860 BPGColorSpaceEnum color_space, int bit_depth, | |
1861 int limited_range, int premultiplied_alpha) | |
1862 { | |
1863 FILE *f; | |
3
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1864 Image *img = NULL; |
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1865 uint8_t buf[PROBE_BUF_SIZE]; |
0 | 1866 |
1867 *pmd = NULL; | |
1868 | |
3
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1869 if ((f = fopen(infilename, "rb")) == NULL) |
0 | 1870 return NULL; |
3
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1871 |
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1872 if (fread(buf, 1, PROBE_BUF_SIZE, f) != PROBE_BUF_SIZE) |
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1873 goto err; |
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1874 |
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1875 fseek(f, 0, SEEK_SET); |
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1876 |
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1877 if (png_sig_cmp(buf, 0, PROBE_BUF_SIZE) == 0) |
8
5a1eec3c43cc
Get rid of indirect metadata variable sillyness in load_image().
Matti Hamalainen <ccr@tnsp.org>
parents:
7
diff
changeset
|
1878 img = read_png(pmd, f, color_space, bit_depth, limited_range, premultiplied_alpha); |
3
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1879 else |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1880 if (memcmp(buf, PROBE_TIFF_MAGIC_LE, sizeof(PROBE_TIFF_MAGIC_LE)) == 0 || |
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1881 memcmp(buf, PROBE_TIFF_MAGIC_BE, sizeof(PROBE_TIFF_MAGIC_BE)) == 0) |
8
5a1eec3c43cc
Get rid of indirect metadata variable sillyness in load_image().
Matti Hamalainen <ccr@tnsp.org>
parents:
7
diff
changeset
|
1882 img = read_tiff(pmd, infilename, color_space, bit_depth, limited_range, premultiplied_alpha); |
4
bbd61622856a
Initial implementation of TIFF format read support via libtiff.
Matti Hamalainen <ccr@tnsp.org>
parents:
3
diff
changeset
|
1883 else |
8
5a1eec3c43cc
Get rid of indirect metadata variable sillyness in load_image().
Matti Hamalainen <ccr@tnsp.org>
parents:
7
diff
changeset
|
1884 img = read_jpeg(pmd, f, bit_depth); |
3
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1885 |
ffcd1967fb5c
Clean up load_image() probing code a bit in preparation for TIFF support.
Matti Hamalainen <ccr@tnsp.org>
parents:
0
diff
changeset
|
1886 err: |
0 | 1887 fclose(f); |
1888 return img; | |
1889 } | |
1890 | |
1891 void save_yuv1(Image *img, FILE *f) | |
1892 { | |
1893 int c_w, c_h, i, c_count, y; | |
1894 | |
1895 if (img->format == BPG_FORMAT_GRAY) | |
1896 c_count = 1; | |
1897 else | |
1898 c_count = 3; | |
1899 for(i = 0; i < c_count; i++) { | |
1900 get_plane_res(img, &c_w, &c_h, i); | |
1901 for(y = 0; y < c_h; y++) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1902 fwrite(img->data[i] + y * img->linesize[i], |
0 | 1903 1, c_w << img->pixel_shift, f); |
1904 } | |
1905 } | |
1906 } | |
1907 | |
1908 void save_yuv(Image *img, const char *filename) | |
1909 { | |
1910 FILE *f; | |
1911 | |
1912 f = fopen(filename, "wb"); | |
1913 if (!f) { | |
1914 fprintf(stderr, "Could not open %s\n", filename); | |
1915 exit(1); | |
1916 } | |
1917 save_yuv1(img, f); | |
1918 fclose(f); | |
1919 } | |
1920 | |
1921 /* return the position of the end of the NAL or -1 if error */ | |
1922 static int find_nal_end(const uint8_t *buf, int buf_len) | |
1923 { | |
1924 int idx; | |
1925 | |
1926 idx = 0; | |
1927 if (buf_len >= 4 && | |
1928 buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 1) { | |
1929 idx = 4; | |
1930 } else if (buf_len >= 3 && | |
1931 buf[0] == 0 && buf[1] == 0 && buf[2] == 1) { | |
1932 idx = 3; | |
1933 } else { | |
1934 return -1; | |
1935 } | |
1936 /* NAL header */ | |
1937 if (idx + 2 > buf_len) | |
1938 return -1; | |
1939 /* find the last byte */ | |
1940 for(;;) { | |
1941 if (idx + 2 >= buf_len) { | |
1942 idx = buf_len; | |
1943 break; | |
1944 } | |
1945 if (buf[idx] == 0 && buf[idx + 1] == 0 && buf[idx + 2] == 1) | |
1946 break; | |
1947 if (idx + 3 < buf_len && | |
1948 buf[idx] == 0 && buf[idx + 1] == 0 && buf[idx + 2] == 0 && buf[idx + 3] == 1) | |
1949 break; | |
1950 idx++; | |
1951 } | |
1952 return idx; | |
1953 } | |
1954 | |
1955 /* return the position of the end of the NAL or -1 if error */ | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1956 static int extract_nal(uint8_t **pnal_buf, int *pnal_len, |
0 | 1957 const uint8_t *buf, int buf_len) |
1958 { | |
1959 int idx, start, end, len; | |
1960 uint8_t *nal_buf; | |
1961 int nal_len; | |
1962 | |
1963 end = find_nal_end(buf, buf_len); | |
1964 if (end < 0) | |
1965 return -1; | |
1966 if (buf[2] == 1) | |
1967 start = 3; | |
1968 else | |
1969 start = 4; | |
1970 len = end - start; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1971 |
0 | 1972 nal_buf = malloc(len); |
1973 nal_len = 0; | |
1974 idx = start; | |
1975 while (idx < end) { | |
1976 if (idx + 2 < end && buf[idx] == 0 && buf[idx + 1] == 0 && buf[idx + 2] == 3) { | |
1977 nal_buf[nal_len++] = 0; | |
1978 nal_buf[nal_len++] = 0; | |
1979 idx += 3; | |
1980 } else { | |
1981 nal_buf[nal_len++] = buf[idx++]; | |
1982 } | |
1983 } | |
1984 while (idx < end) { | |
1985 nal_buf[nal_len++] = buf[idx++]; | |
1986 } | |
1987 *pnal_buf = nal_buf; | |
1988 *pnal_len = nal_len; | |
1989 return idx; | |
1990 } | |
1991 | |
1992 /* big endian variable length 7 bit encoding */ | |
1993 static void put_ue(uint8_t **pp, uint32_t v) | |
1994 { | |
1995 uint8_t *p = *pp; | |
1996 int i, j; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
1997 |
0 | 1998 for(i = 1; i < 5; i++) { |
1999 if (v < (1 << (7 * i))) | |
2000 break; | |
2001 } | |
2002 for(j = i - 1; j >= 1; j--) | |
2003 *p++ = ((v >> (7 * j)) & 0x7f) | 0x80; | |
2004 *p++ = v & 0x7f; | |
2005 *pp = p; | |
2006 } | |
2007 | |
2008 typedef struct { | |
2009 const uint8_t *buf; | |
2010 int idx; | |
2011 int buf_len; | |
2012 } GetBitState; | |
2013 | |
2014 static void init_get_bits(GetBitState *s, const uint8_t *buf, int buf_len) | |
2015 { | |
2016 s->buf = buf; | |
2017 s->buf_len = buf_len; | |
2018 s->idx = 0; | |
2019 } | |
2020 | |
2021 static void skip_bits(GetBitState *s, int n) | |
2022 { | |
2023 s->idx += n; | |
2024 } | |
2025 | |
2026 /* 1 <= n <= 25. return '0' bits if past the end of the buffer. */ | |
2027 static uint32_t get_bits(GetBitState *s, int n) | |
2028 { | |
2029 const uint8_t *buf = s->buf; | |
2030 int p, i; | |
2031 uint32_t v; | |
2032 | |
2033 p = s->idx >> 3; | |
2034 if ((p + 3) < s->buf_len) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2035 v = (buf[p] << 24) | (buf[p + 1] << 16) | |
0 | 2036 (buf[p + 2] << 8) | buf[p + 3]; |
2037 } else { | |
2038 v = 0; | |
2039 for(i = 0; i < 3; i++) { | |
2040 if ((p + i) < s->buf_len) | |
2041 v |= buf[p + i] << (24 - i * 8); | |
2042 } | |
2043 } | |
2044 v = (v >> (32 - (s->idx & 7) - n)) & ((1 << n) - 1); | |
2045 s->idx += n; | |
2046 return v; | |
2047 } | |
2048 | |
2049 /* 1 <= n <= 32 */ | |
2050 static uint32_t get_bits_long(GetBitState *s, int n) | |
2051 { | |
2052 uint32_t v; | |
2053 | |
2054 if (n <= 25) { | |
2055 v = get_bits(s, n); | |
2056 } else { | |
2057 n -= 16; | |
2058 v = get_bits(s, 16) << n; | |
2059 v |= get_bits(s, n); | |
2060 } | |
2061 return v; | |
2062 } | |
2063 | |
2064 /* at most 32 bits are supported */ | |
2065 static uint32_t get_ue_golomb(GetBitState *s) | |
2066 { | |
2067 int i; | |
2068 i = 0; | |
2069 for(;;) { | |
2070 if (get_bits(s, 1)) | |
2071 break; | |
2072 i++; | |
2073 if (i == 32) | |
2074 return 0xffffffff; | |
2075 } | |
2076 if (i == 0) | |
2077 return 0; | |
2078 else | |
2079 return ((1 << i) | get_bits_long(s, i)) - 1; | |
2080 } | |
2081 | |
2082 typedef struct { | |
2083 uint8_t *buf; | |
2084 int idx; | |
2085 } PutBitState; | |
2086 | |
2087 static void init_put_bits(PutBitState *s, uint8_t *buf) | |
2088 { | |
2089 s->buf = buf; | |
2090 s->idx = 0; | |
2091 } | |
2092 | |
2093 static void put_bit(PutBitState *s, int bit) | |
2094 { | |
2095 s->buf[s->idx >> 3] |= bit << (7 - (s->idx & 7)); | |
2096 s->idx++; | |
2097 } | |
2098 | |
2099 static void put_bits(PutBitState *s, int n, uint32_t v) | |
2100 { | |
2101 int i; | |
2102 | |
2103 for(i = 0; i < n; i++) { | |
2104 put_bit(s, (v >> (n - 1 - i)) & 1); | |
2105 } | |
2106 } | |
2107 | |
2108 static void put_ue_golomb(PutBitState *s, uint32_t v) | |
2109 { | |
2110 uint32_t a; | |
2111 int n; | |
2112 | |
2113 v++; | |
2114 n = 0; | |
2115 a = v; | |
2116 while (a != 0) { | |
2117 a >>= 1; | |
2118 n++; | |
2119 } | |
2120 if (n > 1) | |
2121 put_bits(s, n - 1, 0); | |
2122 put_bits(s, n, v); | |
2123 } | |
2124 | |
2125 typedef struct { | |
2126 uint8_t *buf; | |
2127 int size; | |
2128 int len; | |
2129 } DynBuf; | |
2130 | |
2131 static void dyn_buf_init(DynBuf *s) | |
2132 { | |
2133 s->buf = NULL; | |
2134 s->size = 0; | |
2135 s->len = 0; | |
2136 } | |
2137 | |
2138 static int dyn_buf_resize(DynBuf *s, int size) | |
2139 { | |
2140 int new_size; | |
2141 uint8_t *new_buf; | |
2142 | |
2143 if (size <= s->size) | |
2144 return 0; | |
2145 new_size = (s->size * 3) / 2; | |
2146 if (new_size < size) | |
2147 new_size = size; | |
2148 new_buf = realloc(s->buf, new_size); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2149 if (!new_buf) |
0 | 2150 return -1; |
2151 s->buf = new_buf; | |
2152 s->size = new_size; | |
2153 return 0; | |
2154 } | |
2155 | |
2156 /* suppress the VPS NAL and keep only the useful part of the SPS | |
2157 header. The decoder can rebuild a valid HEVC stream if needed. */ | |
2158 static int build_modified_sps(uint8_t **pout_buf, int *pout_buf_len, | |
2159 const uint8_t *buf, int buf_len) | |
2160 { | |
2161 int nal_unit_type, nal_len, idx, i, ret, msps_buf_len; | |
2162 int out_buf_len, out_buf_len_max; | |
2163 uint8_t *nal_buf, *msps_buf, *out_buf; | |
2164 GetBitState gb_s, *gb = &gb_s; | |
2165 PutBitState pb_s, *pb = &pb_s; | |
2166 uint8_t *p; | |
2167 | |
2168 idx = extract_nal(&nal_buf, &nal_len, buf, buf_len); | |
2169 if (idx < 0) | |
2170 return -1; | |
2171 if (nal_len < 2) { | |
2172 free(nal_buf); | |
2173 return -1; | |
2174 } | |
2175 nal_unit_type = (nal_buf[0] >> 1) & 0x3f; | |
2176 free(nal_buf); | |
2177 if (nal_unit_type != 32) { | |
2178 fprintf(stderr, "expecting VPS nal (%d)\n", nal_unit_type); | |
2179 return -1; /* expect VPS nal */ | |
2180 } | |
2181 | |
2182 ret = extract_nal(&nal_buf, &nal_len, buf + idx, buf_len); | |
2183 if (ret < 0) | |
2184 return -1; | |
2185 idx += ret; | |
2186 if (nal_len < 2) | |
2187 return -1; | |
2188 nal_unit_type = (nal_buf[0] >> 1) & 0x3f; | |
2189 if (nal_unit_type != 33) { | |
2190 fprintf(stderr, "expecting SPS nal (%d)\n", nal_unit_type); | |
2191 return -1; /* expect SPS nal */ | |
2192 } | |
2193 | |
2194 /* skip the initial part of the SPS up to and including | |
2195 log2_min_cb_size */ | |
2196 { | |
2197 int vps_id, max_sub_layers, profile_idc, sps_id; | |
2198 int chroma_format_idc, width, height, bit_depth_luma, bit_depth_chroma; | |
2199 int log2_max_poc_lsb, sublayer_ordering_info, log2_min_cb_size; | |
2200 int log2_diff_max_min_coding_block_size, log2_min_tb_size; | |
2201 int log2_diff_max_min_transform_block_size; | |
2202 int max_transform_hierarchy_depth_inter; | |
2203 int max_transform_hierarchy_depth_intra; | |
2204 int scaling_list_enable_flag, amp_enabled_flag, sao_enabled; | |
2205 int pcm_enabled_flag, nb_st_rps; | |
2206 int long_term_ref_pics_present_flag, sps_strong_intra_smoothing_enable_flag, vui_present; | |
2207 int sps_temporal_mvp_enabled_flag; | |
2208 int pcm_sample_bit_depth_luma_minus1; | |
2209 int pcm_sample_bit_depth_chroma_minus1; | |
2210 int log2_min_pcm_luma_coding_block_size_minus3; | |
2211 int log2_diff_max_min_pcm_luma_coding_block_size; | |
2212 int pcm_loop_filter_disabled_flag; | |
2213 int sps_extension_flag, sps_range_extension_flag, sps_extension_7bits; | |
2214 int sps_range_extension_flags; | |
2215 | |
2216 init_get_bits(gb, nal_buf, nal_len); | |
2217 skip_bits(gb, 16); /* nal header */ | |
2218 vps_id = get_bits(gb, 4); | |
2219 if (vps_id != 0) { | |
2220 fprintf(stderr, "VPS id 0 expected\n"); | |
2221 return -1; | |
2222 } | |
2223 max_sub_layers = get_bits(gb, 3); | |
2224 if (max_sub_layers != 0) { | |
2225 fprintf(stderr, "max_sub_layers == 0 expected\n"); | |
2226 return -1; | |
2227 } | |
2228 skip_bits(gb, 1); /* temporal_id_nesting_flag */ | |
2229 /* profile tier level */ | |
2230 skip_bits(gb, 2); /* profile_space */ | |
2231 skip_bits(gb, 1); /* tier_flag */ | |
2232 profile_idc = get_bits(gb, 5); | |
2233 for(i = 0; i < 32; i++) { | |
2234 skip_bits(gb, 1); /* profile_compatibility_flag */ | |
2235 } | |
2236 skip_bits(gb, 1); /* progressive_source_flag */ | |
2237 skip_bits(gb, 1); /* interlaced_source_flag */ | |
2238 skip_bits(gb, 1); /* non_packed_constraint_flag */ | |
2239 skip_bits(gb, 1); /* frame_only_constraint_flag */ | |
2240 skip_bits(gb, 44); /* XXX_reserved_zero_44 */ | |
2241 skip_bits(gb, 8); /* level_idc */ | |
2242 | |
2243 sps_id = get_ue_golomb(gb); | |
2244 if (sps_id != 0) { | |
2245 fprintf(stderr, "SPS id 0 expected (%d)\n", sps_id); | |
2246 return -1; | |
2247 } | |
2248 chroma_format_idc = get_ue_golomb(gb); | |
2249 if (chroma_format_idc == 3) { | |
2250 get_bits(gb, 1); /* separate_colour_plane_flag */ | |
2251 } | |
2252 width = get_ue_golomb(gb); | |
2253 height = get_ue_golomb(gb); | |
2254 /* pic conformance_flag */ | |
2255 if (get_bits(gb, 1)) { | |
2256 get_ue_golomb(gb); /* left_offset */ | |
2257 get_ue_golomb(gb); /* right_offset */ | |
2258 get_ue_golomb(gb); /* top_offset */ | |
2259 get_ue_golomb(gb); /* bottom_offset */ | |
2260 } | |
2261 bit_depth_luma = get_ue_golomb(gb) + 8; | |
2262 bit_depth_chroma = get_ue_golomb(gb) + 8; | |
2263 log2_max_poc_lsb = get_ue_golomb(gb) + 4; | |
2264 if (log2_max_poc_lsb != 8) { | |
2265 fprintf(stderr, "log2_max_poc_lsb must be 8 (%d)\n", log2_max_poc_lsb); | |
2266 return -1; | |
2267 } | |
2268 sublayer_ordering_info = get_bits(gb, 1); | |
2269 get_ue_golomb(gb); /* max_dec_pic_buffering */ | |
2270 get_ue_golomb(gb); /* num_reorder_pics */ | |
2271 get_ue_golomb(gb); /* max_latency_increase */ | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2272 |
0 | 2273 log2_min_cb_size = get_ue_golomb(gb) + 3; |
2274 log2_diff_max_min_coding_block_size = get_ue_golomb(gb); | |
2275 log2_min_tb_size = get_ue_golomb(gb) + 2; | |
2276 log2_diff_max_min_transform_block_size = get_ue_golomb(gb); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2277 |
0 | 2278 max_transform_hierarchy_depth_inter = get_ue_golomb(gb); |
2279 max_transform_hierarchy_depth_intra = get_ue_golomb(gb); | |
2280 if (max_transform_hierarchy_depth_inter != max_transform_hierarchy_depth_intra) { | |
2281 fprintf(stderr, "max_transform_hierarchy_depth_inter must be the same as max_transform_hierarchy_depth_intra (%d %d)\n", max_transform_hierarchy_depth_inter, max_transform_hierarchy_depth_intra); | |
2282 return -1; | |
2283 } | |
2284 | |
2285 scaling_list_enable_flag = get_bits(gb, 1); | |
2286 if (scaling_list_enable_flag != 0) { | |
2287 fprintf(stderr, "scaling_list_enable_flag must be 0\n"); | |
2288 return -1; | |
2289 } | |
2290 amp_enabled_flag = get_bits(gb, 1); | |
2291 if (!amp_enabled_flag) { | |
2292 fprintf(stderr, "amp_enabled_flag must be set\n"); | |
2293 return -1; | |
2294 } | |
2295 sao_enabled = get_bits(gb, 1); | |
2296 pcm_enabled_flag = get_bits(gb, 1); | |
2297 if (pcm_enabled_flag) { | |
2298 pcm_sample_bit_depth_luma_minus1 = get_bits(gb, 4); | |
2299 pcm_sample_bit_depth_chroma_minus1 = get_bits(gb, 4); | |
2300 log2_min_pcm_luma_coding_block_size_minus3 = get_ue_golomb(gb); | |
2301 log2_diff_max_min_pcm_luma_coding_block_size = get_ue_golomb(gb); | |
2302 pcm_loop_filter_disabled_flag = get_bits(gb, 1); | |
2303 } | |
2304 nb_st_rps = get_ue_golomb(gb); | |
2305 if (nb_st_rps != 0) { | |
2306 fprintf(stderr, "nb_st_rps must be 0 (%d)\n", nb_st_rps); | |
2307 return -1; | |
2308 } | |
2309 long_term_ref_pics_present_flag = get_bits(gb, 1); | |
2310 if (long_term_ref_pics_present_flag) { | |
2311 fprintf(stderr, "nlong_term_ref_pics_present_flag must be 0 (%d)\n", nb_st_rps); | |
2312 return -1; | |
2313 } | |
2314 sps_temporal_mvp_enabled_flag = get_bits(gb, 1); | |
2315 if (!sps_temporal_mvp_enabled_flag) { | |
2316 fprintf(stderr, "sps_temporal_mvp_enabled_flag must be set\n"); | |
2317 return -1; | |
2318 } | |
2319 sps_strong_intra_smoothing_enable_flag = get_bits(gb, 1); | |
2320 vui_present = get_bits(gb, 1); | |
2321 if (vui_present) { | |
2322 int sar_present, sar_idx, overscan_info_present_flag; | |
2323 int video_signal_type_present_flag, chroma_loc_info_present_flag; | |
2324 int default_display_window_flag, vui_timing_info_present_flag; | |
2325 int vui_poc_proportional_to_timing_flag; | |
2326 int vui_hrd_parameters_present_flag, bitstream_restriction_flag; | |
2327 | |
2328 sar_present = get_bits(gb, 1); | |
2329 if (sar_present) { | |
2330 sar_idx = get_bits(gb, 8); | |
2331 if (sar_idx == 255) { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2332 skip_bits(gb, 16); /* sar_num */ |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2333 skip_bits(gb, 16); /* sar_den */ |
0 | 2334 } |
2335 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2336 |
0 | 2337 overscan_info_present_flag = get_bits(gb, 1); |
2338 if (overscan_info_present_flag) { | |
2339 skip_bits(gb, 1); /* overscan_appropriate_flag */ | |
2340 } | |
2341 | |
2342 video_signal_type_present_flag = get_bits(gb, 1); | |
2343 if (video_signal_type_present_flag) { | |
2344 fprintf(stderr, "video_signal_type_present_flag must be 0\n"); | |
2345 return -1; | |
2346 } | |
2347 chroma_loc_info_present_flag = get_bits(gb, 1); | |
2348 if (chroma_loc_info_present_flag) { | |
2349 get_ue_golomb(gb); | |
2350 get_ue_golomb(gb); | |
2351 } | |
2352 skip_bits(gb, 1); /* neutra_chroma_indication_flag */ | |
2353 skip_bits(gb, 1); | |
2354 skip_bits(gb, 1); | |
2355 default_display_window_flag = get_bits(gb, 1); | |
2356 if (default_display_window_flag) { | |
2357 fprintf(stderr, "default_display_window_flag must be 0\n"); | |
2358 return -1; | |
2359 } | |
2360 vui_timing_info_present_flag = get_bits(gb, 1); | |
2361 if (vui_timing_info_present_flag) { | |
2362 skip_bits(gb, 32); | |
2363 skip_bits(gb, 32); | |
2364 vui_poc_proportional_to_timing_flag = get_bits(gb, 1); | |
2365 if (vui_poc_proportional_to_timing_flag) { | |
2366 get_ue_golomb(gb); | |
2367 } | |
2368 vui_hrd_parameters_present_flag = get_bits(gb, 1); | |
2369 if (vui_hrd_parameters_present_flag) { | |
2370 fprintf(stderr, "vui_hrd_parameters_present_flag must be 0\n"); | |
2371 return -1; | |
2372 } | |
2373 } | |
2374 bitstream_restriction_flag = get_bits(gb, 1); | |
2375 if (bitstream_restriction_flag) { | |
2376 skip_bits(gb, 1); | |
2377 skip_bits(gb, 1); | |
2378 skip_bits(gb, 1); | |
2379 get_ue_golomb(gb); | |
2380 get_ue_golomb(gb); | |
2381 get_ue_golomb(gb); | |
2382 get_ue_golomb(gb); | |
2383 get_ue_golomb(gb); | |
2384 } | |
2385 } | |
2386 sps_extension_flag = get_bits(gb, 1); | |
2387 sps_range_extension_flag = 0; | |
2388 sps_range_extension_flags = 0; | |
2389 if (sps_extension_flag) { | |
2390 sps_range_extension_flag = get_bits(gb, 1); | |
2391 sps_extension_7bits = get_bits(gb, 7); | |
2392 if (sps_extension_7bits != 0) { | |
2393 fprintf(stderr, "sps_extension_7bits must be 0\n"); | |
2394 return -1; | |
2395 } | |
2396 if (sps_range_extension_flag) { | |
2397 sps_range_extension_flags = get_bits(gb, 9); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2398 if (sps_range_extension_flags & ((1 << (8 - 3)) | |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2399 (1 << (8 - 4)) | |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2400 (1 << (8 - 6)) | |
0 | 2401 (1 << (8 - 8)))) { |
2402 fprintf(stderr, "unsupported range extensions (0x%x)\n", | |
2403 sps_range_extension_flags); | |
2404 return -1; | |
2405 } | |
2406 } | |
2407 } | |
2408 | |
2409 /* build the modified SPS */ | |
2410 msps_buf = malloc(nal_len + 32); | |
2411 memset(msps_buf, 0, nal_len + 16); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2412 |
0 | 2413 init_put_bits(pb, msps_buf); |
2414 put_ue_golomb(pb, log2_min_cb_size - 3); | |
2415 put_ue_golomb(pb, log2_diff_max_min_coding_block_size); | |
2416 put_ue_golomb(pb, log2_min_tb_size - 2); | |
2417 put_ue_golomb(pb, log2_diff_max_min_transform_block_size); | |
2418 put_ue_golomb(pb, max_transform_hierarchy_depth_intra); | |
2419 put_bits(pb, 1, sao_enabled); | |
2420 put_bits(pb, 1, pcm_enabled_flag); | |
2421 if (pcm_enabled_flag) { | |
2422 put_bits(pb, 4, pcm_sample_bit_depth_luma_minus1); | |
2423 put_bits(pb, 4, pcm_sample_bit_depth_chroma_minus1); | |
2424 put_ue_golomb(pb, log2_min_pcm_luma_coding_block_size_minus3); | |
2425 put_ue_golomb(pb, log2_diff_max_min_pcm_luma_coding_block_size); | |
2426 put_bits(pb, 1, pcm_loop_filter_disabled_flag); | |
2427 } | |
2428 put_bits(pb, 1, sps_strong_intra_smoothing_enable_flag); | |
2429 put_bits(pb, 1, sps_extension_flag); | |
2430 if (sps_extension_flag) { | |
2431 put_bits(pb, 1, sps_range_extension_flag); | |
2432 put_bits(pb, 7, 0); | |
2433 if (sps_range_extension_flag) { | |
2434 put_bits(pb, 9, sps_range_extension_flags); | |
2435 } | |
2436 } | |
2437 msps_buf_len = (pb->idx + 7) >> 3; | |
2438 | |
2439 out_buf_len_max = 5 + msps_buf_len; | |
2440 out_buf = malloc(out_buf_len_max); | |
2441 | |
2442 // printf("msps_n_bits=%d\n", pb->idx); | |
2443 p = out_buf; | |
2444 put_ue(&p, msps_buf_len); /* header length */ | |
2445 | |
2446 memcpy(p, msps_buf, msps_buf_len); | |
2447 p += msps_buf_len; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2448 |
0 | 2449 out_buf_len = p - out_buf; |
2450 free(msps_buf); | |
2451 free(nal_buf); | |
2452 } | |
2453 *pout_buf = out_buf; | |
2454 *pout_buf_len = out_buf_len; | |
2455 return idx; | |
2456 } | |
2457 | |
2458 static int add_frame_duration_sei(DynBuf *out_buf, uint16_t frame_ticks) | |
2459 { | |
2460 uint8_t nal_buf[128], *q; | |
2461 int nut, nal_len; | |
2462 | |
2463 q = nal_buf; | |
2464 *q++ = 0x00; | |
2465 *q++ = 0x00; | |
2466 *q++ = 0x01; | |
2467 nut = 39; /* prefix SEI NUT */ | |
2468 *q++ = (nut << 1); | |
2469 *q++ = 1; | |
2470 *q++ = 0xff; /* payload_type = 257 */ | |
2471 *q++ = 0x02; | |
2472 *q++ = 2; /* payload_size = 2 */ | |
2473 *q++ = frame_ticks >> 8; | |
2474 *q++ = frame_ticks; | |
2475 *q++ = 0x80; /* extra '1' bit and align to byte */ | |
2476 /* Note: the 0x00 0x00 b pattern with b <= 3 cannot happen, so no | |
2477 need to escape */ | |
2478 nal_len = q - nal_buf; | |
2479 if (dyn_buf_resize(out_buf, out_buf->len + nal_len) < 0) | |
2480 return -1; | |
2481 memcpy(out_buf->buf + out_buf->len, nal_buf, nal_len); | |
2482 out_buf->len += nal_len; | |
2483 return 0; | |
2484 } | |
2485 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2486 static int build_modified_hevc(uint8_t **pout_buf, |
0 | 2487 const uint8_t *cbuf, int cbuf_len, |
2488 const uint8_t *abuf, int abuf_len, | |
2489 const uint16_t *frame_duration_tab, | |
2490 int frame_count) | |
2491 { | |
2492 DynBuf out_buf_s, *out_buf = &out_buf_s; | |
2493 uint8_t *msps; | |
2494 const uint8_t *nal_buf; | |
2495 int msps_len, cidx, aidx, is_alpha, nal_len, first_nal, start, l, frame_num; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2496 |
0 | 2497 dyn_buf_init(out_buf); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2498 |
0 | 2499 /* add alpha MSPS */ |
2500 aidx = 0; /* avoids warning */ | |
2501 if (abuf) { | |
2502 aidx = build_modified_sps(&msps, &msps_len, abuf, abuf_len); | |
2503 if (aidx < 0) | |
2504 goto fail; | |
2505 if (dyn_buf_resize(out_buf, out_buf->len + msps_len) < 0) | |
2506 goto fail; | |
2507 memcpy(out_buf->buf + out_buf->len, msps, msps_len); | |
2508 out_buf->len += msps_len; | |
2509 free(msps); | |
2510 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2511 |
0 | 2512 /* add color MSPS */ |
2513 cidx = build_modified_sps(&msps, &msps_len, cbuf, cbuf_len); | |
2514 if (cidx < 0) | |
2515 goto fail; | |
2516 if (dyn_buf_resize(out_buf, out_buf->len + msps_len) < 0) | |
2517 goto fail; | |
2518 memcpy(out_buf->buf + out_buf->len, msps, msps_len); | |
2519 out_buf->len += msps_len; | |
2520 free(msps); | |
2521 | |
2522 /* add the remaining NALs, alternating between alpha (if present) | |
2523 and color. */ | |
2524 is_alpha = (abuf != NULL); | |
2525 first_nal = 1; | |
2526 frame_num = 0; | |
2527 for(;;) { | |
2528 if (!is_alpha) { | |
2529 if (cidx >= cbuf_len) { | |
2530 if (abuf) { | |
2531 fprintf(stderr, "Incorrect number of alpha NALs\n"); | |
2532 goto fail; | |
2533 } | |
2534 break; | |
2535 } | |
2536 nal_buf = cbuf + cidx; | |
2537 nal_len = find_nal_end(nal_buf, cbuf_len - cidx); | |
2538 // printf("cidx=%d/%d nal_len=%d\n", cidx, cbuf_len, nal_len); | |
2539 if (nal_len < 0) | |
2540 goto fail; | |
2541 cidx += nal_len; | |
2542 } else { | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2543 if (aidx >= abuf_len) |
0 | 2544 break; |
2545 nal_buf = abuf + aidx; | |
2546 nal_len = find_nal_end(nal_buf, abuf_len - aidx); | |
2547 // printf("aidx=%d/%d nal_len=%d\n", aidx, abuf_len, nal_len); | |
2548 if (nal_len < 0) | |
2549 goto fail; | |
2550 aidx += nal_len; | |
2551 } | |
2552 start = 3 + (nal_buf[2] == 0); | |
2553 if (!is_alpha) { | |
2554 int nut; | |
2555 /* add SEI NAL for the frame duration (animation case) */ | |
2556 nut = (nal_buf[start] >> 1) & 0x3f; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2557 if ((nut <= 9 || (nut >= 16 && nut <= 21)) && |
0 | 2558 start + 2 < nal_len && (nal_buf[start + 2] & 0x80)) { |
2559 int frame_ticks; | |
2560 assert(frame_num < frame_count); | |
2561 frame_ticks = frame_duration_tab[frame_num]; | |
2562 if (frame_ticks > 1) { | |
2563 add_frame_duration_sei(out_buf, frame_ticks); | |
2564 } | |
2565 frame_num++; | |
2566 } | |
2567 } | |
2568 if (first_nal) { | |
2569 /* skip first start code */ | |
2570 l = start; | |
2571 } else { | |
2572 l = 0; | |
2573 } | |
2574 if (dyn_buf_resize(out_buf, out_buf->len + nal_len - l) < 0) | |
2575 goto fail; | |
2576 // printf("add nal len=%d\n", nal_len - l); | |
2577 memcpy(out_buf->buf + out_buf->len, nal_buf + l, nal_len - l); | |
2578 if (is_alpha) { | |
2579 /* set nul_layer_id of alpha to '1' */ | |
2580 out_buf->buf[out_buf->len + (start - l) + 1] |= 1 << 3; | |
2581 } | |
2582 out_buf->len += nal_len - l; | |
2583 | |
2584 if (abuf) { | |
2585 is_alpha ^= 1; | |
2586 } | |
2587 first_nal = 0; | |
2588 } | |
2589 *pout_buf = out_buf->buf; | |
2590 return out_buf->len; | |
2591 fail: | |
2592 free(out_buf->buf); | |
2593 return -1; | |
2594 } | |
2595 | |
2596 typedef enum { | |
2597 #if defined(USE_X265) | |
2598 HEVC_ENCODER_X265, | |
2599 #endif | |
2600 #if defined(USE_JCTVC) | |
2601 HEVC_ENCODER_JCTVC, | |
2602 #endif | |
2603 | |
2604 HEVC_ENCODER_COUNT, | |
2605 } HEVCEncoderEnum; | |
2606 | |
2607 static char *hevc_encoder_name[HEVC_ENCODER_COUNT] = { | |
2608 #if defined(USE_X265) | |
2609 "x265", | |
2610 #endif | |
2611 #if defined(USE_JCTVC) | |
2612 "jctvc", | |
2613 #endif | |
2614 }; | |
2615 | |
2616 static HEVCEncoder *hevc_encoder_tab[HEVC_ENCODER_COUNT] = { | |
2617 #if defined(USE_X265) | |
2618 &x265_hevc_encoder, | |
2619 #endif | |
2620 #if defined(USE_JCTVC) | |
2621 &jctvc_encoder, | |
2622 #endif | |
2623 }; | |
2624 | |
2625 #define IMAGE_HEADER_MAGIC 0x425047fb | |
2626 | |
2627 #define DEFAULT_OUTFILENAME "out.bpg" | |
2628 #define DEFAULT_QP 29 | |
2629 #define DEFAULT_BIT_DEPTH 8 | |
2630 | |
2631 #ifdef RExt__HIGH_BIT_DEPTH_SUPPORT | |
2632 #define BIT_DEPTH_MAX 14 | |
2633 #else | |
2634 #define BIT_DEPTH_MAX 12 | |
2635 #endif | |
2636 #define DEFAULT_COMPRESS_LEVEL 8 | |
2637 | |
2638 | |
2639 typedef struct BPGEncoderContext BPGEncoderContext; | |
2640 | |
2641 typedef struct BPGEncoderParameters { | |
2642 int qp; /* 0 ... 51 */ | |
2643 int alpha_qp; /* -1 ... 51. -1 means same as qp */ | |
2644 int lossless; /* true if lossless compression (qp and alpha_qp are | |
2645 ignored) */ | |
2646 BPGImageFormatEnum preferred_chroma_format; | |
2647 int sei_decoded_picture_hash; /* 0, 1 */ | |
2648 int compress_level; /* 1 ... 9 */ | |
2649 int verbose; | |
2650 HEVCEncoderEnum encoder_type; | |
2651 int animated; /* 0 ... 1: if true, encode as animated image */ | |
2652 uint16_t loop_count; /* animations: number of loops. 0=infinite */ | |
2653 /* animations: the frame delay is a multiple of | |
2654 frame_delay_num/frame_delay_den seconds */ | |
2655 uint16_t frame_delay_num; | |
2656 uint16_t frame_delay_den; | |
2657 } BPGEncoderParameters; | |
2658 | |
2659 typedef int BPGEncoderWriteFunc(void *opaque, const uint8_t *buf, int buf_len); | |
2660 | |
2661 struct BPGEncoderContext { | |
2662 BPGEncoderParameters params; | |
2663 BPGMetaData *first_md; | |
2664 HEVCEncoder *encoder; | |
2665 int frame_count; | |
2666 HEVCEncoderContext *enc_ctx; | |
2667 HEVCEncoderContext *alpha_enc_ctx; | |
2668 int frame_ticks; | |
2669 uint16_t *frame_duration_tab; | |
2670 int frame_duration_tab_size; | |
2671 }; | |
2672 | |
2673 void *mallocz(size_t size) | |
2674 { | |
2675 void *ptr; | |
2676 ptr = malloc(size); | |
2677 if (!ptr) | |
2678 return NULL; | |
2679 memset(ptr, 0, size); | |
2680 return ptr; | |
2681 } | |
2682 | |
2683 BPGEncoderParameters *bpg_encoder_param_alloc(void) | |
2684 { | |
2685 BPGEncoderParameters *p; | |
2686 p = mallocz(sizeof(BPGEncoderParameters)); | |
2687 if (!p) | |
2688 return NULL; | |
2689 p->qp = DEFAULT_QP; | |
2690 p->alpha_qp = -1; | |
2691 p->preferred_chroma_format = BPG_FORMAT_420; | |
2692 p->compress_level = DEFAULT_COMPRESS_LEVEL; | |
2693 p->frame_delay_num = 1; | |
2694 p->frame_delay_den = 25; | |
2695 p->loop_count = 0; | |
2696 return p; | |
2697 } | |
2698 | |
2699 void bpg_encoder_param_free(BPGEncoderParameters *p) | |
2700 { | |
2701 free(p); | |
2702 } | |
2703 | |
2704 BPGEncoderContext *bpg_encoder_open(BPGEncoderParameters *p) | |
2705 { | |
2706 BPGEncoderContext *s; | |
2707 | |
2708 s = mallocz(sizeof(BPGEncoderContext)); | |
2709 if (!s) | |
2710 return NULL; | |
2711 s->params = *p; | |
2712 s->encoder = hevc_encoder_tab[s->params.encoder_type]; | |
2713 s->frame_ticks = 1; | |
2714 return s; | |
2715 } | |
2716 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2717 void bpg_encoder_set_extension_data(BPGEncoderContext *s, |
0 | 2718 BPGMetaData *md) |
2719 { | |
2720 s->first_md = md; | |
2721 } | |
2722 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2723 static int bpg_encoder_encode_trailer(BPGEncoderContext *s, |
0 | 2724 BPGEncoderWriteFunc *write_func, |
2725 void *opaque) | |
2726 { | |
2727 uint8_t *out_buf, *alpha_buf, *hevc_buf; | |
2728 int out_buf_len, alpha_buf_len, hevc_buf_len; | |
2729 | |
2730 out_buf_len = s->encoder->close(s->enc_ctx, &out_buf); | |
2731 if (out_buf_len < 0) { | |
2732 fprintf(stderr, "Error while encoding picture\n"); | |
2733 exit(1); | |
2734 } | |
2735 s->enc_ctx = NULL; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2736 |
0 | 2737 alpha_buf = NULL; |
2738 alpha_buf_len = 0; | |
2739 if (s->alpha_enc_ctx) { | |
2740 alpha_buf_len = s->encoder->close(s->alpha_enc_ctx, &alpha_buf); | |
2741 if (alpha_buf_len < 0) { | |
2742 fprintf(stderr, "Error while encoding picture (alpha plane)\n"); | |
2743 exit(1); | |
2744 } | |
2745 s->alpha_enc_ctx = NULL; | |
2746 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2747 |
0 | 2748 hevc_buf = NULL; |
2749 hevc_buf_len = build_modified_hevc(&hevc_buf, out_buf, out_buf_len, | |
2750 alpha_buf, alpha_buf_len, | |
2751 s->frame_duration_tab, s->frame_count); | |
2752 if (hevc_buf_len < 0) { | |
2753 fprintf(stderr, "Error while creating HEVC data\n"); | |
2754 exit(1); | |
2755 } | |
2756 free(out_buf); | |
2757 free(alpha_buf); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2758 |
0 | 2759 if (write_func(opaque, hevc_buf, hevc_buf_len) != hevc_buf_len) { |
2760 fprintf(stderr, "Error while writing HEVC data\n"); | |
2761 exit(1); | |
2762 } | |
2763 free(hevc_buf); | |
2764 return 0; | |
2765 } | |
2766 | |
2767 int bpg_encoder_set_frame_duration(BPGEncoderContext *s, int frame_ticks) | |
2768 { | |
2769 if (frame_ticks >= 1 && frame_ticks <= 65535) { | |
2770 s->frame_ticks = frame_ticks; | |
2771 return 0; | |
2772 } else { | |
2773 return -1; | |
2774 } | |
2775 } | |
2776 | |
2777 /* Warning: currently 'img' is modified. When encoding animations, img | |
2778 = NULL indicates the end of the stream. */ | |
2779 int bpg_encoder_encode(BPGEncoderContext *s, Image *img, | |
2780 BPGEncoderWriteFunc *write_func, | |
2781 void *opaque) | |
2782 { | |
2783 const BPGEncoderParameters *p = &s->params; | |
2784 Image *img_alpha; | |
2785 HEVCEncodeParams ep_s, *ep = &ep_s; | |
2786 uint8_t *extension_buf; | |
2787 int extension_buf_len; | |
2788 int cb_size, width, height; | |
2789 | |
2790 if (p->animated && !img) { | |
2791 return bpg_encoder_encode_trailer(s, write_func, opaque); | |
2792 } | |
2793 | |
2794 /* extract the alpha plane */ | |
2795 if (img->has_alpha) { | |
2796 int c_idx; | |
2797 | |
2798 img_alpha = malloc(sizeof(Image)); | |
2799 memset(img_alpha, 0, sizeof(*img_alpha)); | |
2800 if (img->format == BPG_FORMAT_GRAY) | |
2801 c_idx = 1; | |
2802 else | |
2803 c_idx = 3; | |
2804 | |
2805 img_alpha->w = img->w; | |
2806 img_alpha->h = img->h; | |
2807 img_alpha->format = BPG_FORMAT_GRAY; | |
2808 img_alpha->has_alpha = 0; | |
2809 img_alpha->color_space = BPG_CS_YCbCr; | |
2810 img_alpha->bit_depth = img->bit_depth; | |
2811 img_alpha->pixel_shift = img->pixel_shift; | |
2812 img_alpha->data[0] = img->data[c_idx]; | |
2813 img_alpha->linesize[0] = img->linesize[c_idx]; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2814 |
0 | 2815 img->data[c_idx] = NULL; |
2816 img->has_alpha = 0; | |
2817 } else { | |
2818 img_alpha = NULL; | |
2819 } | |
2820 | |
2821 if (img->format == BPG_FORMAT_444 && img->color_space != BPG_CS_RGB) { | |
2822 if (p->preferred_chroma_format == BPG_FORMAT_420 || | |
2823 p->preferred_chroma_format == BPG_FORMAT_420_VIDEO) { | |
2824 int c_h_phase = (p->preferred_chroma_format == BPG_FORMAT_420); | |
2825 if (image_ycc444_to_ycc420(img, c_h_phase) != 0) | |
2826 goto error_convert; | |
2827 } else if (p->preferred_chroma_format == BPG_FORMAT_422 || | |
2828 p->preferred_chroma_format == BPG_FORMAT_422_VIDEO) { | |
2829 int c_h_phase = (p->preferred_chroma_format == BPG_FORMAT_422); | |
2830 if (image_ycc444_to_ycc422(img, c_h_phase) != 0) { | |
2831 error_convert: | |
2832 fprintf(stderr, "Cannot convert image\n"); | |
2833 exit(1); | |
2834 } | |
2835 } | |
2836 } | |
2837 | |
2838 cb_size = 8; /* XXX: should make it configurable. We assume the | |
2839 HEVC encoder uses the same value */ | |
2840 width = img->w; | |
2841 height = img->h; | |
2842 image_pad(img, cb_size); | |
2843 if (img_alpha) | |
2844 image_pad(img_alpha, cb_size); | |
2845 | |
2846 /* convert to the allocated pixel width to 8 bit if needed by the | |
2847 HEVC encoder */ | |
2848 if (img->bit_depth == 8) { | |
2849 image_convert16to8(img); | |
2850 if (img_alpha) | |
2851 image_convert16to8(img_alpha); | |
2852 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2853 |
0 | 2854 if (s->frame_count == 0) { |
2855 memset(ep, 0, sizeof(*ep)); | |
2856 ep->qp = p->qp; | |
2857 ep->width = img->w; | |
2858 ep->height = img->h; | |
2859 ep->chroma_format = img->format; | |
2860 ep->bit_depth = img->bit_depth; | |
2861 ep->intra_only = !p->animated; | |
2862 ep->lossless = p->lossless; | |
2863 ep->sei_decoded_picture_hash = p->sei_decoded_picture_hash; | |
2864 ep->compress_level = p->compress_level; | |
2865 ep->verbose = p->verbose; | |
2866 | |
2867 s->enc_ctx = s->encoder->open(ep); | |
2868 if (!s->enc_ctx) { | |
2869 fprintf(stderr, "Error while opening encoder\n"); | |
2870 exit(1); | |
2871 } | |
2872 | |
2873 if (img_alpha) { | |
2874 if (p->alpha_qp < 0) | |
2875 ep->qp = p->qp; | |
2876 else | |
2877 ep->qp = p->alpha_qp; | |
2878 ep->chroma_format = 0; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2879 |
0 | 2880 s->alpha_enc_ctx = s->encoder->open(ep); |
2881 if (!s->alpha_enc_ctx) { | |
2882 fprintf(stderr, "Error while opening alpha encoder\n"); | |
2883 exit(1); | |
2884 } | |
2885 } | |
2886 | |
2887 /* prepare the extension data */ | |
2888 if (p->animated) { | |
2889 BPGMetaData *md; | |
2890 uint8_t buf[15], *q; | |
2891 | |
2892 md = bpg_md_alloc(BPG_EXTENSION_TAG_ANIM_CONTROL); | |
2893 q = buf; | |
2894 put_ue(&q, p->loop_count); | |
2895 put_ue(&q, p->frame_delay_num); | |
2896 put_ue(&q, p->frame_delay_den); | |
2897 md->buf_len = q - buf; | |
2898 md->buf = malloc(md->buf_len); | |
2899 memcpy(md->buf, buf, md->buf_len); | |
2900 md->next = s->first_md; | |
2901 s->first_md = md; | |
2902 } | |
2903 | |
2904 extension_buf = NULL; | |
2905 extension_buf_len = 0; | |
2906 if (s->first_md) { | |
2907 BPGMetaData *md1; | |
2908 int max_len; | |
2909 uint8_t *q; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2910 |
0 | 2911 max_len = 0; |
2912 for(md1 = s->first_md; md1 != NULL; md1 = md1->next) { | |
2913 max_len += md1->buf_len + 5 * 2; | |
2914 } | |
2915 extension_buf = malloc(max_len); | |
2916 q = extension_buf; | |
2917 for(md1 = s->first_md; md1 != NULL; md1 = md1->next) { | |
2918 put_ue(&q, md1->tag); | |
2919 put_ue(&q, md1->buf_len); | |
2920 memcpy(q, md1->buf, md1->buf_len); | |
2921 q += md1->buf_len; | |
2922 } | |
2923 extension_buf_len = q - extension_buf; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2924 |
0 | 2925 bpg_md_free(s->first_md); |
2926 s->first_md = NULL; | |
2927 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2928 |
0 | 2929 { |
2930 uint8_t img_header[128], *q; | |
2931 int v, has_alpha, has_extension, alpha2_flag, alpha1_flag, format; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2932 |
0 | 2933 has_alpha = (img_alpha != NULL); |
2934 has_extension = (extension_buf_len > 0); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2935 |
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2936 |
0 | 2937 if (has_alpha) { |
2938 if (img->has_w_plane) { | |
2939 alpha1_flag = 0; | |
2940 alpha2_flag = 1; | |
2941 } else { | |
2942 alpha1_flag = 1; | |
2943 alpha2_flag = img->premultiplied_alpha; | |
2944 } | |
2945 } else { | |
2946 alpha1_flag = 0; | |
2947 alpha2_flag = 0; | |
2948 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2949 |
0 | 2950 q = img_header; |
2951 *q++ = (IMAGE_HEADER_MAGIC >> 24) & 0xff; | |
2952 *q++ = (IMAGE_HEADER_MAGIC >> 16) & 0xff; | |
2953 *q++ = (IMAGE_HEADER_MAGIC >> 8) & 0xff; | |
2954 *q++ = (IMAGE_HEADER_MAGIC >> 0) & 0xff; | |
2955 | |
2956 if (img->c_h_phase == 0 && img->format == BPG_FORMAT_420) | |
2957 format = BPG_FORMAT_420_VIDEO; | |
2958 else if (img->c_h_phase == 0 && img->format == BPG_FORMAT_422) | |
2959 format = BPG_FORMAT_422_VIDEO; | |
2960 else | |
2961 format = img->format; | |
2962 v = (format << 5) | (alpha1_flag << 4) | (img->bit_depth - 8); | |
2963 *q++ = v; | |
2964 v = (img->color_space << 4) | (has_extension << 3) | | |
2965 (alpha2_flag << 2) | (img->limited_range << 1) | | |
2966 p->animated; | |
2967 *q++ = v; | |
2968 put_ue(&q, width); | |
2969 put_ue(&q, height); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2970 |
0 | 2971 put_ue(&q, 0); /* zero length means up to the end of the file */ |
2972 if (has_extension) { | |
2973 put_ue(&q, extension_buf_len); /* extension data length */ | |
2974 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2975 |
0 | 2976 write_func(opaque, img_header, q - img_header); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2977 |
0 | 2978 if (has_extension) { |
2979 if (write_func(opaque, extension_buf, extension_buf_len) != extension_buf_len) { | |
2980 fprintf(stderr, "Error while writing extension data\n"); | |
2981 exit(1); | |
2982 } | |
2983 free(extension_buf); | |
2984 } | |
2985 } | |
2986 } | |
2987 | |
2988 /* store the frame duration */ | |
2989 if ((s->frame_count + 1) > s->frame_duration_tab_size) { | |
2990 s->frame_duration_tab_size = (s->frame_duration_tab_size * 3) / 2; | |
2991 if (s->frame_duration_tab_size < (s->frame_count + 1)) | |
2992 s->frame_duration_tab_size = (s->frame_count + 1); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2993 s->frame_duration_tab = realloc(s->frame_duration_tab, |
0 | 2994 sizeof(s->frame_duration_tab) * s->frame_duration_tab_size); |
2995 } | |
2996 s->frame_duration_tab[s->frame_count] = s->frame_ticks; | |
2997 | |
2998 s->encoder->encode(s->enc_ctx, img); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
2999 |
0 | 3000 if (img_alpha) { |
3001 s->encoder->encode(s->alpha_enc_ctx, img_alpha); | |
3002 image_free(img_alpha); | |
3003 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3004 |
0 | 3005 s->frame_count++; |
3006 | |
3007 if (!p->animated) | |
3008 bpg_encoder_encode_trailer(s, write_func, opaque); | |
3009 | |
3010 return 0; | |
3011 } | |
3012 | |
3013 void bpg_encoder_close(BPGEncoderContext *s) | |
3014 { | |
3015 free(s->frame_duration_tab); | |
3016 bpg_md_free(s->first_md); | |
3017 free(s); | |
3018 } | |
3019 | |
3020 static int my_write_func(void *opaque, const uint8_t *buf, int buf_len) | |
3021 { | |
3022 FILE *f = opaque; | |
3023 return fwrite(buf, 1, buf_len, f); | |
3024 } | |
3025 | |
3026 static int get_filename_num(char *buf, int buf_size, const char *str, int n) | |
3027 { | |
15
29527d65b71a
Fix assigned-but-unused variable warning.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
3028 const char *p; |
0 | 3029 char *q; |
3030 int l, c; | |
3031 | |
3032 q = buf; | |
3033 p = str; | |
3034 for(;;) { | |
3035 c = *p++; | |
3036 if (c == '\0') | |
3037 break; | |
3038 if (c == '%') { | |
3039 l = 0; | |
3040 for(;;) { | |
3041 c = *p; | |
3042 if (c < '0' || c > '9') | |
3043 break; | |
3044 l = l * 10 + (c - '0'); | |
3045 p++; | |
3046 } | |
3047 c = *p++; | |
3048 if (c == '%') { | |
3049 goto add_char; | |
3050 } else if (c != 'd') { | |
3051 return -1; | |
3052 } | |
3053 snprintf(q, buf + buf_size - q, "%0*u", l, n); | |
3054 q += strlen(q); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3055 |
0 | 3056 } else { |
3057 add_char: | |
3058 if ((q - buf) < buf_size - 1) | |
3059 *q++ = c; | |
3060 } | |
3061 } | |
3062 *q = '\0'; | |
3063 return 0; | |
3064 } | |
3065 | |
3066 void help(int is_full) | |
3067 { | |
3068 char hevc_encoders[128]; | |
3069 int i; | |
3070 | |
3071 hevc_encoders[0] = '\0'; | |
3072 for(i = 0; i < HEVC_ENCODER_COUNT; i++) { | |
3073 if (i != 0) | |
3074 strcat(hevc_encoders, " "); | |
3075 strcat(hevc_encoders, hevc_encoder_name[i]); | |
3076 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3077 |
0 | 3078 printf("BPG Image Encoder version " CONFIG_BPG_VERSION "\n" |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3079 "usage: bpgenc [options] infile.[jpg|png|tiff]\n" |
0 | 3080 "\n" |
3081 "Main options:\n" | |
3082 "-h show the full help (including the advanced options)\n" | |
3083 "-o outfile set output filename (default = %s)\n" | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3084 "-q qp set quantizer parameter (smaller gives better quality,\n" |
0 | 3085 " range: 0-51, default = %d)\n" |
3086 "-f cfmt set the preferred chroma format (420, 422, 444,\n" | |
3087 " default=420)\n" | |
3088 "-c color_space set the preferred color space (ycbcr, rgb, ycgco,\n" | |
3089 " ycbcr_bt709, ycbcr_bt2020, default=ycbcr)\n" | |
3090 "-b bit_depth set the bit depth (8 to %d, default = %d)\n" | |
3091 "-lossless enable lossless mode\n" | |
3092 "-e encoder select the HEVC encoder (%s, default = %s)\n" | |
3093 "-m level select the compression level (1=fast, 9=slow, default = %d)\n" | |
3094 "\n" | |
3095 "Animation options:\n" | |
3096 "-a generate animations from a sequence of images. Use %%d or\n" | |
3097 " %%Nd (N = number of digits) in the filename to specify the\n" | |
3098 " image index, starting from 0 or 1.\n" | |
3099 "-fps N set the frame rate (default = 25)\n" | |
3100 "-loop N set the number of times the animation is played. 0 means\n" | |
3101 " infinite (default = 0)\n" | |
3102 "-delayfile file text file containing one number per image giving the\n" | |
3103 " display delay per image in centiseconds.\n" | |
3104 , DEFAULT_OUTFILENAME, DEFAULT_QP, BIT_DEPTH_MAX, DEFAULT_BIT_DEPTH, | |
3105 hevc_encoders, hevc_encoder_name[0], DEFAULT_COMPRESS_LEVEL); | |
3106 | |
3107 if (is_full) { | |
3108 printf("\nAdvanced options:\n" | |
3109 "-alphaq set quantizer parameter for the alpha channel (default = same as -q value)\n" | |
3110 "-premul store the color with premultiplied alpha\n" | |
3111 "-limitedrange encode the color data with the limited range of video\n" | |
3112 "-hash include MD5 hash in HEVC bitstream\n" | |
3113 "-keepmetadata keep the metadata (from JPEG: EXIF, ICC profile, XMP, from PNG: ICC profile)\n" | |
3114 "-v show debug messages\n" | |
25 | 3115 ); |
0 | 3116 } |
3117 | |
3118 exit(1); | |
3119 } | |
3120 | |
3121 struct option long_opts[] = { | |
16
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3122 { "hash" , no_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3123 { "keepmetadata" , no_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3124 { "alphaq" , required_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3125 { "lossless" , no_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3126 { "limitedrange" , no_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3127 { "premul" , no_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3128 { "loop" , required_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3129 { "fps" , required_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3130 { "delayfile" , required_argument , NULL, 0 }, |
86b6c976ef2d
Fix some warnings by adding missing field initializers for long opts.
Matti Hamalainen <ccr@tnsp.org>
parents:
15
diff
changeset
|
3131 { NULL , 0 , NULL, 0 }, |
0 | 3132 }; |
3133 | |
3134 int main(int argc, char **argv) | |
3135 { | |
3136 const char *infilename, *outfilename, *frame_delay_file; | |
3137 Image *img; | |
3138 FILE *f; | |
3139 int c, option_index; | |
3140 int keep_metadata; | |
3141 int bit_depth, i, limited_range, premultiplied_alpha; | |
3142 BPGColorSpaceEnum color_space; | |
3143 BPGMetaData *md; | |
3144 BPGEncoderContext *enc_ctx; | |
3145 BPGEncoderParameters *p; | |
3146 | |
3147 p = bpg_encoder_param_alloc(); | |
3148 | |
3149 outfilename = DEFAULT_OUTFILENAME; | |
3150 color_space = BPG_CS_YCbCr; | |
3151 keep_metadata = 0; | |
3152 bit_depth = DEFAULT_BIT_DEPTH; | |
3153 limited_range = 0; | |
3154 premultiplied_alpha = 0; | |
3155 frame_delay_file = NULL; | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3156 |
0 | 3157 for(;;) { |
3158 c = getopt_long_only(argc, argv, "q:o:hf:c:vm:b:e:a", long_opts, &option_index); | |
3159 if (c == -1) | |
3160 break; | |
3161 switch(c) { | |
3162 case 0: | |
3163 switch(option_index) { | |
3164 case 0: | |
3165 p->sei_decoded_picture_hash = 1; | |
3166 break; | |
3167 case 1: | |
3168 keep_metadata = 1; | |
3169 break; | |
3170 case 2: | |
3171 p->alpha_qp = atoi(optarg); | |
3172 if (p->alpha_qp < 0 || p->alpha_qp > 51) { | |
3173 fprintf(stderr, "alpha_qp must be between 0 and 51\n"); | |
3174 exit(1); | |
3175 } | |
3176 break; | |
3177 case 3: | |
3178 p->lossless = 1; | |
3179 color_space = BPG_CS_RGB; | |
3180 p->preferred_chroma_format = BPG_FORMAT_444; | |
3181 bit_depth = 8; | |
3182 limited_range = 0; | |
3183 break; | |
3184 case 4: | |
3185 limited_range = 1; | |
3186 break; | |
3187 case 5: | |
3188 premultiplied_alpha = 1; | |
3189 break; | |
3190 case 6: | |
3191 p->loop_count = strtoul(optarg, NULL, 0); | |
3192 break; | |
3193 case 7: | |
3194 p->frame_delay_num = 1; | |
3195 p->frame_delay_den = strtoul(optarg, NULL, 0); | |
3196 if (p->frame_delay_den == 0) { | |
3197 fprintf(stderr, "invalid frame rate\n"); | |
3198 exit(1); | |
3199 } | |
3200 break; | |
3201 case 8: | |
3202 frame_delay_file = optarg; | |
3203 break; | |
3204 default: | |
3205 goto show_help; | |
3206 } | |
3207 break; | |
3208 case 'h': | |
3209 show_help: | |
3210 help(1); | |
3211 break; | |
3212 case 'q': | |
3213 p->qp = atoi(optarg); | |
3214 if (p->qp < 0 || p->qp > 51) { | |
3215 fprintf(stderr, "qp must be between 0 and 51\n"); | |
3216 exit(1); | |
3217 } | |
3218 break; | |
3219 case 'o': | |
3220 outfilename = optarg; | |
3221 break; | |
3222 case 'f': | |
3223 if (!strcmp(optarg, "420")) { | |
3224 p->preferred_chroma_format = BPG_FORMAT_420; | |
3225 } else if (!strcmp(optarg, "422")) { | |
3226 p->preferred_chroma_format = BPG_FORMAT_422; | |
3227 } else if (!strcmp(optarg, "444")) { | |
3228 p->preferred_chroma_format = BPG_FORMAT_444; | |
3229 } else if (!strcmp(optarg, "422_video")) { | |
3230 p->preferred_chroma_format = BPG_FORMAT_422_VIDEO; | |
3231 } else if (!strcmp(optarg, "420_video")) { | |
3232 p->preferred_chroma_format = BPG_FORMAT_420_VIDEO; | |
3233 } else { | |
3234 fprintf(stderr, "Invalid chroma format\n"); | |
3235 exit(1); | |
3236 } | |
3237 break; | |
3238 case 'c': | |
3239 if (!strcmp(optarg, "ycbcr")) { | |
3240 color_space = BPG_CS_YCbCr; | |
3241 } else if (!strcmp(optarg, "rgb")) { | |
3242 color_space = BPG_CS_RGB; | |
3243 p->preferred_chroma_format = BPG_FORMAT_444; | |
3244 } else if (!strcmp(optarg, "ycgco")) { | |
3245 color_space = BPG_CS_YCgCo; | |
3246 } else if (!strcmp(optarg, "ycbcr_bt709")) { | |
3247 color_space = BPG_CS_YCbCr_BT709; | |
3248 } else if (!strcmp(optarg, "ycbcr_bt2020")) { | |
3249 color_space = BPG_CS_YCbCr_BT2020; | |
3250 } else { | |
3251 fprintf(stderr, "Invalid color space format\n"); | |
3252 exit(1); | |
3253 } | |
3254 break; | |
3255 case 'm': | |
3256 p->compress_level = atoi(optarg); | |
3257 if (p->compress_level < 1) | |
3258 p->compress_level = 1; | |
3259 else if (p->compress_level > 9) | |
3260 p->compress_level = 9; | |
3261 break; | |
3262 case 'b': | |
3263 bit_depth = atoi(optarg); | |
3264 if (bit_depth < 8 || bit_depth > BIT_DEPTH_MAX) { | |
3265 fprintf(stderr, "Invalid bit depth (range: 8 to %d)\n", | |
3266 BIT_DEPTH_MAX); | |
3267 exit(1); | |
3268 } | |
3269 break; | |
3270 case 'v': | |
3271 p->verbose++; | |
3272 break; | |
3273 case 'e': | |
3274 for(i = 0; i < HEVC_ENCODER_COUNT; i++) { | |
3275 if (!strcmp(optarg, hevc_encoder_name[i])) | |
3276 break; | |
3277 } | |
3278 if (i == HEVC_ENCODER_COUNT) { | |
3279 fprintf(stderr, "Unsupported encoder. Available ones are:"); | |
3280 for(i = 0; i < HEVC_ENCODER_COUNT; i++) { | |
3281 fprintf(stderr, " %s", hevc_encoder_name[i]); | |
3282 } | |
3283 fprintf(stderr, "\n"); | |
3284 exit(1); | |
3285 } | |
3286 p->encoder_type = i; | |
3287 break; | |
3288 case 'a': | |
3289 p->animated = 1; | |
3290 break; | |
3291 default: | |
3292 exit(1); | |
3293 } | |
3294 } | |
3295 | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3296 if (optind >= argc) |
0 | 3297 help(0); |
3298 infilename = argv[optind]; | |
3299 | |
3300 f = fopen(outfilename, "wb"); | |
3301 if (!f) { | |
3302 perror(outfilename); | |
3303 exit(1); | |
3304 } | |
3305 | |
3306 enc_ctx = bpg_encoder_open(p); | |
3307 if (!enc_ctx) { | |
3308 fprintf(stderr, "Could not open BPG encoder\n"); | |
3309 exit(1); | |
3310 } | |
3311 | |
3312 if (p->animated) { | |
3313 int frame_num, first_frame, frame_ticks; | |
3314 char filename[1024]; | |
3315 FILE *f1; | |
3316 | |
3317 if (frame_delay_file) { | |
3318 f1 = fopen(frame_delay_file, "r"); | |
3319 if (!f1) { | |
3320 fprintf(stderr, "Could not open '%s'\n", frame_delay_file); | |
3321 exit(1); | |
3322 } | |
3323 } else { | |
3324 f1 = NULL; | |
3325 } | |
3326 | |
3327 first_frame = 1; | |
3328 for(frame_num = 0; ; frame_num++) { | |
3329 if (get_filename_num(filename, sizeof(filename), infilename, frame_num) < 0) { | |
3330 fprintf(stderr, "Invalid filename syntax: '%s'\n", infilename); | |
3331 exit(1); | |
3332 } | |
3333 img = load_image(&md, filename, color_space, bit_depth, limited_range, | |
3334 premultiplied_alpha); | |
3335 if (!img) { | |
3336 if (frame_num == 0) | |
3337 continue; /* accept to start at 0 or 1 */ | |
3338 if (first_frame) { | |
3339 fprintf(stderr, "Could not read '%s'\n", filename); | |
3340 exit(1); | |
3341 } else { | |
3342 break; | |
3343 } | |
3344 } | |
3345 frame_ticks = 1; | |
3346 if (f1) { | |
3347 float fdelay; | |
3348 if (fscanf(f1, "%f", &fdelay) == 1) { | |
3349 frame_ticks = lrint(fdelay * p->frame_delay_den / (p->frame_delay_num * 100)); | |
3350 if (frame_ticks < 1) | |
3351 frame_ticks = 1; | |
3352 } | |
3353 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3354 |
0 | 3355 if (p->verbose) |
3356 printf("Encoding '%s' ticks=%d\n", filename, frame_ticks); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3357 |
0 | 3358 if (keep_metadata && first_frame) { |
3359 bpg_encoder_set_extension_data(enc_ctx, md); | |
3360 } else { | |
3361 bpg_md_free(md); | |
3362 } | |
3363 bpg_encoder_set_frame_duration(enc_ctx, frame_ticks); | |
3364 bpg_encoder_encode(enc_ctx, img, my_write_func, f); | |
3365 image_free(img); | |
3366 | |
3367 first_frame = 0; | |
3368 } | |
3369 if (f1) | |
3370 fclose(f1); | |
3371 /* end of stream */ | |
3372 bpg_encoder_encode(enc_ctx, NULL, my_write_func, f); | |
3373 } else { | |
3374 img = load_image(&md, infilename, color_space, bit_depth, limited_range, | |
3375 premultiplied_alpha); | |
3376 if (!img) { | |
3377 fprintf(stderr, "Could not read '%s'\n", infilename); | |
3378 exit(1); | |
3379 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3380 |
0 | 3381 if (!keep_metadata && md) { |
3382 bpg_md_free(md); | |
3383 md = NULL; | |
3384 } | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3385 |
0 | 3386 bpg_encoder_set_extension_data(enc_ctx, md); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3387 |
0 | 3388 bpg_encoder_encode(enc_ctx, img, my_write_func, f); |
3389 image_free(img); | |
3390 } | |
3391 | |
3392 fclose(f); | |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3393 |
0 | 3394 bpg_encoder_close(enc_ctx); |
5
524eae707ba4
Cosmetics: Remove trailing whitespace.
Matti Hamalainen <ccr@tnsp.org>
parents:
4
diff
changeset
|
3395 |
0 | 3396 bpg_encoder_param_free(p); |
3397 | |
3398 return 0; | |
3399 } |