1 /*
2 Copyright (C) 2018-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: dk4bifap.ctr
12 */
13 
14 /**	@file dk4bifap.c The dk4bifap module.
15 */
16 
17 
18 #include "dk4conf.h"
19 
20 #if	DK4_HAVE_MATH_H
21 #ifndef	MATH_H_INCLUDED
22 #if	DK4_ON_WINDOWS
23 #ifndef	_USE_MATH_DEFINES
24 #define	_USE_MATH_DEFINES 1
25 #endif
26 #endif
27 #include <math.h>
28 #define	MATH_H_INCLUDED 1
29 #endif
30 #endif
31 
32 #ifndef	DK4MEM_H_INCLUDED
33 #include <libdk4base/dk4mem.h>
34 #endif
35 
36 #ifndef	DK4BIFAP_H_INCLUDED
37 #include <libdk4bifa/dk4bifap.h>
38 #endif
39 
40 #ifndef	BIF_H_INCLUDED
41 #include <libdk4bif/bif.h>
42 #endif
43 
44 #ifndef	DK4MAODD_H_INCLUDED
45 #include <libdk4maiodd/dk4maodd.h>
46 #endif
47 
48 #ifndef	DK4MAODDBL_H_INCLUDED
49 #include <libdk4maiodd/dk4maoddbl.h>
50 #endif
51 
52 #ifndef	DK4MATH_H_INCLUDED
53 #include <libdk4c/dk4math.h>
54 #endif
55 
56 #if DK4_HAVE_ASSERT_H
57 #ifndef	ASSERT_H_INCLUDED
58 #include <assert.h>
59 #define	ASSERT_H_INCLUDED 1
60 #endif
61 #endif
62 
63 
64 
65 
66 
67 /**	File name dummy to use when processing standard input.
68 */
69 static const dkChar		dk4bifap_def_fn[] = { dkT("<stdin>") };
70 
71 
72 
73 /**	File name of string table for localizted texts.
74 */
75 static const dkChar	dk4bifap_str[] = { dkT("dk4bif.str") };
76 
77 
78 
79 /**	Default texts for diagnostic messages if localized texts are not found.
80 */
81 static const dkChar * const	dk4bifap_kw[] = {
82 /* 0 */
83 dkT("File suffix does not inidicate a known image type!"),
84 
85 /* 1 */
86 dkT("Failed to open image!"),
87 
88 /* 2 */
89 dkT("Syntax error, file probably damaged!"),
90 
91 /* 3 */
92 dkT("Failed to open and/or read file!"),
93 
94 /* 4 */
95 dkT("File type not supported!"),
96 
97 /* 5 */
98 dkT("Invalid arguments provided to function call, probably bug!"),
99 
100 /* 6 */
101 dkT("Unusual maxval "),
102 
103 /* 7 */
104 dkT("!\n\tMay result in color distorsion!"),
105 
106 /* 8 */
107 dkT("Aspect ratio changed!\n\tChanging resolution from "),
108 
109 /* 9 */
110 dkT("/"),
111 
112 /* 10 */
113 dkT(" to "),
114 
115 /* 11 */
116 dkT("/"),
117 
118 /* 12 */
119 dkT(" dpi.\n\tThis will probably result in an image distorsion."),
120 
121 /* 13 */
122 dkT("Size reduced, image too large for LaTeX!"),
123 
124 NULL
125 
126 };
127 
128 
129 
130 /**	Report error using one text fragment.
131 	@param	app	Application structure.
132 	@param	si	Index of text fragment in dk4bifap_kw or
133 	list of localized texts.
134 */
135 static
136 void
dk4bifap_error_1(dk4_app_t * app,size_t si)137 dk4bifap_error_1(
138 	dk4_app_t	*app,
139 	size_t		 si
140 )
141 {
142 	const dkChar * const	*msg	=	dk4bifap_kw;	/* Localized texs */
143 	size_t					 sz_msg;					/* Size of msg array */
144 
145 	sz_msg = dk4app_string_table_size(dk4bifap_kw);
146 	msg = dk4app_string_table(app, dk4bifap_str, dk4bifap_kw);
147 	dk4app_log_1(app, msg, sz_msg, DK4_LL_ERROR, si);
148 }
149 
150 
151 
152 /**	Report warning using one text fragment.
153 	@param	app	Application structure.
154 	@param	si	Index of text fragment in dk4bifap_kw or
155 	list of localized texts.
156 */
157 static
158 void
dk4bifap_warning_1(dk4_app_t * app,size_t si)159 dk4bifap_warning_1(
160 	dk4_app_t	*app,
161 	size_t		 si
162 )
163 {
164 	const dkChar * const	*msg	=	dk4bifap_kw;	/* Localized texs */
165 	size_t					 sz_msg;					/* Size of msg array */
166 
167 	sz_msg = dk4app_string_table_size(dk4bifap_kw);
168 	msg = dk4app_string_table(app, dk4bifap_str, dk4bifap_kw);
169 	dk4app_log_1(app, msg, sz_msg, DK4_LL_WARNING, si);
170 }
171 
172 
173 
174 /**	Report errors from attempt to open a bitmap image file.
175 	@param	fn	File name to read.
176 	@param	erp	Error report containing error information.
177 	@param	app	Application structure for diagnostics, may be NULL.
178 */
179 static
180 void
dk4bif_error_open_app(dkChar const * fn,dk4_er_t * erp,dk4_app_t * app)181 dk4bif_error_open_app(
182 	dkChar		const	*fn,
183 	dk4_er_t			*erp,
184 	dk4_app_t			*app
185 )
186 {
187 	dkChar		const	*oldsourcefile;	/* Previous source file name to save */
188 	dk4_um_t			 oldsourceline;	/* Previous source line no to save */
189 	oldsourcefile = dk4app_get_log_source_file(app);
190 	oldsourceline = dk4app_get_log_source_line(app);
191 	if (NULL == fn) { fn = dk4bifap_def_fn; }
192 	dk4app_set_log_source_file(app, fn);
193 	dk4app_set_log_source_line(app, 0UL);
194 	dk4bifap_error_1(app, 1);
195 	switch (erp->ec) {
196 		case DK4_E_MEMORY_ALLOCATION_FAILED : {
197 			dk4app_log_base1(app, DK4_LL_ERROR, 90);
198 		} break;
199 		case DK4_E_SYNTAX : {
200 			dk4bifap_error_1(app, 2);
201 		} break;
202 		case DK4_E_MATH_OVERFLOW : {
203 			dk4app_log_base1(app, DK4_LL_ERROR, 82);
204 		} break;
205 		case DK4_E_NOT_FOUND : {
206 			dk4bifap_error_1(app, 0);
207 		} break;
208 		case DK4_E_READ_FAILED : {
209 			dk4bifap_error_1(app, 3);
210 		} break;
211 		case DK4_E_NOT_SUPPORTED : {
212 			dk4bifap_error_1(app, 4);
213 		} break;
214 		case DK4_E_INVALID_ARGUMENTS : {
215 			dk4bifap_error_1(app, 5);
216 		} break;
217 	}
218 	dk4app_set_log_source_file(app, oldsourcefile);
219 	dk4app_set_log_source_line(app, oldsourceline);
220 }
221 
222 
223 
224 /**	Check whether the bitmap image file is NetPBM type and has an
225 	unusual maxval, report unusual maxval.
226 	@param	bif	Bitmap image file to check.
227 	@param	app	Application structure for diagnostics, may be NULL.
228 */
229 static
230 void
dk4bifap_check_netpbm_maxval(dk4_bif_t * bif,dk4_app_t * app)231 dk4bifap_check_netpbm_maxval(
232 	dk4_bif_t	*bif,
233 	dk4_app_t	*app
234 )
235 {
236 	dkChar								 buf[16*sizeof(dk4_um_t)]; /* Buffer */
237 	dkChar const * const				*msg	= dk4bifap_kw;	/* Localized */
238 	dkChar						const	*oldsourcefile;	/* Previous src file */
239 	dk4_bif_netpbm_per_frame_t			*npfd;			/* Per-frame data */
240 	dk4_bif_frame_t						*frptr;			/* Current frame */
241 	dkChar						const	*fn = NULL;		/* File name */
242 	dk4_um_t							 oldsourceline;	/* Previous src line */
243 	size_t								 sz_msg;	/* Size of msg array */
244 	int									 res;		/* Operation result */
245 	dk4_px_t							 bdspec;	/* Maximum value for bpc */
246 	dk4_px_t							 bdmaxv;	/* Maxval */
247 
248 #if	DK4_USE_ASSERT
249 	assert(NULL != bif);
250 	assert(NULL != app);
251 #endif
252 	if ((NULL != bif) && (NULL != app)) {
253 		switch (bif->imgtype) {
254 			case DK4_BIF_TYPE_NETPBM : {
255 				dk4sto_it_reset(bif->i_frames);
256 				do {
257 					frptr = (dk4_bif_frame_t *)dk4sto_it_next(bif->i_frames);
258 					if (NULL != frptr) {
259 						npfd = (dk4_bif_netpbm_per_frame_t *)(frptr->tsdata);
260 						bdspec = dk4pxbit_get_max(npfd->bpc);
261 						bdmaxv = npfd->maxval;
262 						if (bdspec != bdmaxv) {
263 							fn = bif->filename;
264 							res = dk4ma_write_decimal_unsigned(
265 								buf, DK4_SIZEOF(buf,dkChar), bdmaxv, 0, NULL
266 							);
267 							if (0 != res) {
268 								oldsourcefile = dk4app_get_log_source_file(app);
269 								oldsourceline = dk4app_get_log_source_line(app);
270 								dk4app_set_log_source_file(app, fn);
271 								dk4app_set_log_source_line(app, (dk4_um_t)0UL);
272 								sz_msg = dk4app_string_table_size(dk4bifap_kw);
273 								msg = dk4app_string_table(
274 									app, dk4bifap_str, dk4bifap_kw
275 								);
276 								dk4app_log_3(
277 									app, msg, sz_msg, DK4_LL_WARNING, 6, 7, buf
278 								);
279 								dk4app_set_log_source_file(app, oldsourcefile);
280 								dk4app_set_log_source_line(app, oldsourceline);
281 							}
282 						}
283 					}
284 				} while (NULL != frptr);
285 				dk4sto_it_reset(bif->i_frames);
286 			} break;
287 		}
288 	}
289 
290 }
291 
292 
293 
294 dk4_bif_t *
dk4bif_open_app(dkChar const * fn,int honly,dk4_cs_conv_ctx_t const * pcsctx,dk4_app_t * app)295 dk4bif_open_app(
296 	dkChar				const	*fn,
297 	int							 honly,
298 	dk4_cs_conv_ctx_t	const	*pcsctx,
299 	dk4_app_t					*app
300 )
301 {
302 	dk4_er_t		 er;				/* Error report */
303 	dk4_bif_t		*back	= NULL;		/* Function result */
304 
305 #if	DK4_USE_ASSERT
306 	assert(NULL != fn);
307 #endif
308 	dk4error_init(&er);
309 	back = dk4bif_open(fn, honly, pcsctx, &er);
310 	if ((NULL == back) && (NULL != app)) {
311 
312 		dk4bif_error_open_app(fn, &er, app);
313 	}
314 	if (NULL != back) {
315 
316 		dk4bifap_check_netpbm_maxval(back, app);
317 	}
318 
319 	return back;
320 }
321 
322 
323 
324 dk4_bif_t *
dk4bif_open_file_app(FILE * fipo,dkChar const * fn,int ty,int honly,dk4_cs_conv_ctx_t const * pcsctx,dk4_app_t * app)325 dk4bif_open_file_app(
326 	FILE						*fipo,
327 	dkChar				const	*fn,
328 	int							 ty,
329 	int							 honly,
330 	dk4_cs_conv_ctx_t	const	*pcsctx,
331 	dk4_app_t					*app
332 )
333 {
334 	dk4_er_t		 er;
335 	dk4_bif_t		*back	= NULL;
336 
337 #if	DK4_USE_ASSERT
338 	assert(NULL != fipo);
339 #endif
340 	dk4error_init(&er);
341 	back = dk4bif_open_file(fipo, fn, ty, honly, pcsctx, &er);
342 	if ((NULL == back) && (NULL != app)) {
343 
344 		dk4bif_error_open_app(fn, &er, app);
345 	}
346 	if (NULL != back) {
347 
348 		dk4bifap_check_netpbm_maxval(back, app);
349 	}
350 
351 	return back;
352 }
353 
354 
355 
356 int
dk4bif_type_for_suffix_app(dkChar const * fn,dk4_app_t * app)357 dk4bif_type_for_suffix_app(
358 	dkChar		const	*fn,
359 	dk4_app_t			*app
360 )
361 {
362 	const dkChar	*oldsourcefile	=	NULL;	/* Previous source file name */
363 	dk4_um_t		 oldsourceline	=	0UL;	/* Previous source line no */
364 	int				 back	= -1;
365 
366 #if	DK4_USE_ASSERT
367 	assert(NULL != fn);
368 #endif
369 	if (NULL != fn) {
370 		back = dk4bif_type_for_suffix(fn);
371 		if ((0 > back) && (NULL != app)) {
372 			oldsourcefile = dk4app_get_log_source_file(app);
373 			oldsourceline = dk4app_get_log_source_line(app);
374 			dk4app_set_log_source_file(app, fn);
375 			dk4app_set_log_source_line(app, 0UL);
376 			/* ##### ERROR: Not a known bitmap image file type */
377 			dk4app_set_log_source_file(app, oldsourcefile);
378 			dk4app_set_log_source_line(app, oldsourceline);
379 		}
380 	}
381 
382 	return back;
383 }
384 
385 
386 
387 void
dk4bif_warn_aspect_ratio_change(dk4_bif_t * bif,double xres,double yres,dk4_app_t * app)388 dk4bif_warn_aspect_ratio_change(
389 	dk4_bif_t		*bif,
390 	double			 xres,
391 	double			 yres,
392 	dk4_app_t		*app
393 )
394 {
395 	dkChar	 b1[64];
396 	dkChar	 b2[64];
397 	dkChar	 b3[64];
398 	dkChar	 b4[64];
399 	const dkChar	*p[16];
400 	const dkChar	* const	*msg	=	dk4bifap_kw;
401 
402 #if	DK4_USE_ASSERT
403 	assert(NULL != bif);
404 #endif
405 	dk4ma_write_double(b1, 64, bif->cf->res_x, 0, 1, NULL);
406 	dk4ma_write_double(b2, 64, bif->cf->res_y, 0, 1, NULL);
407 	dk4ma_write_double(b3, 64, xres, 0, 1, NULL);
408 	dk4ma_write_double(b4, 64, yres, 0, 1, NULL);
409 	/* WARNING: Resolution setting changes aspect ratio */
410 	msg = dk4app_string_table(app, dk4bifap_str, dk4bifap_kw);
411 	p[0] = msg[8];
412 	p[1] = b1;
413 	p[2] = msg[9];
414 	p[3] = b2;
415 	p[4] = msg[10];
416 	p[5] = b3;
417 	p[6] = msg[11];
418 	p[7] = b4;
419 	p[8] = msg[12];
420 	dk4app_log_msg(app, DK4_LL_WARNING, p, 9);
421 
422 }
423 
424 
425 
426 int
dk4bif_set_res_app(dk4_bif_t * bif,double xres,double yres,dk4_app_t * app)427 dk4bif_set_res_app(
428 	dk4_bif_t			*bif,
429 	double				 xres,
430 	double				 yres,
431 	dk4_app_t			*app
432 )
433 {
434 	double	 qo;			/* Quotient of old resolutions */
435 	double	 qn;			/* Quotient of new resolutions */
436 	int		 back	= 0;
437 
438 #if	DK4_USE_ASSERT
439 	assert(NULL != bif);
440 	assert(0.0 < xres);
441 	assert(0.0 < yres);
442 #endif
443 	if ((NULL != bif) && (0.0 < xres) && (0.0 < yres)) {
444 		if (NULL != bif->cf) {
445 			if ((0.0 < bif->cf->res_x) && (0.0 < bif->cf->res_y)) {
446 
447 				qo = bif->cf->res_y / bif->cf->res_x;
448 				qn = yres / xres;
449 				if ((0 != dk4ma_is_finite(qo)) && (0 != dk4ma_is_finite(qn))) {
450 					if (DK4_BIF_EPSILON_ASPECT <= fabs(qn - qo)) {
451 						dk4bif_warn_aspect_ratio_change(
452 							bif, xres, yres, app
453 						);
454 					}
455 				}
456 			}
457 			bif->cf->res_x = xres;
458 			bif->cf->res_y = yres;
459 			back = 1;
460 		}
461 	}
462 	else {
463 		/* ERROR: Invalid arguments */
464 	}
465 
466 	return back;
467 }
468 
469 
470 
471 /**	Correct resolution for one frame to ensure dimensions suitable for LaTeX.
472 	@param	pfrm	Frame to process.
473 	@param	app		Application structure for diagnostics, may be NULL.
474 */
475 static
476 void
dk4bif_frame_restrict_size(dk4_bif_frame_t * pfrm,dk4_app_t * app)477 dk4bif_frame_restrict_size(
478 	dk4_bif_frame_t	*pfrm,
479 	dk4_app_t		*app
480 )
481 {
482 	double	oldresx	=	72.0;
483 	double	oldresy	=	72.0;
484 	double	w;
485 	double	h;
486 	double	fx;
487 	double	fy;
488 
489 	if (0.0 < pfrm->res_x) {
490 		w = (72.0 * (double)(pfrm->dim_x)) / pfrm->res_x;
491 		oldresx = pfrm->res_x;
492 	}
493 	else {
494 		w = (double)(pfrm->dim_x);
495 	}
496 	if (0.0 < pfrm->res_y) {
497 		h = (72.0 * (double)(pfrm->dim_y)) / pfrm->res_y;
498 		oldresy = pfrm->res_y;
499 	}
500 	else {
501 		h = (double)(pfrm->dim_y);
502 	}
503 	if ((0 != dk4ma_is_finite(w)) && (0 != dk4ma_is_finite(h))) {
504 		if ((16322.1 < w) || (16321.0 < h)) {
505 			/*
506 				At least one dimension too large, must correct resolution
507 			*/
508 			fx = fabs(w / 16322.0);
509 			fy = fabs(h / 16322.0);
510 			if (fx < fy) {
511 				fx = fy;
512 			}
513 			fx = ceil(log2(ceil(fx)));
514 			fx = 4.0 * pow(2.0, fx);
515 			if (0 != dk4ma_is_finite(fx)) {
516 				oldresx = oldresx * fx;
517 				oldresy = oldresy * fx;
518 				if (
519 					(0 != dk4ma_is_finite(oldresx))
520 					&& (0 != dk4ma_is_finite(oldresy))
521 				) {
522 					pfrm->res_x = oldresx;
523 					pfrm->res_y = oldresy;
524 					pfrm->szmod	= 1;
525 					dk4bifap_warning_1(app, 13);
526 				}
527 				else {
528 					/* ERROR: Math overflow */
529 					dk4app_log_base1(app, DK4_LL_ERROR, 82);
530 				}
531 			}
532 			else {
533 				/* ERROR: Math overflow */
534 				dk4app_log_base1(app, DK4_LL_ERROR, 82);
535 			}
536 		}
537 	}
538 	else {
539 		/* ERROR: Math overflow */
540 		dk4app_log_base1(app, DK4_LL_ERROR, 82);
541 	}
542 
543 }
544 
545 
546 
547 void
dk4bif_restrict_size_app(dk4_bif_t * bifptr,dk4_app_t * app,dkChar const * filename)548 dk4bif_restrict_size_app(
549 	dk4_bif_t		*bifptr,
550 	dk4_app_t		*app,
551 	dkChar const	*filename
552 )
553 {
554 	dk4_sto_it_t	*it		=	NULL;
555 	dk4_bif_frame_t	*pfrm	=	NULL;
556 	dkChar const	*oldf	=	NULL;
557 	dk4_um_t		 oldl	=	(dk4_um_t)0UL;
558 
559 	if (NULL != bifptr) {
560 		if (NULL != bifptr->s_frames) {
561 			oldf = dk4app_get_log_source_file(app);
562 			oldl = dk4app_get_log_source_line(app);
563 			dk4app_set_log_source_file(app, filename);
564 			dk4app_set_log_source_line(app, (dk4_um_t)0UL);
565 			it = dk4sto_it_open(bifptr->s_frames, NULL);
566 			if (NULL != it) {
567 				dk4sto_it_reset(it);
568 				while (NULL != (pfrm = (dk4_bif_frame_t *)dk4sto_it_next(it))) {
569 					dk4bif_frame_restrict_size(pfrm, app);
570 				}
571 				dk4sto_it_close(it);
572 			}
573 			else {
574 				/* ERROR: Memory */
575 				dk4app_log_base1(app, DK4_LL_ERROR, 90);
576 			}
577 			dk4app_set_log_source_file(app, oldf);
578 			dk4app_set_log_source_line(app, oldl);
579 		}
580 	}
581 
582 }
583 
584 
585 
586 /* vim: set ai sw=4 ts=4 : */
587 
588