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