1/* $Id: strip.c,v 1.3.2.2 2010-06-08 18:50:43 bfriesen Exp $ */
2
3/*
4 * Copyright (c) 2004, Andrey Kiselev  <dron@ak4719.spb.edu>
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that (i) the above copyright notices and this permission notice appear in
9 * all copies of the software and related documentation, and (ii) the names of
10 * Sam Leffler and Silicon Graphics may not be used in any advertising or
11 * publicity relating to the software without the specific, prior written
12 * permission of Sam Leffler and Silicon Graphics.
13 *
14 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
16 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
17 *
18 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
19 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
22 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 * OF THIS SOFTWARE.
24 */
25
26/*
27 * TIFF Library
28 *
29 * Functions to test strip interface of libtiff.
30 */
31
32#include <stdio.h>
33#include <string.h>
34
35#include "tiffio.h"
36
37int
38write_strips(TIFF *tif, const tdata_t array, const tsize_t size)
39{
40	tstrip_t	strip, nstrips;
41	tsize_t		stripsize, offset;
42
43	stripsize = TIFFStripSize(tif);
44	if (!stripsize) {
45		fprintf (stderr, "Wrong size of strip.\n");
46		return -1;
47	}
48
49	nstrips = TIFFNumberOfStrips(tif);
50	for (offset = 0, strip = 0;
51	     offset < size && strip < nstrips;
52	     offset+=stripsize, strip++) {
53		/*
54		 * Properly write last strip.
55		 */
56		tsize_t	bufsize = size - offset;
57		if (bufsize > stripsize)
58			bufsize = stripsize;
59
60		if (TIFFWriteEncodedStrip(tif, strip, (char *)array + offset,
61					  bufsize) != bufsize) {
62			fprintf (stderr, "Can't write strip %lu.\n",
63				 (unsigned long)strip);
64			return -1;
65		}
66        }
67
68	return 0;
69}
70
71int
72read_strips(TIFF *tif, const tdata_t array, const tsize_t size)
73{
74	tstrip_t	strip, nstrips;
75	tsize_t		stripsize, offset;
76	tdata_t		buf = NULL;
77
78	stripsize = TIFFStripSize(tif);
79	if (!stripsize) {
80		fprintf (stderr, "Wrong size of strip.\n");
81		return -1;
82	}
83
84	buf = _TIFFmalloc(stripsize);
85	if (!buf) {
86		fprintf (stderr, "Can't allocate space for strip buffer.\n");
87		return -1;
88	}
89
90	nstrips = TIFFNumberOfStrips(tif);
91	for (offset = 0, strip = 0;
92	     offset < size && strip < nstrips;
93	     offset+=stripsize, strip++) {
94		/*
95		 * Properly read last strip.
96		 */
97		tsize_t	bufsize = size - offset;
98		if (bufsize > stripsize)
99			bufsize = stripsize;
100
101		if (TIFFReadEncodedStrip(tif, strip, buf, -1) != bufsize) {
102			fprintf (stderr, "Can't read strip %lu.\n",
103				 (unsigned long)strip);
104			return -1;
105		}
106		if (memcmp(buf, (char *)array + offset, bufsize) != 0) {
107			fprintf (stderr, "Wrong data read for strip %lu.\n",
108				 (unsigned long)strip);
109			_TIFFfree(buf);
110			return -1;
111		}
112        }
113
114	_TIFFfree(buf);
115
116	return 0;
117}
118
119int
120create_image_striped(const char *name, uint32 width, uint32 length,
121		      uint32 rowsperstrip, uint16 compression,
122		      uint16 spp, uint16 bps, uint16 photometric,
123		      uint16 sampleformat, uint16 planarconfig,
124		      const tdata_t array, const tsize_t size)
125{
126	TIFF		*tif;
127
128	/* Test whether we can write tags. */
129	tif = TIFFOpen(name, "w");
130	if (!tif)
131		goto openfailure;
132
133	if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width)) {
134		fprintf (stderr, "Can't set ImageWidth tag.\n");
135		goto failure;
136	}
137	if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, length)) {
138		fprintf (stderr, "Can't set ImageLength tag.\n");
139		goto failure;
140	}
141	if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps)) {
142		fprintf (stderr, "Can't set BitsPerSample tag.\n");
143		goto failure;
144	}
145	if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp)) {
146		fprintf (stderr, "Can't set SamplesPerPixel tag.\n");
147		goto failure;
148	}
149	if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip)) {
150		fprintf (stderr, "Can't set RowsPerStrip tag.\n");
151		goto failure;
152	}
153	if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, planarconfig)) {
154		fprintf (stderr, "Can't set PlanarConfiguration tag.\n");
155		goto failure;
156	}
157	if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
158		fprintf (stderr, "Can't set PhotometricInterpretation tag.\n");
159		goto failure;
160	}
161
162	if (write_strips(tif, array, size) < 0) {
163		fprintf (stderr, "Can't write image data.\n");
164		goto failure;
165	}
166
167	TIFFClose(tif);
168	return 0;
169
170failure:
171	TIFFClose(tif);
172openfailure:
173	fprintf (stderr, "Can't create test TIFF file %s:\n"
174"    ImageWidth=%u, ImageLength=%u, RowsPerStrip=%u, Compression=%d,\n"
175"    BitsPerSample=%d, SamplesPerPixel=%d, SampleFormat=%d,\n"
176"    PlanarConfiguration=%d, PhotometricInterpretation=%d.\n",
177		 name, width, length, rowsperstrip, compression,
178		 bps, spp, sampleformat, planarconfig,
179		 photometric);
180	return -1;
181}
182
183int
184read_image_striped(const char *name, uint32 width, uint32 length,
185		    uint32 rowsperstrip, uint16 compression,
186		    uint16 spp, uint16 bps, uint16 photometric,
187		    uint16 sampleformat, uint16 planarconfig,
188		    const tdata_t array, const tsize_t size)
189{
190	TIFF		*tif;
191	uint16		value_u16;
192	uint32		value_u32;
193
194	/* Test whether we can read written values. */
195	tif = TIFFOpen(name, "r");
196	if (!tif)
197		goto openfailure;
198
199	if (TIFFIsTiled(tif)) {
200		fprintf (stderr, "Can't read image %s, it is tiled.\n",
201			 name);
202		goto failure;
203	}
204	if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &value_u32)
205	    || value_u32 != width) {
206		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_IMAGEWIDTH);
207		goto failure;
208	}
209	if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &value_u32)
210	    || value_u32 != length) {
211		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_IMAGELENGTH);
212		goto failure;
213	}
214	if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &value_u16)
215	    || value_u16 != bps) {
216		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_BITSPERSAMPLE);
217		goto failure;
218	}
219	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &value_u16)
220	    || value_u16 != photometric) {
221		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_PHOTOMETRIC);
222		goto failure;
223	}
224	if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &value_u16)
225	    || value_u16 != spp) {
226		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_SAMPLESPERPIXEL);
227		goto failure;
228	}
229	if (!TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &value_u32)
230	    || value_u32 != rowsperstrip) {
231		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_ROWSPERSTRIP);
232		goto failure;
233	}
234	if (!TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &value_u16)
235	    || value_u16 != planarconfig) {
236		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_PLANARCONFIG);
237		goto failure;
238	}
239
240	if (read_strips(tif, array, size) < 0) {
241		fprintf (stderr, "Can't read image data.\n");
242		goto failure;
243	}
244
245	TIFFClose(tif);
246	return 0;
247
248failure:
249	TIFFClose(tif);
250openfailure:
251	fprintf (stderr, "Can't read test TIFF file %s:\n"
252"    ImageWidth=%u, ImageLength=%u, RowsPerStrip=%u, Compression=%d,\n"
253"    BitsPerSample=%d, SamplesPerPixel=%d, SampleFormat=%d,\n"
254"    PlanarConfiguration=%d, PhotometricInterpretation=%d.\n",
255		 name, width, length, rowsperstrip, compression,
256		 bps, spp, sampleformat, planarconfig,
257		 photometric);
258	return -1;
259}
260
261int
262write_scanlines(TIFF *tif, const tdata_t array, const tsize_t size)
263{
264	uint32		length, row;
265	tsize_t		scanlinesize, offset;
266
267	(void) size;
268
269	if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &length)) {
270		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_IMAGELENGTH);
271		return -1;
272	}
273
274	scanlinesize = TIFFScanlineSize(tif);
275	if (!scanlinesize) {
276		fprintf (stderr, "Wrong size of scanline.\n");
277		return -1;
278	}
279
280	for (offset = 0, row = 0; row < length; offset+=scanlinesize, row++) {
281		if (TIFFWriteScanline(tif, (char *)array + offset, row, 0) < 0) {
282			fprintf (stderr,
283				 "Can't write image data at row %u.\n", row);
284			return -1;
285		}
286        }
287
288	return 0;
289}
290
291/* vim: set ts=8 sts=8 sw=8 noet: */
292/*
293 * Local Variables:
294 * mode: c
295 * c-basic-offset: 8
296 * fill-column: 78
297 * End:
298 */
299