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