1
2 /*
3 * jslice.c
4 *
5 * This program will take a slice of a given picture and save it to
6 * a second file name
7 *
8 */
9
10 /*
11 * CHANGES
12 *
13 * 31/05/2000 - Added JavaScript enhancements and direct embedding
14 * 21/05/2000 - Added image-dimentions
15 * 25/05/2000 - Fixed up hyperlink detection from slice file
16 *
17 */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22
23 /*
24 * Include file for users of JPEG library.
25 * You will need to have included system headers that define at least
26 * the typedefs FILE and size_t before you can include jpeglib.h.
27 * (stdio.h is sufficient on ANSI-conforming systems.)
28 * You may also wish to include "jerror.h".
29 */
30
31 #include "jpeglib.h"
32 #include <setjmp.h>
33
34 JSAMPROW * arow; /* points to a row of JSAMPLES*/
35 JSAMPLE * buffer; /* Points to large array of R,G,B-order data */
36 JSAMPLE * image;
37 JSAMPROW wimage[4097]; /* array of rows for the "whole" image */
38 JSAMPROW pimage[4097]; /* array of rows for the "partial" image */
39
40 #define _VERSION "1.0.0"
41 #define _MESSAGE "<!-- ----------------------------------------\n\
42 Created with the assistance of jslice, v1.0.0 \n\
43 written by Paul L Daniels\n\
44 pldaniels@pldaniels.com\n\
45 http://www.pldaniels.com/jslice\n\
46 (C) P.L.Daniels 2000\n\
47 ------------------------------------------ -->\n\n"
48 #define _HELP "jslice v1.0.0 - (C) Paul L Daniels 2000\n\n\
49 Options Available -\n\
50 -i Input JPEG file [ie frontPage.jpg]\n\
51 -p Ouput JPEG file prefix [ie fpactive]\n\
52 -c Cut/Slice file [ie frontpage.slices]\n\
53 -q Quality of JPEG output [ie 85]\n\
54 -h OPTIONAL - Header file to prefix to HTML output [ie header.html]\n\
55 -f OPTIONAL - Footer file to suffix to HTML output [ie footer.html]\n\
56 --help produce this help.\n\
57 \n\
58 example of using jslice...\n\
59 jslice -i frontpage_active.jpg -p fpa -c frontpage.slices -q 75 -h header.html -f footer.html > index.html\n\n\
60 end of help.\n\n"
61 #define MAX_HEIGHT 4096
62 #define MAX_WIDTH 4096
63 #define MAX_LINK_SIZE 1024
64 #define MAX_SLICES 1000
65
66 #define _CUT 1
67 #define _UNCUT 0
68
69 #define _QUALITY_DEFAULT 75
70
71 #define _ERR_CANTOPENJPEG 101
72 #define _ERR_CANTWRITEJPEG 102
73 #define _ERR_CANTREADSCRIPT 103
74 #define _ERR_INSUFFICENTMEM 200
75
76 int image_height; /* Number of rows in image */
77 int image_width; /* Number of columns in image */
78 int p_height; /* width of image after cut */
79 int p_width; /* height of image after cut */
80
81
82 /* define a structure that will keep the details of each box slice.
83 */
84
85 struct _aslice {
86
87 int ax, bx, ay, by;
88 char link[MAX_LINK_SIZE+1];
89 };
90
91 typedef struct _aslice _tslice;
92 int slicesx[MAX_WIDTH];
93 int slicesy[MAX_HEIGHT];
94
95
96 /* And of course, create a global variable out of it.
97 */
98
99 _tslice slices[MAX_SLICES];
100
101
102 GLOBAL(void)
write_JPEG_file(char * filename,int quality)103 write_JPEG_file (char * filename, int quality)
104 {
105 /* This struct contains the JPEG compression parameters and pointers to
106 * working space (which is allocated as needed by the JPEG library).
107 * It is possible to have several such structures, representing multiple
108 * compression/decompression processes, in existence at once. We refer
109 * to any one struct (and its associated working data) as a "JPEG object".
110 */
111 struct jpeg_compress_struct cinfo;
112 /* This struct represents a JPEG error handler. It is declared separately
113 * because applications often want to supply a specialized error handler
114 * (see the second half of this file for an example). But here we just
115 * take the easy way out and use the standard error handler, which will
116 * print a message on stderr and call exit() if compression fails.
117 * Note that this struct must live as long as the main JPEG parameter
118 * struct, to avoid dangling-pointer problems.
119 */
120 struct jpeg_error_mgr jerr;
121 /* More stuff */
122 FILE * outfile; /* target file */
123 JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
124 int row_stride; /* physical row width in image buffer */
125
126 /* Step 1: allocate and initialize JPEG compression object */
127
128 /* We have to set up the error handler first, in case the initialization
129 * step fails. (Unlikely, but it could happen if you are out of memory.)
130 * This routine fills in the contents of struct jerr, and returns jerr's
131 * address which we place into the link field in cinfo.
132 */
133 cinfo.err = jpeg_std_error(&jerr);
134 /* Now we can initialize the JPEG compression object. */
135 jpeg_create_compress(&cinfo);
136
137 /* Step 2: specify data destination (eg, a file) */
138 /* Note: steps 2 and 3 can be done in either order. */
139
140 /* Here we use the library-supplied code to send compressed data to a
141 * stdio stream. You can also write your own code to do something else.
142 * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
143 * requires it in order to write binary files.
144 */
145 if ((outfile = fopen(filename, "wb")) == NULL) {
146 fprintf(stderr, "can't open %s\n", filename);
147 exit(_ERR_CANTWRITEJPEG);
148 }
149 jpeg_stdio_dest(&cinfo, outfile);
150
151 /* Step 3: set parameters for compression */
152
153 /* First we supply a description of the input image.
154 * Four fields of the cinfo struct must be filled in:
155 */
156 cinfo.image_width = p_width; /* image width and height, in pixels */
157 cinfo.image_height = p_height;
158 cinfo.input_components = 3; /* # of color components per pixel */
159 cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
160 /* Now use the library's routine to set default compression parameters.
161 * (You must set at least cinfo.in_color_space before calling this,
162 * since the defaults depend on the source color space.)
163 */
164 jpeg_set_defaults(&cinfo);
165 /* Now you can set any non-default parameters you wish to.
166 * Here we just illustrate the use of quality (quantization table) scaling:
167 */
168 jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
169
170 /* Step 4: Start compressor */
171
172 /* TRUE ensures that we will write a complete interchange-JPEG file.
173 * Pass TRUE unless you are very sure of what you're doing.
174 */
175 jpeg_start_compress(&cinfo, TRUE);
176
177 /* Step 5: while (scan lines remain to be written) */
178 /* jpeg_write_scanlines(...); */
179
180 /* Here we use the library's state variable cinfo.next_scanline as the
181 * loop counter, so that we don't have to keep track ourselves.
182 * To keep things simple, we pass one scanline per call; you can pass
183 * more if you wish, though.
184 */
185 row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
186
187 while (cinfo.next_scanline < cinfo.image_height) {
188 /* jpeg_write_scanlines expects an array of pointers to scanlines.
189 * Here the array is only one element long, but you could pass
190 * more than one scanline at a time if that's more convenient.
191 */
192 row_pointer[0] = pimage[cinfo.next_scanline];
193 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
194 }
195
196 /* Step 6: Finish compression */
197
198 jpeg_finish_compress(&cinfo);
199 /* After finish_compress, we can close the output file. */
200 fclose(outfile);
201
202 /* Step 7: release JPEG compression object */
203
204 /* This is an important step since it will release a good deal of memory. */
205 jpeg_destroy_compress(&cinfo);
206
207 /* And we're done! */
208 }
209
210
211 /*
212 * Here's the extended error handler struct:
213 */
214
215 struct my_error_mgr {
216 struct jpeg_error_mgr pub; /* "public" fields */
217
218 jmp_buf setjmp_buffer; /* for return to caller */
219 };
220
221 typedef struct my_error_mgr * my_error_ptr;
222
223 /*
224 * Here's the routine that will replace the standard error_exit method:
225 */
226
227 METHODDEF(void)
my_error_exit(j_common_ptr cinfo)228 my_error_exit (j_common_ptr cinfo)
229 {
230 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
231 my_error_ptr myerr = (my_error_ptr) cinfo->err;
232
233 /* Always display the message. */
234 /* We could postpone this until after returning, if we chose. */
235 (*cinfo->err->output_message) (cinfo);
236
237 /* Return control to the setjmp point */
238 longjmp(myerr->setjmp_buffer, 1);
239 }
240
241
242 /*
243 * Sample routine for JPEG decompression. We assume that the source file name
244 * is passed in. We want to return 1 on success, 0 on error.
245 */
246
247
248 GLOBAL(int)
read_JPEG_file(char * filename)249 read_JPEG_file (char * filename)
250 {
251
252
253 /* This struct contains the JPEG decompression parameters and pointers to
254 * working space (which is allocated as needed by the JPEG library).
255 */
256 struct jpeg_decompress_struct cinfo;
257 /* We use our private extension JPEG error handler.
258 * Note that this struct must live as long as the main JPEG parameter
259 * struct, to avoid dangling-pointer problems.
260 */
261 struct my_error_mgr jerr;
262 /* More stuff */
263 FILE * infile; /* source file */
264 JSAMPROW row_pointer[1];
265
266 int row_stride; /* physical row width in output buffer */
267
268
269 if ((infile = fopen(filename, "rb")) == NULL) {
270 fprintf(stderr, "can't open %s\n", filename);
271 exit(_ERR_CANTOPENJPEG);
272 }
273
274 cinfo.err = jpeg_std_error(&jerr.pub);
275 jerr.pub.error_exit = my_error_exit;
276
277 if (setjmp(jerr.setjmp_buffer)) {
278 jpeg_destroy_decompress(&cinfo);
279 fclose(infile);
280 exit(_ERR_INSUFFICENTMEM);
281 }
282
283 jpeg_create_decompress(&cinfo);
284
285 jpeg_stdio_src(&cinfo, infile);
286
287 (void) jpeg_read_header(&cinfo, TRUE);
288 (void) jpeg_start_decompress(&cinfo);
289
290
291 image_width = cinfo.output_width;
292 image_height = cinfo.output_height;
293
294 row_stride = cinfo.output_width * cinfo.output_components;
295
296
297 while (cinfo.output_scanline < cinfo.output_height) {
298
299 wimage[cinfo.output_scanline] = malloc(sizeof(JSAMPLE) *(row_stride+1));
300 row_pointer[0] = wimage[cinfo.output_scanline];
301
302 (void) jpeg_read_scanlines(&cinfo, row_pointer, 1);
303
304 /* Assume put_scanline_someplace wants a pointer and sample count. */
305
306 }
307
308 /* Step 7: Finish decompression */
309
310 (void) jpeg_finish_decompress(&cinfo);
311 /* We can ignore the return value since suspension is not possible
312 * with the stdio data source.
313 */
314
315 /* Step 8: Release JPEG decompression object */
316
317 /* This is an important step since it will release a good deal of memory. */
318 jpeg_destroy_decompress(&cinfo);
319
320 /* After finish_decompress, we can close the input file.
321 * Here we postpone it until after no more JPEG errors are possible,
322 * so as to simplify the setjmp error logic above. (Actually, I don't
323 * think that jpeg_destroy can do an error exit, but why assume anything...)
324 */
325 fclose(infile);
326
327 /* At this point you may want to check to see whether any corrupt-data
328 * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
329 */
330
331 /* And we're done! */
332 return 1;
333 }
334
335
336
337
338
get_cut_count_x(int maxx)339 int get_cut_count_x( int maxx ) {
340
341 int count = 0;
342 int x;
343
344 for (x = 0; x < maxx; x++) {
345 if (slicesx[x] != _UNCUT) count++;
346 }
347
348 return count;
349 }
350
351
get_cut_count_y(int maxy)352 int get_cut_count_y( int maxy ) {
353
354 int count = 0;
355 int y;
356
357 for (y = 0; y < maxy; y++) {
358 if (slicesy[y] != _UNCUT) count++;
359 }
360
361 return count;
362 }
363
364
365
366
367
count_cuts(int sx,int fx)368 int count_cuts( int sx, int fx ) {
369
370 int cuts = 0;
371 int cx;
372
373 /* for every pixel across the horizontal...*/
374 for (cx = sx; cx < fx; cx++){
375
376 /* if we've found a cut mark...*/
377 if (slicesx[cx] != _UNCUT) {
378
379 /* increase our cut count */
380 cuts++;
381
382 /* if the next pixel is also cut, but from the same row
383 * then we must skip it, as it's just consecutive cutouts
384 */
385 if (slicesx[cx+1] == slicesx[cx]) {
386 cx++;
387 }
388
389 } /* if slices != UNCUT */
390
391 } /* for */
392
393 return cuts;
394 }
395
396
397
398
399
400 /* cut
401 *
402 * this procesdure "cuts" out the required portion of the picture.
403 *
404 */
405
cut(int ax,int ay,int bx,int by)406 int cut( int ax, int ay, int bx, int by ) {
407
408 int cx, cy;
409
410 /* get our dimentions of the image,
411 * remember, that a image has a MINIMUM size of 1x1
412 * NOT 0x0
413 */
414 p_width = bx - ax +1;
415 p_height = by - ay +1;
416
417 /* for every row... */
418 for (cy = 0; cy < p_height; cy++) {
419
420 /* allocate the memory for the new row of the image */
421 pimage[cy] = malloc(sizeof(JSAMPLE) *(p_width*3));
422
423 /* for every pixel */
424 for (cx = 0; cx < (p_width*3); cx++) {
425
426 /* copy across the pixels */
427 pimage[cy][cx] = wimage[cy+ay][cx+(ax*3)];
428
429 } /* for cx */
430 } /* for cy */
431
432 return 0;
433
434 }
435
436
437
438 /*
439 * dump_slices
440 *
441 * Debugging and information routine
442 */
dump_slices(void)443 int dump_slices( void ) {
444
445 int i;
446 fprintf(stdout,"\n<!-- ");
447 for (i = 0; i < MAX_WIDTH; i++){
448 if (slicesx[i] != _UNCUT) fprintf(stdout,"%d, ",i);
449 }
450 fprintf(stdout," -->\n");
451
452 return 0;
453 }
454
455
456
457
458
script_cut(char * script_name,char * foutprefix,int quality)459 int script_cut( char *script_name, char *foutprefix, int quality ){
460
461 #define MAX 1023
462
463 FILE *script;
464 int count;
465 int ax;
466 int i;
467 int slicewidth;
468 int tally;
469 int cols;
470 int lastx;
471 int ffr;
472 int slicew, sliceh;
473 int real_url = 0;
474 int urltest;
475 int linecount = 0;
476 char line[1024];
477 char foutname[1024];
478 char *link;
479
480 script = fopen(script_name,"r");
481
482 /*
483 * Make sure we don't try reading dud files
484 */
485 if (script == NULL) {
486 fprintf(stderr,"Error when trying to open the slice-coordinate file %s\nPlease check to see that the file name is correct, and that it is a text only file\n",script_name);
487 exit(_ERR_CANTREADSCRIPT);
488 }
489
490 count = 0;
491
492 /* clean out the slices rulers */
493 for (ax = 0; ax < MAX_WIDTH; ax++) {
494 slicesx[ax] = _UNCUT;
495 slicesy[ax] = _UNCUT;
496 }
497
498 /* get all our lines... */
499 while (fgets(line, MAX, script) != NULL) {
500
501 linecount++;
502
503 /*
504 * Digest our line if it's not a comment
505 */
506 if ((line[0] != '#')&&(strlen(line) > 7)){
507
508 /* get the coordinates... */
509 slices[count].ax = atoi(strtok(line," "));
510 if (slices[count].ax > image_width) {
511 fprintf(stderr,"Line %d: X1 value of %d too large, reduced to %d\n",linecount,slices[count].ax,image_width);
512 slices[count].ax = image_width;
513 }
514 if (slices[count].ax < 0) {
515 fprintf(stderr,"Line %d: X1 value of %d too small, value now 0.\n",linecount,slices[count].ax);
516 slices[count].ax = 0;
517 }
518
519 slices[count].ay = atoi(strtok(NULL," "));
520 if (slices[count].ay >= image_height) {
521 fprintf(stderr,"Line %d: Y1 value of %d too large, reduced to %d\n",linecount,slices[count].ay,image_height-2);
522 slices[count].ay = image_height-2;
523 }
524 if (slices[count].ay < 0) {
525 fprintf(stderr,"Line %d: Y1 value of %d too small, value now 0.\n",linecount,slices[count].ay);
526 slices[count].ay = 0;
527 }
528
529 slices[count].bx = atoi(strtok(NULL," "));
530 if (slices[count].bx > image_width) {
531 fprintf(stderr,"Line %d: X2 value of %d too large, reduced to %d\n",linecount,slices[count].bx,image_width);
532 slices[count].bx = image_width;
533 }
534 if (slices[count].bx < 0) {
535 fprintf(stderr,"Line %d: X2 value of %d too small, value now 0.\n",linecount,slices[count].bx);
536 slices[count].bx = 0;
537 }
538
539 slices[count].by = atoi(strtok(NULL," "));
540 if (slices[count].by >= image_height) {
541 fprintf(stderr,"Line %d: Y2 value of %d too large, reduced to %d\n",linecount,slices[count].by,image_height-2);
542 slices[count].by = image_height-2;
543 }
544 if (slices[count].by < 0) {
545 fprintf(stderr,"Line %d: Y2 value of %d too small, value now 0.\n",linecount,slices[count].by);
546 slices[count].by = 0;
547 }
548
549 /* get our link... */
550 link = strtok(NULL,"\n\r");
551
552 /*
553 * Test to see that the URL string is potentially valid
554 *
555 */
556 if (link != NULL) {
557 for (urltest = 0; urltest < strlen(link); urltest++){
558 real_url += isalnum(link[urltest]);
559 }
560 if (urltest > 0) strcpy(slices[count].link, link);
561 }
562 else slices[count].link[0] = '\0';
563
564
565 /*
566 * Stamp in the slice arrays our marks where we have to slice
567 *
568 * 0.1.3 - We mark in the top-y value in the ax and bx here
569 * so that we can determin if we are counting one or two
570 * columns when we come to counting up the number of cuts
571 * between a given ax -> bx
572 *
573 */
574 slicesx[slices[count].ax] = slices[count].ay +_CUT;
575 slicesx[slices[count].bx] = slices[count].ay +_CUT;
576 slicesy[slices[count].ay] = _CUT;
577 slicesy[slices[count].by] = _CUT;
578
579 count++;
580 }
581 }
582
583 /*
584 * Let the HTML Table start flowing
585 *
586 */
587 fprintf(stdout,"<TABLE border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><TR>\n");
588
589 /*
590 * Print out our SLICING SPACERS!
591 *
592 */
593 slicewidth = tally = 1;
594 for ( ax = 1; ax <= image_width; ax++ ){
595 if (slicesx[ax] != _UNCUT) {
596 if (slicesx[ax-1] != slicesx[ax]){
597 fprintf(stdout,"<TD><img src=\"spacer.gif\" width=\"%d\" height=\"1\"></td>",slicewidth);
598 tally += slicewidth;
599 slicewidth=0;
600 }
601 }
602 slicewidth++;
603 }
604
605 fprintf(stdout,"\n<!-- total width = %d -->\n",tally);
606 fprintf(stdout,"</tr>\n<TR>\n");
607
608 /* print out commentory information about the slices
609 * to the HTML file
610 */
611 dump_slices();
612
613 lastx = -1;
614 ffr = 1;
615 tally = 0;
616
617 for ( i = 0; i < count; i++ ){
618
619 /* create our filename of the output slice */
620 sprintf(foutname,"%s%d.jpg",foutprefix,i+1);
621
622 /* determine how many columns we have for this slice */
623 cols = count_cuts(slices[i].ax, slices[i].bx);
624
625 /* Catch the scenario where the blocks wrap back around */
626 if (lastx >= slices[i].ax){
627 ffr = 1;
628 fprintf(stdout,"</tr>\n<TR>\n");
629 }
630
631 lastx = slices[i].ax;
632
633
634 slicew = slices[i].bx -slices[i].ax +1;
635 sliceh = slices[i].by -slices[i].ay +1;
636
637 if (slices[i].link[0] != '\0') {
638 fprintf(stdout,"<TD colspan=\"%d\"><a href=\"%s\"><img src=\"%s\" border=\"0\" width=\"%d\" height=\"%d\"></a></td>\n",cols,slices[i].link,foutname,slicew,sliceh);
639 } else {
640 fprintf(stdout,"<TD colspan=\"%d\"><img src=\"%s\" border=\"0\" width=\"%d\" height=\"%d\"></td>\n",cols,foutname,slicew, sliceh);
641 }
642
643 cut(slices[i].ax, slices[i].ay, slices[i].bx, slices[i].by);
644
645 write_JPEG_file(foutname,quality);
646
647 ffr = 0;
648 }
649
650 fprintf(stdout,"\n<!-- total width = %d -->\n",tally);
651
652 fprintf(stdout,"</tr></table>");
653
654
655
656 return 0;
657 }
658
659
660
661
662 /*
663 * filetostdout
664 *
665 * prints a given file to stdout
666 *
667 */
filetostdout(char * fname)668 int filetostdout( char *fname ){
669
670 FILE *f = fopen(fname,"r");
671 char achar;
672
673 /* if the file opened okay... */
674 if (f) {
675 while ( (achar = fgetc(f))!= EOF) fprintf(stdout,"%c",achar);
676 fclose(f);
677 }
678 else {
679 fprintf(stderr,"Error: could not open file %s\n",fname);
680 }
681
682 return 0;
683 }
684
685
686
687 /*
688 * main
689 *
690 * The basic procedure is as follows...
691 *
692 * read in the input jpeg,
693 * x1,y1 -> x2, y2 coord's
694 * output file name, and
695 * the quality factor
696 *
697 * read in the required file
698 * copy the required "slice" into a new buffer
699 * write the new buffer to the new file name
700 *
701 */
main(int argc,char ** argv)702 int main( int argc, char **argv ) {
703
704 int quality;
705 int aindex; /* argv index */
706 char *infile=NULL, *outfile=NULL, *scriptfile=NULL, *headerfile=NULL, *footerfile=NULL;
707
708
709 /* if (argc < 9) {
710
711 fprintf(stderr,"jslice v%s usage :\n %s -i <input jpeg> -p <output jpeg prefix> \
712 -c <cut list file> -q <output quality> \
713 [-h <header file>] [-f <footer file>]\n\n",_VERSION,argv[0]);
714
715 exit(1);
716 }
717 */
718 /*
719 * Get the command line parameters ...
720 */
721 for ( aindex = 1; aindex < argc; aindex++ ){
722
723 if (argv[aindex][0] == '-'){
724
725 if ( argv[aindex][1] == 'i' ){
726 infile = argv[aindex+1];
727 }
728 else
729 if ( argv[aindex][1] == 'p' ){
730 outfile = argv[aindex+1];
731 }
732 else
733 if ( argv[aindex][1] == 'c' ){
734 scriptfile = argv[aindex+1];
735 }
736 else
737 if ( argv[aindex][1] == 'q' ){
738 quality = atoi(argv[aindex+1]);
739 }
740 else
741 if ( argv[aindex][1] == 'h' ){
742 headerfile = argv[aindex+1];
743 }
744 else
745 if ( argv[aindex][1] == 'f' ){
746 footerfile = argv[aindex+1];
747 }
748 else
749 if (strstr(argv[aindex],"help")){
750 fprintf(stderr,_HELP);
751 exit(1);
752 }
753 else {
754 /* if nothing fitted... then dump HELP!! */
755 fprintf(stderr,_HELP);
756 exit(1);
757 }
758 } /* if this was a '-' argument */
759
760 } /* for */
761
762
763 /*
764 * Check for errors in the input...
765 *
766 */
767
768 if (!infile) {
769 fprintf(stderr,"Error: I -need- an input JPEG file, use the -i option\n");
770 exit(1);
771 }
772
773 if (!outfile) {
774 fprintf(stderr,"Error: output file PREFIX required, use the -p option\n");
775 exit(1);
776 }
777
778 if (!scriptfile) {
779 fprintf(stderr,"Error: cutlist file not specified, use the -c option\n");
780 exit(1);
781 }
782
783 if (!quality) {
784 fprintf(stderr,"Warning: quality not specified, using %d%%\n",_QUALITY_DEFAULT);
785 quality = _QUALITY_DEFAULT;
786 }
787
788 if ((quality > 100)||(quality < 1)) {
789 fprintf(stderr,"Invalid JPEG quality setting, please choose a value between 1 and 100\n");
790 exit(1);
791 }
792
793
794 /* Now, let us read the input JPEG file to the buffer */
795 read_JPEG_file(infile);
796
797 /* Test to see if this picture isn't too large for our jslice program
798 */
799 if ((image_width >= MAX_WIDTH) || (image_height >= MAX_HEIGHT)){
800 fprintf(stderr,"Sorry, but jslice has been compiled only to handle pictures up to %d x %d pixels\n",MAX_WIDTH,MAX_HEIGHT);
801 exit(1);
802 }
803
804 /*
805 * We've gotten this far... now lets actually produce some results
806 */
807
808 /*
809 * Print my message
810 *
811 */
812 fprintf(stdout,_MESSAGE);
813
814
815 if (headerfile) {
816 filetostdout(headerfile);
817 }
818
819 script_cut(scriptfile, outfile, quality);
820
821 if (footerfile) {
822 filetostdout(footerfile);
823 }
824
825 return 0;
826 }
827