• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* scanimage -- command line scanning utility
2  * Uses the SANE library.
3  *
4  * Copyright (C) 2021 Thierry HUCHARD <thierry@ordissimo.com>
5  *
6  * For questions and comments contact the sane-devel mailinglist (see
7  * http://www.sane-project.org/mailing-lists.html).
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of the
12  * License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <stdarg.h>
28 #include <errno.h>
29 
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <time.h>
33 #include "jpegtopdf.h"
34 
35 #ifndef PATH_MAX
36 # define PATH_MAX 4096
37 #endif
38 
39 #define	SANE_NO_ERR			(0)
40 #define	SANE_NO_ERR_CANCLED	(1)
41 
42 #define	SANE_ERR			(-128)
43 #define	SANE_FILE_ERR		(-1)
44 
45 
46 /* Creater/Producer */
47 #define SANE_PDF_CREATER "sane"
48 #define SANE_PDF_PRODUCER "sane"
49 
50 /* PDF File Header */
51 #define SANE_PDF_HEADER "%%PDF-1.3\n"
52 
53 /* trailer format */
54 #define SANE_PDF_TRAILER_OBJ "trailer\n<<\n/Size %d\n/Root 1 0 R\n/Info 3 0 R\n>>\nstartxref\n%lld\n%%%%EOF\n"
55 
56 /* xref format */
57 #define SANE_PDF_XREF_OBJ1 "xref\n0 %d\n0000000000 65535 f \n"
58 #define SANE_PDF_XREF_OBJ2 "%010lld 00000 n \n"
59 
60 /* Catalog format */
61 #define SANE_PDF_CATALOG_OBJ "1 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n>>\nendobj\n"
62 
63 /* Pages format */
64 #define SANE_PDF_PAGES_OBJ1 "2 0 obj\n<<\n/Type /Pages\n/Kids [ "
65 #define SANE_PDF_PAGES_OBJ2 "%d 0 R "
66 #define SANE_PDF_PAGES_OBJ3 "]\n/Count %d\n>>\nendobj\n"
67 
68 /* Info format */
69 #define SANE_PDF_INFO_OBJ "3 0 obj\n<<\n/Creator (" SANE_PDF_CREATER ")\n/Producer (" SANE_PDF_PRODUCER ")\n/CreationDate %s\n>>\nendobj\n"
70 #define SANE_PDF_INFO_DATES "(D:%4d%02d%02d%02d%02d%02d%c%02d'%02d')"
71 
72 /* Page format */
73 #define SANE_PDF_PAGE_OBJ1 "%d 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n"
74 #define SANE_PDF_PAGE_OBJ2 "/Resources\n<<\n/XObject << /Im%d %d 0 R >>\n/ProcSet [ /PDF /%s ]\n>>\n"
75 #define SANE_PDF_PAGE_OBJ3 "/MediaBox [ 0 0 %d %d ]\n/Contents %d 0 R\n>>\nendobj\n"
76 #define SANE_PDF_PAGE_OBJ3_180 "/Rotate 180\n/MediaBox [ 0 0 %d %d ]\n/Contents %d 0 R\n>>\nendobj\n"
77 #define SANE_PDF_PAGE_OBJ		SANE_PDF_PAGE_OBJ1 SANE_PDF_PAGE_OBJ2 SANE_PDF_PAGE_OBJ3
78 #define SANE_PDF_PAGE_OBJ_180	SANE_PDF_PAGE_OBJ1 SANE_PDF_PAGE_OBJ2 SANE_PDF_PAGE_OBJ3_180
79 
80 /* Contents format */
81 #define SANE_PDF_CONTENTS_OBJ1 "%d 0 obj\n<< /Length %d 0 R >>\nstream\n"
82 #define SANE_PDF_CONTENTS_OBJ2 "q\n%d 0 0 %d 0 0 cm\n/Im%d Do\nQ\n"
83 
84 /* XObject(Image) format */
85 #define SANE_PDF_IMAGE_OBJ1 "%d 0 obj\n<<\n/Length %d 0 R\n/Type /XObject\n/Subtype /Image\n"
86 #define SANE_PDF_IMAGE_OBJ2 "/Width %d /Height %d\n/ColorSpace /%s\n/BitsPerComponent %d\n"
87 #define SANE_PDF_IMAGE_OBJ3 "/Filter /DCTDecode\n>>\nstream\n"
88 #define SANE_PDF_IMAGE_OBJ	SANE_PDF_IMAGE_OBJ1 SANE_PDF_IMAGE_OBJ2 SANE_PDF_IMAGE_OBJ3
89 
90 /* Length format */
91 #define SANE_PDF_LENGTH_OBJ "%d 0 obj\n%d\nendobj\n"
92 
93 /* end of stream/object */
94 #define SANE_PDF_END_ST_OBJ "\nendstream\nendobj\n"
95 
96 
97 /* object id of first page */
98 #define SANE_PDF_FIRST_PAGE_ID (4)
99 
100 /* xref max value */
101 #define SANE_PDF_XREF_MAX (9999999999LL)
102 
103 /* pdfwork->offset_table */
104 enum {
105 	SANE_PDF_ENDDOC_XREF = 0,
106 	SANE_PDF_ENDDOC_CATALOG,
107 	SANE_PDF_ENDDOC_PAGES,
108 	SANE_PDF_ENDDOC_INFO,
109 	SANE_PDF_ENDDOC_NUM,
110 };
111 
112 /* pdfpage->offset_table */
113 enum {
114 	SANE_PDF_PAGE_OBJ_PAGE = 0,
115 	SANE_PDF_PAGE_OBJ_IMAGE,
116 	SANE_PDF_PAGE_OBJ_IMAGE_LEN,
117 	SANE_PDF_PAGE_OBJ_CONTENTS,
118 	SANE_PDF_PAGE_OBJ_CONTENTS_LEN,
119 	SANE_PDF_PAGE_OBJ_NUM,
120 };
121 
122 /* Page object info */
123 typedef struct sane_pdf_page {
124 	SANE_Int		page;			/* page No. */
125 	SANE_Int		obj_id;			/* Page object id */
126 	SANE_Int		image_type;		/* ColorSpace, BitsPerComponent */
127 	SANE_Int		res;			/* image resolution */
128 	SANE_Int		w;				/* width (image res) */
129 	SANE_Int		h;				/* height (image res) */
130 	SANE_Int		w_72;			/* width (72dpi) */
131 	SANE_Int		h_72;			/* height (72dpi) */
132 	SANE_Int64		offset_table[SANE_PDF_PAGE_OBJ_NUM];	/* xref table */
133 	SANE_Int		stream_len;		/* stream object length */
134 	SANE_Int		status;			/* page object status */
135 	struct sane_pdf_page	*prev;	/* previous page data */
136 	struct sane_pdf_page	*next;	/* next page data */
137 } SANE_pdf_page;
138 
139 
140 /* PDF Work */
141 typedef struct {
142 	SANE_Int		obj_num;		/* xref - num, trailer - Size */
143 	SANE_Int		page_num;		/* Pages - Count */
144 	SANE_Int64		offset_table[SANE_PDF_ENDDOC_NUM];	/* xref table */
145 	SANE_pdf_page		*first;			/* first page data */
146 	SANE_pdf_page		*last;			/* last page data */
147 	FILE*			fd;				/* destination file */
148 } SANE_pdf_work;
149 
re_write_if_fail(FILE * fd,void * lpSrc,SANE_Int writeSize)150 static SANE_Int re_write_if_fail(
151                 FILE *               fd,
152                 void *               lpSrc,
153                 SANE_Int             writeSize )
154 {
155         SANE_Int       ret = SANE_ERR, ldata_1st, ldata_2nd;
156 
157         if( ( fd == NULL ) || ( lpSrc == NULL ) || ( writeSize <= 0 ) ) {
158                 fprintf ( stderr, "[re_write_if_fail]Parameter is error.\n" );
159                 goto    EXIT;
160         }
161 		else if( ( ldata_1st = fwrite( (SANE_Byte *)lpSrc, 1, writeSize, fd ) ) != writeSize ){
162                 fprintf ( stderr, "[re_write_if_fail]Can't write file(1st request:%d -> write:%d).\n", writeSize, ldata_1st );
163                 if( ( ldata_2nd = fwrite( (SANE_Byte*)lpSrc+ldata_1st, 1, writeSize-ldata_1st, fd) ) != writeSize-ldata_1st ){ /* For detect write() error */
164                         fprintf ( stderr, "[re_write_if_fail]Can't write file(2nd request:%d -> write:%d).\n", writeSize-ldata_1st, ldata_2nd );
165                         goto    EXIT;
166                 }
167         }
168         ret = SANE_NO_ERR;
169 EXIT:
170         return  ret;
171 }
172 
_get_current_offset(FILE * fd)173 static SANE_Int64 _get_current_offset( FILE *fd )
174 {
175 	SANE_Int64	offset64 = (SANE_Int64)fseek( fd, 0, SEEK_CUR );
176 
177 	if ( offset64 > SANE_PDF_XREF_MAX ) offset64 = -1;
178 
179 	return offset64;
180 }
181 
_get_current_time(struct tm * pt,SANE_Byte * sign_c,int * ptz_h,int * ptz_m)182 static SANE_Int _get_current_time( struct tm *pt, SANE_Byte *sign_c, int *ptz_h, int *ptz_m )
183 {
184 	SANE_Int		ret = SANE_ERR;
185 	time_t			t;
186 	long			tz;
187 
188 	if ( pt == NULL || sign_c == NULL || ptz_h == NULL || ptz_m == NULL ) {
189 		goto EXIT;
190 	}
191 
192 	memset ((void *)pt, 0, sizeof(struct tm) );
193 	/* get time */
194 	if( ( t = time( NULL ) ) < 0 ) {
195 		fprintf ( stderr, " Can't get time.\n" );
196 		goto EXIT;
197 	}
198 	/* get localtime */
199 	if ( localtime_r( &t, pt ) == NULL ) {
200 		fprintf ( stderr, " Can't get localtime.\n" );
201 		goto EXIT;
202 	}
203 	/* get time difference ( OHH'mm' ) */
204 #ifdef __FreeBSD__
205        tz = -pt->tm_gmtoff;
206 #else
207 	tz = timezone;
208 #endif
209 	if ( tz > 0 ) {
210 		*sign_c = '-';
211 	}
212 	else {
213 		tz = -tz;
214 		*sign_c = '+';
215 	}
216 	*ptz_h = tz / 60 / 60;
217 	*ptz_m = ( tz / 60 ) % 60;
218 
219 	ret = SANE_NO_ERR;
220 EXIT:
221 	return ret;
222 }
223 
sane_pdf_open(void ** ppw,FILE * fd)224 SANE_Int sane_pdf_open( void **ppw, FILE *fd )
225 {
226 	SANE_Int		ret = SANE_ERR;
227 	SANE_pdf_work		*p = NULL;
228 
229 	if ( fd == NULL ) {
230 		fprintf ( stderr, " Initialize parameter is error!\n" );
231 		goto	EXIT;
232 	}
233 	else if ( ( p = (SANE_pdf_work *)calloc(1, sizeof(SANE_pdf_page) ) ) == NULL ) {
234 		fprintf ( stderr, " Can't get work memory!\n" );
235 		goto	EXIT;
236 	}
237 
238 	p->fd = fd;
239 	p->obj_num = SANE_PDF_FIRST_PAGE_ID - 1;	/* Catalog, Pages, Info */
240 	p->page_num = 0;
241 	p->first = NULL;
242 	p->last = NULL;
243 
244 	*ppw = (void *)p;
245 
246 	ret = SANE_NO_ERR;
247 EXIT:
248 	return ret;
249 }
250 
sane_pdf_close(void * pw)251 void sane_pdf_close( void *pw )
252 {
253 	SANE_pdf_page		*cur, *next;
254 	SANE_pdf_work		*pwork = (SANE_pdf_work *)pw;
255 
256 	if ( pwork == NULL ) {
257 		fprintf ( stderr, " Initialize parameter is error!\n");
258 		goto	EXIT;
259 	}
260 
261 	cur = pwork->first;
262 	while ( cur != NULL ) {
263 		next = cur->next;
264 		free( (void *)cur );
265 		cur = next;
266 	}
267 
268 	free ( (void *)pwork );
269 
270 EXIT:
271 	return ;
272 }
273 
sane_pdf_start_doc(void * pw)274 SANE_Int sane_pdf_start_doc( void *pw )
275 {
276 	SANE_Int		ret = SANE_ERR, ldata;
277 	SANE_Byte		str[32];
278 	SANE_Int			len;
279 	SANE_pdf_work		*pwork = (SANE_pdf_work *)pw;
280 
281 	if ( pwork == NULL ) {
282 		fprintf ( stderr, " Initialize parameter is error!\n");
283 		goto	EXIT;
284 	}
285 
286 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_HEADER );
287 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
288 		fprintf ( stderr, " string is too long!\n" );
289 		goto EXIT;
290 	}
291 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
292 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
293 		goto EXIT;
294 	}
295 
296 	ret = SANE_NO_ERR;
297 EXIT:
298 	return ret;
299 }
300 
sane_pdf_end_doc(void * pw)301 SANE_Int sane_pdf_end_doc( void *pw )
302 {
303 	SANE_Int		ret = SANE_ERR, ldata, i, size, w_count;
304 	SANE_pdf_page		*p = NULL;
305 	SANE_Byte		str[1024], str_t[64];
306 	SANE_Int			len;
307 	SANE_pdf_work		*pwork = (SANE_pdf_work *)pw;
308 
309 	struct tm		tm;
310 	SANE_Byte		sign_c;
311 	int				tz_h = 0, tz_m = 0;
312 
313 	if ( pwork == NULL ) {
314 		fprintf ( stderr, " Initialize parameter is error!\n");
315 		goto	EXIT;
316 	}
317 
318 	size = pwork->obj_num + 1;
319 	w_count = 1;
320 
321 	/* <1> Pages */
322 	if ( ( pwork->offset_table[ SANE_PDF_ENDDOC_PAGES ] = _get_current_offset( pwork->fd ) ) < 0 ) {
323 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
324 		goto EXIT;
325 	}
326 	/* write Pages(1) */
327 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_PAGES_OBJ1 );
328 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
329 		fprintf ( stderr, " string is too long!\n" );
330 		goto EXIT;
331 	}
332 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
333 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
334 		goto EXIT;
335 	}
336 
337 	/* write Pages(2) ... Kids array */
338 	p = pwork->first;
339 	i = 0;
340 	while ( p != NULL ) {
341 		i++;
342 		if ( p->status != SANE_NO_ERR ) {
343 			fprintf ( stderr, " page(%d) is NG!\n", i );
344 			goto EXIT;
345 		}
346 
347 		len = snprintf( (char*)str, sizeof(str), SANE_PDF_PAGES_OBJ2, (int)p->obj_id );	/* Page object id */
348 		if ( (size_t)len >= sizeof(str) || len < 0 ) {
349 			fprintf ( stderr, " string is too long!\n" );
350 			goto EXIT;
351 		}
352 		if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
353 			fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
354 			goto EXIT;
355 		}
356 
357 		p = p->next;
358 	}
359 
360 	/* write Pages(3) */
361 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_PAGES_OBJ3, (int)pwork->page_num );	/* Count */
362 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
363 		fprintf ( stderr, " string is too long!\n" );
364 		goto EXIT;
365 	}
366 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
367 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
368 		goto EXIT;
369 	}
370 
371 	/* <2> Catalog */
372 	if ( ( pwork->offset_table[ SANE_PDF_ENDDOC_CATALOG ] = _get_current_offset( pwork->fd ) ) < 0 ) {
373 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
374 		goto EXIT;
375 	}
376 	/* write Catalog */
377 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_CATALOG_OBJ );
378 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
379 		fprintf ( stderr, " string is too long!\n" );
380 		goto EXIT;
381 	}
382 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
383 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
384 		goto EXIT;
385 	}
386 
387 	/* <3> Info */
388 	if ( ( pwork->offset_table[ SANE_PDF_ENDDOC_INFO ] = _get_current_offset( pwork->fd ) ) < 0 ) {
389 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
390 		goto EXIT;
391 	}
392 	if ( _get_current_time( &tm, &sign_c, &tz_h, &tz_m ) == SANE_ERR ) {
393 		fprintf ( stderr, " Error is occured in _get_current_time.\n" );
394 		goto EXIT;
395 	}
396 	/* Dates format */
397 	len = snprintf((char*)str_t, sizeof(str_t), SANE_PDF_INFO_DATES,
398 		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
399 		tm.tm_hour, tm.tm_min, tm.tm_sec, sign_c, tz_h, tz_m );
400 	if ( (size_t)len >= sizeof(str_t) || len < 0 ) {
401 		fprintf ( stderr, " string is too long!\n" );
402 		goto EXIT;
403 	}
404 	/* write Info */
405 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_INFO_OBJ, str_t );			/* CreationDate */
406 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
407 		fprintf ( stderr, " string is too long!\n" );
408 		goto EXIT;
409 	}
410 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
411 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
412 		goto EXIT;
413 	}
414 
415 	/* <4> xref */
416 	if ( ( pwork->offset_table[ SANE_PDF_ENDDOC_XREF ] = _get_current_offset( pwork->fd ) ) < 0 ) {
417 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
418 		goto EXIT;
419 	}
420 	/* write xref(1) */
421 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_XREF_OBJ1, (int)size );	/* object num */
422 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
423 		fprintf ( stderr, " string is too long!\n" );
424 		goto EXIT;
425 	}
426 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
427 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
428 		goto EXIT;
429 	}
430 
431 	/* write xref(2) */
432 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_XREF_OBJ2 SANE_PDF_XREF_OBJ2 SANE_PDF_XREF_OBJ2,
433 			pwork->offset_table[ SANE_PDF_ENDDOC_CATALOG ],			/* object id = 1 : Catalog */
434 			pwork->offset_table[ SANE_PDF_ENDDOC_PAGES ],			/* object id = 2 : Pages */
435 			pwork->offset_table[ SANE_PDF_ENDDOC_INFO ] );			/* object id = 3 : Info */
436 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
437 		fprintf ( stderr, " string is too long!\n" );
438 		goto EXIT;
439 	}
440 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
441 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
442 		goto EXIT;
443 	}
444 	w_count += SANE_PDF_FIRST_PAGE_ID - 1;
445 
446 	/* write xref(3) */
447 	p = pwork->first;
448 	while ( p != NULL ) {
449 		/* write offset : SANE_PDF_PAGE_OBJ_PAGE -> SANE_PDF_PAGE_OBJ_CONTENTS_LEN */
450 		for ( i = 0; i < SANE_PDF_PAGE_OBJ_NUM; i++ ) {
451 			len = snprintf( (char*)str, sizeof(str), SANE_PDF_XREF_OBJ2, p->offset_table[ i ] );	/* object id = 3 ~ */
452 			if ( (size_t)len >= sizeof(str) || len < 0 ) {
453 				fprintf ( stderr, " string is too long!\n" );
454 				goto EXIT;
455 			}
456 			if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
457 				fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
458 				goto EXIT;
459 			}
460 			w_count ++;
461 		}
462 		p = p->next;
463 	}
464 	/* check object number */
465 	if ( w_count != size ) {
466 		fprintf ( stderr, " object number is wrong.\n" );
467 		goto EXIT;
468 	}
469 
470 	/* <4> trailer */
471 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_TRAILER_OBJ,
472 			(int)size,											/* object num */
473 			pwork->offset_table[ SANE_PDF_ENDDOC_XREF ] );		/* xref offset */
474 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
475 		fprintf ( stderr, " string is too long!\n" );
476 		goto EXIT;
477 	}
478 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
479 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
480 		goto EXIT;
481 	}
482 
483 
484 	ret = SANE_NO_ERR;
485 EXIT:
486 	return ret;
487 }
488 
sane_pdf_start_page(void * pw,SANE_Int w,SANE_Int h,SANE_Int res,SANE_Int type,SANE_Int rotate)489 SANE_Int sane_pdf_start_page(
490 	void		*pw,
491 	SANE_Int		w,
492 	SANE_Int		h,
493 	SANE_Int		res,
494 	SANE_Int		type,
495 	SANE_Int		rotate )
496 {
497 	SANE_Int		ret = SANE_ERR, ldata;
498 	SANE_pdf_page		*p = NULL;
499 	SANE_Byte		str[1024];
500 	SANE_Int			len, len_c;
501 	SANE_Byte		*ProcSetImage[SANE_PDF_IMAGE_NUM]		= { (SANE_Byte *)"ImageC", (SANE_Byte *)"ImageG", (SANE_Byte *)"ImageG" };
502 	SANE_Byte		*ColorSpace[SANE_PDF_IMAGE_NUM]			= { (SANE_Byte *)"DeviceRGB", (SANE_Byte *)"DeviceGray", (SANE_Byte *)"DeviceGray" };
503 	SANE_Int		BitsPerComponent[SANE_PDF_IMAGE_NUM]	= { 8, 8, 1 };
504 	SANE_pdf_work		*pwork = (SANE_pdf_work *)pw;
505 
506 	if ( pwork == NULL || w <= 0 || h <= 0 || res <= 0 ||
507 			!( type == SANE_PDF_IMAGE_COLOR || type == SANE_PDF_IMAGE_GRAY || type == SANE_PDF_IMAGE_MONO ) ||
508 			!( rotate == SANE_PDF_ROTATE_OFF || rotate == SANE_PDF_ROTATE_ON ) ) {
509 		fprintf ( stderr, " Initialize parameter is error!\n");
510 		goto	EXIT;
511 	}
512 	else if ( ( p = (SANE_pdf_page *)calloc( 1, sizeof(SANE_pdf_page) ) ) == NULL ) {
513 		fprintf ( stderr, " Can't get work memory!\n" );
514 		goto	EXIT;
515 	}
516 
517 	pwork->obj_num += SANE_PDF_PAGE_OBJ_NUM;
518 	pwork->page_num ++;
519 
520 	p->prev = p->next = NULL;
521 	if ( pwork->first == NULL ) {
522 		/* append first page */
523 		pwork->first = p;
524 	}
525 	if ( pwork->last == NULL ) {
526 		/* append first page */
527 		pwork->last = p;
528 	}
529 	else {
530 		/* append page */
531 		pwork->last->next = p;
532 		p->prev = pwork->last;
533 		pwork->last = p;
534 	}
535 
536 	p->page = pwork->page_num;
537 	/* page obj id : page1=4, page2=4+5=9, page3=4+5*2=14, ... */
538 	p->obj_id = SANE_PDF_FIRST_PAGE_ID + ( p->page - 1 ) * SANE_PDF_PAGE_OBJ_NUM;
539 	p->image_type = type;
540 	p->res = res;
541 	p->w = w; p->h = h;
542 	p->w_72 = w * 72 / res; p->h_72 = h * 72 / res;
543 	p->stream_len = 0;
544 	p->status = SANE_ERR;
545 
546 	/* <1> Page */
547 	if ( ( p->offset_table[ SANE_PDF_PAGE_OBJ_PAGE ] = _get_current_offset( pwork->fd ) ) < 0 ) {
548 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
549 		goto EXIT;
550 	}
551 	/* write Page */
552 	if ( rotate == SANE_PDF_ROTATE_OFF ) {
553 		len = snprintf( (char*)str, sizeof(str), SANE_PDF_PAGE_OBJ,
554 				(int)(p->obj_id + SANE_PDF_PAGE_OBJ_PAGE),			/* object id ( Page ) */
555 				(int)p->page,										/* ImX (X = page number) ... XObject/Image Name */
556 				(int)(p->obj_id + SANE_PDF_PAGE_OBJ_IMAGE),			/* object id ( XObject/Image ) */
557 				ProcSetImage[ type ],								/* ProcSet */
558 				(int)p->w_72, (int)p->h_72,							/* MediaBox */
559 				(int)(p->obj_id + SANE_PDF_PAGE_OBJ_CONTENTS) );	/* object id ( Contents ) */
560 	}
561 	else {
562 		len = snprintf( (char*)str, sizeof(str), SANE_PDF_PAGE_OBJ_180,
563 				(int)(p->obj_id + SANE_PDF_PAGE_OBJ_PAGE),			/* object id ( Page ) */
564 				(int)p->page,										/* ImX (X = page number) ... XObject/Image Name */
565 				(int)(p->obj_id + SANE_PDF_PAGE_OBJ_IMAGE),			/* object id ( XObject/Image ) */
566 				ProcSetImage[ type ],								/* ProcSet */
567 				(int)p->w_72, (int)p->h_72,							/* MediaBox */
568 				(int)(p->obj_id + SANE_PDF_PAGE_OBJ_CONTENTS) );	/* object id ( Contents ) */
569 	}
570 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
571 		fprintf ( stderr, " string is too long!\n" );
572 		goto EXIT;
573 	}
574 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
575 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
576 		goto EXIT;
577 	}
578 
579 	/* <2> Contents */
580 	if ( ( p->offset_table[ SANE_PDF_PAGE_OBJ_CONTENTS ] = _get_current_offset( pwork->fd ) ) < 0 ) {
581 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
582 		goto EXIT;
583 	}
584 	/* write Contents(1) */
585 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_CONTENTS_OBJ1,
586 			(int)(p->obj_id + SANE_PDF_PAGE_OBJ_CONTENTS),			/* object id ( Contents ) */
587 			(int)(p->obj_id + SANE_PDF_PAGE_OBJ_CONTENTS_LEN) );	/* object id ( Length of Contents ) */
588 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
589 		fprintf ( stderr, " string is too long!\n" );
590 		goto EXIT;
591 	}
592 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
593 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
594 		goto EXIT;
595 	}
596 	/* write Contents(2) */
597 	len_c = len = snprintf( (char*)str, sizeof(str), SANE_PDF_CONTENTS_OBJ2,
598 			(int)p->w_72, (int)p->h_72,							/* CTM ( scaling ) */
599 			(int)p->page );										/* ImX (X = page number) ... XObject/Image Name */
600 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
601 		fprintf ( stderr, " string is too long!\n" );
602 		goto EXIT;
603 	}
604 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
605 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
606 		goto EXIT;
607 	}
608 
609 	/* write Contents(3) */
610 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_END_ST_OBJ );
611 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
612 		fprintf ( stderr, " string is too long!\n" );
613 		goto EXIT;
614 	}
615 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
616 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
617 		goto EXIT;
618 	}
619 
620 	/* <3> Length of Contents - stream */
621 	if ( ( p->offset_table[ SANE_PDF_PAGE_OBJ_CONTENTS_LEN ] = _get_current_offset( pwork->fd ) ) < 0 ) {
622 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
623 		goto EXIT;
624 	}
625 	/* write Length */
626 	len = snprintf( (char *)str, sizeof(str), SANE_PDF_LENGTH_OBJ,
627 			(int)(p->obj_id + SANE_PDF_PAGE_OBJ_CONTENTS_LEN),		/* object id ( Length of Contents ) */
628 			len_c );												/* length value */
629 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
630 		fprintf ( stderr, " string is too long!\n" );
631 		goto EXIT;
632 	}
633 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
634 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
635 		goto EXIT;
636 	}
637 
638 	/* <4> XObject(Image) */
639 	if ( ( p->offset_table[ SANE_PDF_PAGE_OBJ_IMAGE ] = _get_current_offset( pwork->fd ) ) < 0 ) {
640 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
641 		goto EXIT;
642 	}
643 	/* write XObject */
644 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_IMAGE_OBJ,
645 			(int)(p->obj_id + SANE_PDF_PAGE_OBJ_IMAGE),		/* object id ( XObject(Image) ) */
646 			(int)(p->obj_id + SANE_PDF_PAGE_OBJ_IMAGE_LEN),	/* object id ( Length of XObject ) */
647 			(int)p->w, (int)p->h,							/* Width/Height */
648 			ColorSpace[ type ],								/* ColorSpace */
649 			(int)BitsPerComponent[ type ] );				/* BitsPerComponent */
650 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
651 		fprintf ( stderr, " string is too long!\n" );
652 		goto EXIT;
653 	}
654 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
655 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
656 		goto EXIT;
657 	}
658 
659 	ret = SANE_NO_ERR;
660 EXIT:
661 	return ret;
662 
663 }
664 
sane_pdf_end_page(void * pw)665 SANE_Int sane_pdf_end_page( void *pw )
666 {
667 	SANE_Int		ret = SANE_ERR, ldata;
668 	SANE_pdf_page		*p = NULL;
669 	SANE_Byte		str[1024];
670 	SANE_Int			len;
671 	SANE_pdf_work		*pwork = (SANE_pdf_work *)pw;
672 
673 	if ( pwork == NULL ) {
674 		fprintf ( stderr, " Initialize parameter is error!\n" );
675 		goto	EXIT;
676 	}
677 
678 	p = pwork->last;
679 
680 	/* <1> endstream, endobj (XObject) */
681 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_END_ST_OBJ );
682 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
683 		fprintf ( stderr, " string is too long!\n" );
684 		goto EXIT;
685 	}
686 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
687 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
688 		goto EXIT;
689 	}
690 
691 	/* <2> Length of XObject - stream */
692 	if ( ( p->offset_table[ SANE_PDF_PAGE_OBJ_IMAGE_LEN ] = _get_current_offset( pwork->fd ) ) < 0 ) {
693 		fprintf ( stderr, " offset > %lld\n", SANE_PDF_XREF_MAX );
694 		goto EXIT;
695 	}
696 	/* write Length */
697 	len = snprintf( (char*)str, sizeof(str), SANE_PDF_LENGTH_OBJ,
698 			(int)(p->obj_id + SANE_PDF_PAGE_OBJ_IMAGE_LEN),		/* object id ( Length of XObject stream ) */
699 			(int)p->stream_len );								/* length value */
700 	if ( (size_t)len >= sizeof(str) || len < 0 ) {
701 		fprintf ( stderr, " string is too long!\n" );
702 		goto EXIT;
703 	}
704 	if ( ( ldata = re_write_if_fail( pwork->fd, str, len ) ) < 0 ) {
705 		fprintf ( stderr, " Error is occured in re_write_if_fail.\n" );
706 		goto EXIT;
707 	}
708 
709 	ret = SANE_NO_ERR;
710 	p->status = SANE_NO_ERR;
711 EXIT:
712 	return ret;
713 }
714