comparison src/glyphs-eimage.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents fdefd0186b75
children e38acbeb1cae
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* EImage-specific Lisp objects. 1 /* EImage-specific Lisp objects.
2 Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc. 2 Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc.
3 Copyright (C) 1995 Board of Trustees, University of Illinois. 3 Copyright (C) 1995 Board of Trustees, University of Illinois.
4 Copyright (C) 1995 Tinker Systems 4 Copyright (C) 1995 Tinker Systems
5 Copyright (C) 1995, 1996 Ben Wing 5 Copyright (C) 1995, 1996, 2001 Ben Wing
6 Copyright (C) 1995 Sun Microsystems 6 Copyright (C) 1995 Sun Microsystems
7 7
8 This file is part of XEmacs. 8 This file is part of XEmacs.
9 9
10 XEmacs is free software; you can redistribute it and/or modify it 10 XEmacs is free software; you can redistribute it and/or modify it
71 } 71 }
72 #endif 72 #endif
73 #else 73 #else
74 #include <setjmp.h> 74 #include <setjmp.h>
75 #endif 75 #endif
76 #ifdef FILE_CODING
77 #include "file-coding.h" 76 #include "file-coding.h"
78 #endif
79 77
80 #ifdef HAVE_TIFF 78 #ifdef HAVE_TIFF
81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff); 79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
82 Lisp_Object Qtiff; 80 Lisp_Object Qtiff;
83 #endif 81 #endif
142 /* Stream that we need to close */ 140 /* Stream that we need to close */
143 FILE *instream; 141 FILE *instream;
144 /* Object that holds state info for JPEG decoding */ 142 /* Object that holds state info for JPEG decoding */
145 struct jpeg_decompress_struct *cinfo_ptr; 143 struct jpeg_decompress_struct *cinfo_ptr;
146 /* EImage data */ 144 /* EImage data */
147 unsigned char *eimage; 145 UChar_Binary *eimage;
148 }; 146 };
149 147
150 static Lisp_Object 148 static Lisp_Object
151 jpeg_instantiate_unwind (Lisp_Object unwind_obj) 149 jpeg_instantiate_unwind (Lisp_Object unwind_obj)
152 { 150 {
156 free_opaque_ptr (unwind_obj); 154 free_opaque_ptr (unwind_obj);
157 if (data->cinfo_ptr) 155 if (data->cinfo_ptr)
158 jpeg_destroy_decompress (data->cinfo_ptr); 156 jpeg_destroy_decompress (data->cinfo_ptr);
159 157
160 if (data->instream) 158 if (data->instream)
161 fclose (data->instream); 159 retry_fclose (data->instream);
162 160
163 if (data->eimage) xfree (data->eimage); 161 if (data->eimage) xfree (data->eimage);
164 162
165 return Qnil; 163 return Qnil;
166 } 164 }
301 #else 299 #else
302 METHODDEF void 300 METHODDEF void
303 #endif 301 #endif
304 my_jpeg_output_message (j_common_ptr cinfo) 302 my_jpeg_output_message (j_common_ptr cinfo)
305 { 303 {
306 char buffer[JMSG_LENGTH_MAX]; 304 Extbyte buffer[JMSG_LENGTH_MAX];
305 Intbyte *intbuf;
307 306
308 /* Create the message */ 307 /* Create the message */
309 (*cinfo->err->format_message) (cinfo, buffer); 308 (*cinfo->err->format_message) (cinfo, buffer);
310 warn_when_safe (Qjpeg, Qinfo, "%s", buffer); 309 EXTERNAL_TO_C_STRING (buffer, intbuf, Qnative);
310 warn_when_safe (Qjpeg, Qinfo, "%s", intbuf);
311 } 311 }
312 312
313 /* The code in this routine is based on example.c from the JPEG library 313 /* The code in this routine is based on example.c from the JPEG library
314 source code and from gif_instantiate() */ 314 source code and from gif_instantiate() */
315 static void 315 static void
354 * We need to clean up the JPEG object, close the input file, and return. 354 * We need to clean up the JPEG object, close the input file, and return.
355 */ 355 */
356 356
357 { 357 {
358 Lisp_Object errstring; 358 Lisp_Object errstring;
359 char buffer[JMSG_LENGTH_MAX]; 359 Extbyte buffer[JMSG_LENGTH_MAX];
360 360
361 /* Create the message */ 361 /* Create the message */
362 (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer); 362 (*cinfo.err->format_message) ((j_common_ptr) &cinfo, buffer);
363 errstring = build_string (buffer); 363 errstring = build_ext_string (buffer, Qnative);
364 364
365 signal_image_error_2 ("JPEG decoding error", 365 signal_image_error_2 ("JPEG decoding error",
366 errstring, instantiator); 366 errstring, instantiator);
367 } 367 }
368 } 368 }
416 /* Step 5: Start decompressor */ 416 /* Step 5: Start decompressor */
417 jpeg_start_decompress (&cinfo); 417 jpeg_start_decompress (&cinfo);
418 418
419 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/ 419 /* Step 6: Read in the data and put into EImage format (8bit RGB triples)*/
420 420
421 unwind.eimage = (unsigned char*) xmalloc (cinfo.output_width * cinfo.output_height * 3); 421 unwind.eimage = (UChar_Binary*) xmalloc (cinfo.output_width * cinfo.output_height * 3);
422 if (!unwind.eimage) 422 if (!unwind.eimage)
423 signal_image_error("Unable to allocate enough memory for image", instantiator); 423 signal_image_error("Unable to allocate enough memory for image", instantiator);
424 424
425 { 425 {
426 JSAMPARRAY row_buffer; /* Output row buffer */ 426 JSAMPARRAY row_buffer; /* Output row buffer */
427 JSAMPLE *jp; 427 JSAMPLE *jp;
428 int row_stride; /* physical row width in output buffer */ 428 int row_stride; /* physical row width in output buffer */
429 unsigned char *op = unwind.eimage; 429 UChar_Binary *op = unwind.eimage;
430 430
431 /* We may need to do some setup of our own at this point before reading 431 /* We may need to do some setup of our own at this point before reading
432 * the data. After jpeg_start_decompress() we have the correct scaled 432 * the data. After jpeg_start_decompress() we have the correct scaled
433 * output image dimensions available 433 * output image dimensions available
434 * We need to make an output work buffer of the right size. 434 * We need to make an output work buffer of the right size.
456 for (i = 0; i < (int) cinfo.output_width; i++) 456 for (i = 0; i < (int) cinfo.output_width; i++)
457 { 457 {
458 int clr; 458 int clr;
459 if (jpeg_gray) 459 if (jpeg_gray)
460 { 460 {
461 unsigned char val; 461 UChar_Binary val;
462 #if (BITS_IN_JSAMPLE == 8) 462 #if (BITS_IN_JSAMPLE == 8)
463 val = (unsigned char) *jp++; 463 val = (UChar_Binary) *jp++;
464 #else /* other option is 12 */ 464 #else /* other option is 12 */
465 val = (unsigned char) (*jp++ >> 4); 465 val = (UChar_Binary) (*jp++ >> 4);
466 #endif 466 #endif
467 for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */ 467 for (clr = 0; clr < 3; clr++) /* copy the same value into RGB */
468 *op++ = val; 468 *op++ = val;
469 } 469 }
470 else 470 else
471 { 471 {
472 for (clr = 0; clr < 3; clr++) 472 for (clr = 0; clr < 3; clr++)
473 #if (BITS_IN_JSAMPLE == 8) 473 #if (BITS_IN_JSAMPLE == 8)
474 *op++ = (unsigned char)*jp++; 474 *op++ = (UChar_Binary)*jp++;
475 #else /* other option is 12 */ 475 #else /* other option is 12 */
476 *op++ = (unsigned char)(*jp++ >> 4); 476 *op++ = (UChar_Binary)(*jp++ >> 4);
477 #endif 477 #endif
478 } 478 }
479 } 479 }
480 } 480 }
481 } 481 }
496 * with the stdio data source. 496 * with the stdio data source.
497 */ 497 */
498 498
499 /* And we're done! */ 499 /* And we're done! */
500 /* This will clean up everything else. */ 500 /* This will clean up everything else. */
501 unbind_to (speccount, Qnil); 501 unbind_to (speccount);
502 } 502 }
503 503
504 #endif /* HAVE_JPEG */ 504 #endif /* HAVE_JPEG */
505 505
506 #ifdef HAVE_GIF 506 #ifdef HAVE_GIF
533 everything gets cleaned up in the presence of an error, we 533 everything gets cleaned up in the presence of an error, we
534 use an unwind_protect(). */ 534 use an unwind_protect(). */
535 535
536 struct gif_unwind_data 536 struct gif_unwind_data
537 { 537 {
538 unsigned char *eimage; 538 UChar_Binary *eimage;
539 /* Object that holds the decoded data from a GIF file */ 539 /* Object that holds the decoded data from a GIF file */
540 GifFileType *giffile; 540 GifFileType *giffile;
541 }; 541 };
542 542
543 static Lisp_Object 543 static Lisp_Object
583 return 0; 583 return 0;
584 } 584 }
585 585
586 struct gif_error_struct 586 struct gif_error_struct
587 { 587 {
588 const char *err_str; /* return the error string */ 588 const Extbyte *err_str; /* return the error string */
589 jmp_buf setjmp_buffer; /* for return to caller */ 589 jmp_buf setjmp_buffer; /* for return to caller */
590 }; 590 };
591 591
592 static void 592 static void
593 gif_error_func (const char *err_str, VoidPtr error_ptr) 593 gif_error_func (const Extbyte *err_str, VoidPtr error_ptr)
594 { 594 {
595 struct gif_error_struct *error_data = (struct gif_error_struct *) error_ptr; 595 struct gif_error_struct *error_data = (struct gif_error_struct *) error_ptr;
596 596
597 /* return to setjmp point */ 597 /* return to setjmp point */
598 error_data->err_str = err_str; 598 error_data->err_str = err_str;
633 /* set up error facilities */ 633 /* set up error facilities */
634 if (setjmp(gif_err.setjmp_buffer)) 634 if (setjmp(gif_err.setjmp_buffer))
635 { 635 {
636 /* An error was signaled. No clean up is needed, as unwind handles that 636 /* An error was signaled. No clean up is needed, as unwind handles that
637 for us. Just pass the error along. */ 637 for us. Just pass the error along. */
638 Intbyte *interr;
638 Lisp_Object errstring; 639 Lisp_Object errstring;
639 errstring = build_string (gif_err.err_str); 640 EXTERNAL_TO_C_STRING (gif_err.err_str, interr, Qnative);
641 errstring = build_msg_intstring (interr);
640 signal_image_error_2 ("GIF decoding error", errstring, instantiator); 642 signal_image_error_2 ("GIF decoding error", errstring, instantiator);
641 } 643 }
642 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err); 644 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err);
643 645
644 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary); 646 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary);
658 660
659 /* 3. Now create the EImage(s) */ 661 /* 3. Now create the EImage(s) */
660 { 662 {
661 ColorMapObject *cmo = unwind.giffile->SColorMap; 663 ColorMapObject *cmo = unwind.giffile->SColorMap;
662 int i, j, row, pass, interlace, slice; 664 int i, j, row, pass, interlace, slice;
663 unsigned char *eip; 665 UChar_Binary *eip;
664 /* interlaced gifs have rows in this order: 666 /* interlaced gifs have rows in this order:
665 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ 667 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
666 static int InterlacedOffset[] = { 0, 4, 2, 1 }; 668 static int InterlacedOffset[] = { 0, 4, 2, 1 };
667 static int InterlacedJumps[] = { 8, 8, 4, 2 }; 669 static int InterlacedJumps[] = { 8, 8, 4, 2 };
668 670
669 height = unwind.giffile->SHeight; 671 height = unwind.giffile->SHeight;
670 width = unwind.giffile->SWidth; 672 width = unwind.giffile->SWidth;
671 unwind.eimage = (unsigned char*) 673 unwind.eimage = (UChar_Binary*)
672 xmalloc (width * height * 3 * unwind.giffile->ImageCount); 674 xmalloc (width * height * 3 * unwind.giffile->ImageCount);
673 if (!unwind.eimage) 675 if (!unwind.eimage)
674 signal_image_error("Unable to allocate enough memory for image", instantiator); 676 signal_image_error("Unable to allocate enough memory for image", instantiator);
675 677
676 /* write the data in EImage format (8bit RGB triples) */ 678 /* write the data in EImage format (8bit RGB triples) */
698 row = InterlacedOffset[++pass]; 700 row = InterlacedOffset[++pass];
699 } 701 }
700 eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3); 702 eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3);
701 for (j = 0; j < width; j++) 703 for (j = 0; j < width; j++)
702 { 704 {
703 unsigned char pixel = 705 UChar_Binary pixel =
704 unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j]; 706 unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j];
705 *eip++ = cmo->Colors[pixel].Red; 707 *eip++ = cmo->Colors[pixel].Red;
706 *eip++ = cmo->Colors[pixel].Green; 708 *eip++ = cmo->Colors[pixel].Green;
707 *eip++ = cmo->Colors[pixel].Blue; 709 *eip++ = cmo->Colors[pixel].Blue;
708 } 710 }
741 743
742 if (!NILP (tid)) 744 if (!NILP (tid))
743 IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid); 745 IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid);
744 } 746 }
745 747
746 unbind_to (speccount, Qnil); 748 unbind_to (speccount);
747 } 749 }
748 750
749 #endif /* HAVE_GIF */ 751 #endif /* HAVE_GIF */
750 752
751 753
821 } 823 }
822 824
823 struct png_unwind_data 825 struct png_unwind_data
824 { 826 {
825 FILE *instream; 827 FILE *instream;
826 unsigned char *eimage; 828 UChar_Binary *eimage;
827 png_structp png_ptr; 829 png_structp png_ptr;
828 png_infop info_ptr; 830 png_infop info_ptr;
829 }; 831 };
830 832
831 static Lisp_Object 833 static Lisp_Object
836 838
837 free_opaque_ptr (unwind_obj); 839 free_opaque_ptr (unwind_obj);
838 if (data->png_ptr) 840 if (data->png_ptr)
839 png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL); 841 png_destroy_read_struct (&(data->png_ptr), &(data->info_ptr), (png_infopp)NULL);
840 if (data->instream) 842 if (data->instream)
841 fclose (data->instream); 843 retry_fclose (data->instream);
842 844
843 if (data->eimage) xfree(data->eimage); 845 if (data->eimage) xfree(data->eimage);
844 846
845 return Qnil; 847 return Qnil;
846 } 848 }
915 917
916 png_read_info (png_ptr, info_ptr); 918 png_read_info (png_ptr, info_ptr);
917 919
918 { 920 {
919 int y; 921 int y;
920 unsigned char **row_pointers; 922 UChar_Binary **row_pointers;
921 height = info_ptr->height; 923 height = info_ptr->height;
922 width = info_ptr->width; 924 width = info_ptr->width;
923 925
924 /* Wow, allocate all the memory. Truly, exciting. */ 926 /* Wow, allocate all the memory. Truly, exciting. */
925 unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3); 927 unwind.eimage = xnew_array_and_zero (UChar_Binary, width * height * 3);
926 /* libpng expects that the image buffer passed in contains a 928 /* libpng expects that the image buffer passed in contains a
927 picture to draw on top of if the png has any transparencies. 929 picture to draw on top of if the png has any transparencies.
928 This could be a good place to pass that in... */ 930 This could be a good place to pass that in... */
929 931
930 row_pointers = xnew_array (png_byte *, height); 932 row_pointers = xnew_array (png_byte *, height);
1027 init_image_instance_from_eimage, 1029 init_image_instance_from_eimage,
1028 (ii, width, height, 1, unwind.eimage, dest_mask, 1030 (ii, width, height, 1, unwind.eimage, dest_mask,
1029 instantiator, domain)); 1031 instantiator, domain));
1030 1032
1031 /* This will clean up everything else. */ 1033 /* This will clean up everything else. */
1032 unbind_to (speccount, Qnil); 1034 unbind_to (speccount);
1033 } 1035 }
1034 1036
1035 #endif /* HAVE_PNG */ 1037 #endif /* HAVE_PNG */
1036 1038
1037 1039
1060 return IMAGE_COLOR_PIXMAP_MASK; 1062 return IMAGE_COLOR_PIXMAP_MASK;
1061 } 1063 }
1062 1064
1063 struct tiff_unwind_data 1065 struct tiff_unwind_data
1064 { 1066 {
1065 unsigned char *eimage; 1067 UChar_Binary *eimage;
1066 /* Object that holds the decoded data from a TIFF file */ 1068 /* Object that holds the decoded data from a TIFF file */
1067 TIFF *tiff; 1069 TIFF *tiff;
1068 }; 1070 };
1069 1071
1070 static Lisp_Object 1072 static Lisp_Object
1249 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); 1251 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1250 UChar_Binary *bytes; 1252 UChar_Binary *bytes;
1251 Bytecount len; 1253 Bytecount len;
1252 1254
1253 uint32 *raster; 1255 uint32 *raster;
1254 unsigned char *ep; 1256 UChar_Binary *ep;
1255 1257
1256 assert (!NILP (data)); 1258 assert (!NILP (data));
1257 1259
1258 /* #### This is a definite problem under Mule due to the amount of 1260 /* #### This is a definite problem under Mule due to the amount of
1259 stack data it might allocate. Think about Lstreams... */ 1261 stack data it might allocate. Think about Lstreams... */
1272 if (!unwind.tiff) 1274 if (!unwind.tiff)
1273 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator); 1275 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator);
1274 1276
1275 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); 1277 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1276 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height); 1278 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1277 unwind.eimage = (unsigned char *) xmalloc (width * height * 3); 1279 unwind.eimage = (UChar_Binary *) xmalloc (width * height * 3);
1278 1280
1279 /* #### This is little more than proof-of-concept/function testing. 1281 /* #### This is little more than proof-of-concept/function testing.
1280 It needs to be reimplemented via scanline reads for both memory 1282 It needs to be reimplemented via scanline reads for both memory
1281 compactness. */ 1283 compactness. */
1282 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32)); 1284 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
1293 /* This is to get around weirdness in the libtiff library where properly 1295 /* This is to get around weirdness in the libtiff library where properly
1294 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */ 1296 made TIFFs will come out upside down. libtiff bug or jhod-brainlock? */
1295 rp = raster + (i * width); 1297 rp = raster + (i * width);
1296 for (j = 0; j < (int) width; j++) 1298 for (j = 0; j < (int) width; j++)
1297 { 1299 {
1298 *ep++ = (unsigned char)TIFFGetR(*rp); 1300 *ep++ = (UChar_Binary)TIFFGetR(*rp);
1299 *ep++ = (unsigned char)TIFFGetG(*rp); 1301 *ep++ = (UChar_Binary)TIFFGetG(*rp);
1300 *ep++ = (unsigned char)TIFFGetB(*rp); 1302 *ep++ = (UChar_Binary)TIFFGetB(*rp);
1301 rp++; 1303 rp++;
1302 } 1304 }
1303 } 1305 }
1304 } 1306 }
1305 _TIFFfree (raster); 1307 _TIFFfree (raster);
1312 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), 1314 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
1313 init_image_instance_from_eimage, 1315 init_image_instance_from_eimage,
1314 (ii, width, height, 1, unwind.eimage, dest_mask, 1316 (ii, width, height, 1, unwind.eimage, dest_mask,
1315 instantiator, domain)); 1317 instantiator, domain));
1316 1318
1317 unbind_to (speccount, Qnil); 1319 unbind_to (speccount);
1318 } 1320 }
1319 1321
1320 #endif /* HAVE_TIFF */ 1322 #endif /* HAVE_TIFF */
1321 1323
1322 1324