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: dk4bift.ctr
12 */
13 
14 /**	@file dk4bift.c The dk4bift module.
15 */
16 
17 #include "dk4conf.h"
18 
19 
20 
21 
22 
23 
24 #if	DK4_HAVE_TIFF_H
25 
26 #ifndef	DK4MEM_H_INCLUDED
27 #include <libdk4base/dk4mem.h>
28 #endif
29 
30 #ifndef	DK4BIF_H_INCLUDED
31 #include <libdk4bif/dk4bif.h>
32 #endif
33 
34 #ifndef	BIF_H_INCLUDED
35 #include <libdk4bif/bif.h>
36 #endif
37 
38 #ifndef	DK4MAAL_H_INCLUDED
39 #include <libdk4ma/dk4maal.h>
40 #endif
41 
42 #if DK4_HAVE_ASSERT_H
43 #ifndef	ASSERT_H_INCLUDED
44 #include <assert.h>
45 #define	ASSERT_H_INCLUDED 1
46 #endif
47 #endif
48 
49 
50 void
dk4biftiff_nc_release_per_frame_data(void * tsdata)51 dk4biftiff_nc_release_per_frame_data(
52 	void			*tsdata
53 )
54 {
55 	dk4_bif_tiff_per_frame_t	*pfd	= NULL;	/* Per-frame data */
56 
57 #if	DK4_USE_ASSERT
58 	assert(NULL != tsdata);
59 #endif
60 	pfd = (dk4_bif_tiff_per_frame_t *)tsdata;
61 	if (NULL != pfd) {
62 		if (NULL != pfd->rows) {
63 			_TIFFfree(pfd->rows);
64 			pfd->rows = NULL;
65 		}
66 		dk4mem_free(pfd);
67 	}
68 
69 }
70 
71 
72 
73 dk4_bif_t *
dk4biftiff_nc_open_type(dkChar const * fn,dk4_cs_conv_ctx_t const * pcsctx,dk4_er_t * erp)74 dk4biftiff_nc_open_type(
75 	dkChar	const				*fn,
76 	dk4_cs_conv_ctx_t	const	*pcsctx,
77 	dk4_er_t					*erp
78 )
79 {
80 	dk4_er_t					 er;			/* Error report for math op */
81 	dk4_bif_tiff_per_frame_t	*pfd	= NULL;	/* Per-frame data */
82 	dk4_bif_t					*back	= NULL;
83 	TIFF						*tiff	= NULL;	/* TIFF file */
84 	double						 xrv;			/* Temporary resolution valuej */
85 	float						 rv;			/* Temporary resolution value */
86 	uint32						 w;				/* Frame width */
87 	uint32						 h;				/* Frame height */
88 	int							 ok		= 0;	/* Flag: Success */
89 	int							 cc		= 0;	/* Flag: Can continue */
90 	uint16						 ru;			/* Resolution unit */
91 	uint16						 orie;			/* Orientation */
92 	tsize_t						 nby;			/* Byte number to allocate */
93 
94 	back = dk4biftool_nc_new_for_one_frame(
95 		fn, DK4_BIF_TYPE_TIFF, 0, pcsctx, erp
96 	);
97 	if (NULL == back) { goto finished; }
98 
99 
100 	pfd = dk4mem_new(dk4_bif_tiff_per_frame_t,1,NULL);
101 	if (NULL == pfd) { goto finished; }
102 	pfd->rows = NULL;
103 
104 
105 	back->cf->tsdata = pfd;
106 
107 #if	(DK4_CHAR_SIZE > 1) && (DK4_ON_WINDOWS)
108 	tiff = TIFFOpenW(fn, "rb");
109 #else
110 	tiff = TIFFOpen(fn, "rb");
111 #endif
112 	if (NULL == tiff) { goto finished; }
113 
114 
115 	/*	Traverse all frames
116 	*/
117 	ok = 1;
118 	do {
119 		cc = 0;
120 		w  = 0UL;
121 		h  = 0UL;
122 
123 		/*	Read image width and height
124 		*/
125 		if (1 == TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w)) {
126 			back->cf->dim_x = w;
127 		}
128 		else {
129 			w = 0UL;
130 		}
131 		if (1 == TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h)) {
132 			back->cf->dim_y = h;
133 		}
134 		else {
135 			h = 0UL;
136 		}
137 
138 		/*	Read resolution
139 		*/
140 		rv = 0.0;
141 		if (1 == TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &rv)) {
142 			back->cf->res_x = rv;
143 		}
144 		rv = 0.0;
145 		if (1 == TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &rv)) {
146 			back->cf->res_y = rv;
147 		}
148 		ru = 0;
149 		if (1 == TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &ru)) {
150 			if (RESUNIT_CENTIMETER == ru) {
151 				back->cf->res_x *= 2.54;
152 				back->cf->res_y *= 2.54;
153 			}
154 		}
155 		if ((0.0 >= back->cf->res_x) || (0.0 >= back->cf->res_y)) {
156 			back->cf->res_x = back->cf->res_y = -1.0;
157 
158 		}
159 
160 		/*	Read orientation, swap x and y coordinates if necessary
161 		*/
162 		orie = ORIENTATION_TOPLEFT;
163 		if (1 == TIFFGetFieldDefaulted(tiff, TIFFTAG_ORIENTATION, &orie)) {
164 			switch (orie) {
165 				case 5: case 6: case 7: case 8: {
166 					back->cf->dim_x = h; back->cf->dim_y = w;
167 					xrv = back->cf->res_x;
168 					back->cf->res_x = back->cf->res_y;
169 					back->cf->res_y = xrv;
170 				} break;
171 			}
172 		}
173 		else {
174 			orie = ORIENTATION_TOPLEFT;
175 		}
176 
177 		/*	Calculate byte number
178 		*/
179 		dk4error_init(&er);
180 		nby = dk4ma_long_mul(
181 			dk4ma_long_mul(w, h, &er), 4L, &er
182 		);
183 
184 		/*	Read image data
185 		*/
186 		if ((DK4_E_NONE == er.ec) && (0L < w) && (0L < h)) {
187 			pfd->rows = (uint32 *)_TIFFmalloc(nby);
188 			if (NULL != pfd->rows) {
189 				if (1 == TIFFReadRGBAImageOriented(tiff,w,h,pfd->rows,orie,0)) {
190 					back->cf->bg[0] = 255;
191 					back->cf->bg[1] = 255;
192 					back->cf->bg[2] = 255;
193 					back->cf->bg[3] = 255;
194 					back->cf->bglbd[0] = 255;
195 					back->cf->bglbd[1] = 255;
196 					back->cf->bglbd[2] = 255;
197 					back->cf->bglbd[3] = 255;
198 					dk4pxres_setup(&(back->cf->resampler), 8, 8);
199 					back->cf->l_bdepth = back->cf->r_bdepth = 8;
200 					back->cf->n_comp = 4;
201 					back->cf->l_cs = back->cf->f_cs = DK4_CS_RGB_ALPHA;
202 					back->cf->hbg = 0;
203 				}
204 				else {
205 					dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
206 					cc = -1;
207 					ok = 0;
208 				}
209 			}
210 			else {
211 				dk4error_set_elsize_nelem(
212 					erp, DK4_E_MEMORY_ALLOCATION_FAILED, (size_t)nby, 1
213 				);
214 				cc = -1;
215 				ok = 0;
216 			}
217 		}
218 		else {
219 			dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
220 			cc = -1;
221 			ok = 0;
222 		}
223 
224 		/*	Attempt to read one further frame
225 		*/
226 		if (0 == cc) {
227 			if (1 == TIFFReadDirectory(tiff)) {
228 				if (0 != dk4biftool_nc_add_frame(back, erp)) {
229 					pfd = dk4mem_new(dk4_bif_tiff_per_frame_t,1,NULL);
230 					if (NULL != pfd) {
231 						pfd->rows = NULL;
232 						back->cf->tsdata = pfd;
233 						cc = 1;
234 					}
235 					else {
236 						dk4error_set_elsize_nelem(
237 							erp, DK4_E_MEMORY_ALLOCATION_FAILED,
238 							sizeof(dk4_bif_tiff_per_frame_t), 1
239 						);
240 						ok = 0;
241 						cc = -1;
242 					}
243 				}
244 				else {
245 					ok = 0;
246 					cc = -1;
247 				}
248 			}
249 		}
250 
251 	} while (1 == cc);
252 
253 	finished:
254 	if (NULL != tiff) {
255 		TIFFClose(tiff);
256 	}
257 	if (0 == ok) {
258 		if (NULL != back) {
259 			dk4bif_close(back);
260 			back = NULL;
261 		}
262 	}
263 
264 	return back;
265 }
266 
267 
268 
269 int
dk4biftiff_nc_get_original_pixel(dk4_px_t * dptr,dk4_bif_t const * bif,dk4_bif_dim_t rowno,dk4_bif_dim_t colno)270 dk4biftiff_nc_get_original_pixel(
271 	dk4_px_t				*dptr,
272 	dk4_bif_t		const	*bif,
273 	dk4_bif_dim_t			 rowno,
274 	dk4_bif_dim_t			 colno
275 )
276 {
277 	dk4_bif_tiff_per_frame_t	*pfd	= NULL;	/* Per-frame data */
278 	uint32						 abgr;			/* Pixel index in array */
279 	int							 back	= 0;
280 
281 #if	DK4_USE_ASSERT
282 	assert(NULL != dptr);
283 	assert(NULL != bif);
284 #endif
285 	if (NULL == bif->cf->tsdata) {
286 		goto finished;
287 	}
288 	pfd = (dk4_bif_tiff_per_frame_t *)(bif->cf->tsdata);
289 	abgr = (pfd->rows)[(rowno * bif->cf->dim_x) + colno];
290 	dptr[0] = (dk4_px_t)(TIFFGetR(abgr));
291 	dptr[1] = (dk4_px_t)(TIFFGetG(abgr));
292 	dptr[2] = (dk4_px_t)(TIFFGetB(abgr));
293 	dptr[3] = (dk4_px_t)(TIFFGetA(abgr));
294 	back = 1;
295 
296 	finished:
297 
298 	return back;
299 }
300 
301 
302 
303 #endif
304 /* if DK4_HAVE_TIFF_H */
305 
306 
307 /* vim: set ai sw=4 ts=4 : */
308 
309