1 /*
2 Copyright (C) 2017-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 /*
7 WARNING: This file was generated by the dkct program (see
8 http://dktools.sourceforge.net/ for details).
9 Changes you make here will be lost if dkct is run again!
10 You should modify the original source and run dkct on it.
11 Original source: dk4bifj.ctr
12 */
13
14 /** @file dk4bifj.c The dk4bifj module.
15 */
16
17
18 #include "dk4conf.h"
19
20 #if DK4_HAVE_JPEGLIB_H
21
22 #ifndef DK4MEM_H_INCLUDED
23 #include <libdk4base/dk4mem.h>
24 #endif
25
26 #ifndef DK4MAASZ_H_INCLUDED
27 #include <libdk4ma/dk4maasz.h>
28 #endif
29
30 #ifndef DK4BIFTY_H_INCLUDED
31 #include <libdk4bif/dk4bifty.h>
32 #endif
33
34 #ifndef DK4BIF_H_INCLUDED
35 #include <libdk4bif/dk4bif.h>
36 #endif
37
38 #ifndef BIF_H_INCLUDED
39 #include <libdk4bif/bif.h>
40 #endif
41
42 #ifndef JPEGLIB_H_INCLUDED
43 #include <jpeglib.h>
44 #define JPEGLIB_H_INCLUDED 1
45 #endif
46
47 #if DK4_HAVE_SETJMP_H
48 #ifndef SETJMP_H_INCLUDED
49 #include <setjmp.h>
50 #define SETJMP_H_INCLUDED 1
51 #endif
52 #endif
53
54 #if DK4_HAVE_ASSERT_H
55 #ifndef ASSERT_H_INCLUDED
56 #include <assert.h>
57 #define ASSERT_H_INCLUDED 1
58 #endif
59 #endif
60
61
62
63
64
65
66 /** Error manager for jpeglib.
67 */
68 typedef struct {
69 struct jpeg_error_mgr errmgr; /**< Default error manager. */
70 #if DK4_HAVE_SETJMP_H
71 jmp_buf jump_buf; /**< Longjump buffer. */
72 #endif
73 } dk4_bif_jpeg_error_mgr;
74
75
76
77 /** Routine called instead of simple exit on failures.
78 @param cinfo Object containing address of error manager.
79 */
80 static
81 void
dk4bifjpb_error_exit(j_common_ptr cinfo)82 dk4bifjpb_error_exit(j_common_ptr cinfo)
83 {
84 dk4_bif_jpeg_error_mgr *errmgr; /* Error manager structure */
85
86 errmgr = (dk4_bif_jpeg_error_mgr *)(cinfo->err);
87 if (NULL != errmgr) {
88 longjmp(errmgr->jump_buf, 1);
89 }
90
91 }
92
93
94
95 void
dk4bifjpeg_nc_release_per_frame_data(void * tsdata,dk4_bif_frame_t * frptr)96 dk4bifjpeg_nc_release_per_frame_data(
97 void *tsdata,
98 dk4_bif_frame_t *frptr
99 )
100 {
101 JSAMPLE **rptr; /* Array of row pointers */
102 dk4_bif_jpeg_per_frame_t *jfptr; /* Per-frame data */
103 JDIMENSION i; /* Traverse all lines */
104
105
106 #if DK4_USE_ASSERT
107 assert(NULL != tsdata);
108 assert(NULL != frptr);
109 #endif
110 jfptr = (dk4_bif_jpeg_per_frame_t *)tsdata;
111 if (NULL != jfptr) {
112 rptr = jfptr->rows;
113 if (NULL != rptr) {
114 for (i = 0; (dk4_bif_dim_t)i < frptr->dim_y; i++) {
115
116 if (NULL != *rptr) { dk4mem_free(*rptr); }
117 rptr++;
118 }
119
120 dk4mem_free(jfptr->rows);
121 }
122
123 dk4mem_free(jfptr);
124 }
125
126 }
127
128
129
130 /** Transfer information from JPEG structures into BIF structures.
131 @param bifp Bitmap image file to modify.
132 @param pfd Per-frame data structure to modify.
133 @param cinfo JPEG decompression structure (data source).
134 @param sov Flag: Set output variables in cinfo.
135 */
136 static
137 void
dk4bifjpeg_transfer_header_data(dk4_bif_t * bifp,dk4_bif_jpeg_per_frame_t * pfd,struct jpeg_decompress_struct * cinfo,int sov)138 dk4bifjpeg_transfer_header_data(
139 dk4_bif_t *bifp,
140 dk4_bif_jpeg_per_frame_t *pfd,
141 struct jpeg_decompress_struct *cinfo,
142 int sov
143 )
144 {
145
146 #if DK4_USE_ASSERT
147 assert(NULL != bifp);
148 assert(NULL != pfd);
149 assert(NULL != cinfo);
150 #endif
151 bifp->cf->dim_x = cinfo->image_width;
152
153 bifp->cf->dim_y = cinfo->image_height;
154
155 bifp->cf->l_bdepth = BITS_IN_JSAMPLE;
156
157 bifp->cf->r_bdepth = BITS_IN_JSAMPLE;
158
159
160 bifp->cf->bg[0] = MAXJSAMPLE;
161 bifp->cf->bg[1] = MAXJSAMPLE;
162 bifp->cf->bg[2] = MAXJSAMPLE;
163 bifp->cf->bg[3] = MAXJSAMPLE;
164 bifp->cf->bglbd[0] = MAXJSAMPLE;
165 bifp->cf->bglbd[1] = MAXJSAMPLE;
166 bifp->cf->bglbd[2] = MAXJSAMPLE;
167 bifp->cf->bglbd[3] = MAXJSAMPLE;
168 dk4pxres_setup(&(bifp->cf->resampler), MAXJSAMPLE, MAXJSAMPLE);
169 bifp->cf->n_comp = (size_t)(cinfo->out_color_components);
170
171 bifp->cf->hbg = 0;
172 bifp->cf->res_x = -1.0;
173 bifp->cf->res_y = -1.0;
174 if (0 != cinfo->saw_JFIF_marker) {
175 if ((0 < cinfo->X_density) && (0 < cinfo->Y_density)) {
176 bifp->cf->res_x = (double)(cinfo->X_density);
177 bifp->cf->res_y = (double)(cinfo->Y_density);
178
179
180 if (2 == cinfo->density_unit) {
181 bifp->cf->res_x *= 2.54;
182 bifp->cf->res_y *= 2.54;
183
184
185 }
186 if (1 != cinfo->density_unit) {
187 bifp->cf->res_x = -1.0;
188 bifp->cf->res_y = -1.0;
189 }
190 }
191 }
192 switch (cinfo->jpeg_color_space) {
193 case JCS_GRAYSCALE: {
194 bifp->cf->l_cs = DK4_CS_GRAY;
195 bifp->cf->f_cs = DK4_CS_GRAY;
196 if (0 != sov) {
197 cinfo->out_color_space = JCS_GRAYSCALE;
198 }
199 } break;
200 case JCS_CMYK: {
201 bifp->cf->l_cs = DK4_CS_CMYK;
202 bifp->cf->f_cs = DK4_CS_CMYK;
203 if (0 != sov) {
204 cinfo->out_color_space = JCS_CMYK;
205 }
206 } break;
207 /*
208 2018-03-20
209 If the library internal color space is JCS_YCCK or JCS_YCbCr
210 the library functions to access pixel data deliver RGB values.
211 So the default branch sets the color space to RGB.
212 */
213 #if 0
214 case JCS_RGB: {
215 bifp->cf->l_cs = DK4_CS_RGB;
216 bifp->cf->f_cs = DK4_CS_RGB;
217 } break;
218 case JCS_YCCK: {
219 bifp->cf->l_cs = DK4_CS_CMYK;
220 bifp->cf->f_cs = DK4_CS_CMYK;
221 } break;
222 case JCS_YCbCr: {
223 bifp->cf->l_cs = DK4_CS_CMYK;
224 bifp->cf->f_cs = DK4_CS_CMYK;
225 } break;
226 #endif
227 default: {
228 bifp->cf->l_cs = DK4_CS_RGB;
229 bifp->cf->f_cs = DK4_CS_RGB;
230 if (0 != sov) {
231 cinfo->out_color_space = JCS_RGB;
232 }
233 } break;
234 }
235 pfd->num_comp = (size_t)cinfo->out_color_components;
236
237 pfd->is_adobe = ((0 != cinfo->saw_Adobe_marker) ? 1 : 0);
238
239
240 }
241
242
243
244 dk4_bif_t *
dk4bifjpeg_nc_open_file(FILE * fipo,dkChar const * fn,int honly,dk4_cs_conv_ctx_t const * pcsctx,dk4_bif_jpg_clobbered_t * jpgcp,dk4_er_t * erp)245 dk4bifjpeg_nc_open_file(
246 FILE *fipo,
247 dkChar const *fn,
248 int honly,
249 dk4_cs_conv_ctx_t const *pcsctx,
250 dk4_bif_jpg_clobbered_t *jpgcp,
251 dk4_er_t *erp
252 )
253 {
254 struct jpeg_decompress_struct cinfo; /* Jpeglib reader */
255 dk4_bif_jpeg_error_mgr errmgr; /* Jpeglib error man */
256 dk4_er_t er; /* Error report */
257 JSAMPLE **xrptr = NULL; /* Travers rows */
258 dk4_bif_jpeg_per_frame_t *pfd = NULL; /* Per-frame data */
259 size_t bpl = 0; /* Bits per line */
260 size_t i = 0; /* Traverse rows */
261
262
263 /* Create bif and frame for one-frame image
264 */
265 jpgcp->back = dk4biftool_nc_new_for_one_frame(
266 fn, DK4_BIF_TYPE_JPEG, honly, pcsctx, erp
267 );
268 if (NULL == jpgcp->back) { goto finished; }
269
270
271 /* Allocate per-frame data structure
272 */
273 pfd = dk4mem_new(dk4_bif_jpeg_per_frame_t,1,NULL);
274 if (NULL == pfd) { goto finished; }
275 (jpgcp->back->cf)->tsdata = pfd;
276
277
278 /* Initialize per-frame data structure components
279 */
280 pfd->rows = NULL;
281 pfd->num_comp = 0;
282 pfd->is_adobe = 0;
283
284 /* Set up error management
285 */
286 cinfo.err = jpeg_std_error(&(errmgr.errmgr));
287 errmgr.errmgr.error_exit = dk4bifjpb_error_exit;
288
289
290 /* Code below calls setjmp on error
291 */
292 if (0 != setjmp(errmgr.jump_buf)) {
293 dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
294 goto finished;
295 }
296
297 /* Create decompression structure
298 */
299 jpgcp->st = 1;
300 jpeg_create_decompress(&cinfo);
301
302
303 /* Specify data source
304 */
305 jpeg_stdio_src(&cinfo, fipo);
306
307
308 /* Read JPEG header data
309 */
310 jpeg_read_header(&cinfo, TRUE);
311
312
313 /* Transfer header data to bif structures.
314 */
315 dk4bifjpeg_transfer_header_data(jpgcp->back, pfd, &cinfo, 1);
316
317
318 /* When reading just the header we are done here
319 */
320 if (0 != honly) {
321 jpgcp->ok = 1;
322
323 goto finished;
324 }
325
326 /* Start decompression
327 */
328 jpeg_start_decompress(&cinfo);
329
330
331 /* Header data are now corrected if necessary, read information again
332 */
333 dk4bifjpeg_transfer_header_data(jpgcp->back, pfd, &cinfo, 0);
334
335
336 /* Allocate memory for image data
337 */
338 dk4error_init(&er);
339 bpl = dk4ma_size_t_mul(
340 (size_t)(jpgcp->back->cf->dim_x), jpgcp->back->cf->n_comp, &er
341 );
342 if (DK4_E_NONE != er.ec) {
343 dk4error_copy(erp, &er);
344 goto finished;
345 }
346 pfd->rows = dk4mem_new(JSAMPROW,((size_t)(jpgcp->back->cf->dim_y)),erp);
347 if (NULL == pfd->rows) { goto finished; }
348 xrptr = pfd->rows;
349 for (i = 0; i < (size_t)(jpgcp->back->cf->dim_y); i++) { *(xrptr++) = NULL; }
350 xrptr = pfd->rows;
351 for (i = 0; i < (size_t)(jpgcp->back->cf->dim_y); i++) {
352 *xrptr = dk4mem_new(JSAMPLE,bpl,erp);
353 if (NULL == *xrptr) {
354 goto finished;
355 }
356 xrptr++;
357 }
358
359
360 /* Read and decompress data
361 */
362 xrptr = pfd->rows;
363 for (i = 0; i < (size_t)(jpgcp->back->cf->dim_y); i++) {
364 jpeg_read_scanlines(&cinfo, xrptr, 1);
365 xrptr++;
366 }
367
368
369 /* Finish decompression
370 */
371 jpeg_finish_decompress(&cinfo);
372
373
374 /* Everything done, success
375 */
376 jpgcp->ok = 1;
377
378 finished:
379 /*
380 Destroy decompression structure
381 */
382 if (0 < jpgcp->st) {
383 jpeg_destroy_decompress(&cinfo);
384 }
385 if (0 == jpgcp->ok) {
386 if (NULL != jpgcp->back) {
387 dk4bif_close(jpgcp->back);
388 jpgcp->back = NULL;
389 }
390 }
391
392
393 return jpgcp->back;
394 }
395
396
397
398 int
dk4bifjpeg_nc_get_original_pixel(dk4_px_t * dptr,size_t szdptr,dk4_bif_t const * bif,dk4_bif_dim_t rowno,dk4_bif_dim_t colno)399 dk4bifjpeg_nc_get_original_pixel(
400 dk4_px_t *dptr,
401 size_t szdptr,
402 dk4_bif_t const *bif,
403 dk4_bif_dim_t rowno,
404 dk4_bif_dim_t colno
405 )
406 {
407 dk4_er_t er; /* Error report for math op */
408 dk4_bif_jpeg_per_frame_t *pfd = NULL; /* Per-frame data */
409 size_t spos; /* Number of values per row */
410 size_t i; /* Traverse all components */
411 int back = 0;
412
413 #if DK4_USE_ASSERT
414 assert(NULL != dptr);
415 assert(0 < szdptr);
416 assert(NULL != bif);
417 #endif
418 pfd = (dk4_bif_jpeg_per_frame_t *)((bif->cf)->tsdata);
419 if (NULL != pfd) {
420 if (NULL != pfd->rows) {
421 dk4error_init(&er);
422 spos = dk4ma_size_t_mul((size_t)colno, pfd->num_comp, &er);
423 (void)dk4ma_size_t_add(spos, pfd->num_comp, &er);
424 if (DK4_E_NONE == er.ec) {
425 if (szdptr >= pfd->num_comp) {
426 for (i = 0; i < pfd->num_comp; i++) {
427 dptr[i] = ((pfd->rows)[rowno])[spos + i];
428 }
429 back = 1;
430 }
431 }
432 }
433 }
434
435 return back;
436 }
437
438
439 #endif
440 /* if DK4_HAVE_JPEGLIB_H */
441
442
443 /* vim: set ai sw=4 ts=4 : */
444
445