- /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
- fd = openp (search_path, file, Qnil, &file_found, Qnil);
-
- if (fd == -1)
- file_found = Qnil;
- else
- {
- file_found = ENCODE_FILE (file_found);
- close (fd);
- }
-
- UNGCPRO;
- return file_found;
-}
-
-
-/* Read FILE into memory. Value is a pointer to a buffer allocated
- with xmalloc holding FILE's contents. Value is null if an error
- occurred. *SIZE is set to the size of the file. */
-
-static unsigned char *
-slurp_file (file, size)
- char *file;
- int *size;
-{
- FILE *fp = NULL;
- unsigned char *buf = NULL;
- struct stat st;
-
- if (stat (file, &st) == 0
- && (fp = fopen (file, "rb")) != NULL
- && (buf = (unsigned char *) xmalloc (st.st_size),
- fread (buf, 1, st.st_size, fp) == st.st_size))
- {
- *size = st.st_size;
- fclose (fp);
- }
- else
- {
- if (fp)
- fclose (fp);
- if (buf)
- {
- xfree (buf);
- buf = NULL;
- }
- }
-
- return buf;
-}
-
-
-\f
-#ifdef MAC_OS
-
-/***********************************************************************
- MAC Image Load Functions
- ***********************************************************************/
-
-#if USE_MAC_IMAGE_IO
-static int
-image_load_image_io (f, img, type)
- struct frame *f;
- struct image *img;
- CFStringRef type;
-{
- CFDictionaryRef options, src_props = NULL, props = NULL;
- CFStringRef keys[2];
- CFTypeRef values[2];
- Lisp_Object specified_file, specified_data;
- CGImageSourceRef source = NULL;
- size_t count;
- CGImageRef image = NULL;
- int loop_count = -1;
- double delay_time = -1.0;
- int width, height;
- XImagePtr ximg = NULL;
- CGContextRef context;
- CGRect rectangle;
- int has_alpha_p, gif_p;
-
- gif_p = UTTypeEqual (type, kUTTypeGIF);
-
- keys[0] = kCGImageSourceTypeIdentifierHint;
- values[0] = (CFTypeRef) type;
- keys[1] = kCGImageSourceShouldCache;
- values[1] = (CFTypeRef) kCFBooleanFalse;
- options = CFDictionaryCreate (NULL, (const void **) keys,
- (const void **) values,
- sizeof (keys) / sizeof (keys[0]),
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- if (options == NULL)
- {
- image_error ("Error creating options for image `%s'", img->spec, Qnil);
- return 0;
- }
-
- /* Open the file. */
- specified_file = image_spec_value (img->spec, QCfile, NULL);
- specified_data = image_spec_value (img->spec, QCdata, NULL);
-
- if (NILP (specified_data))
- {
- Lisp_Object file;
- CFStringRef path;
- CFURLRef url;
-
- file = x_find_image_file (specified_file);
- if (!STRINGP (file))
- {
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- return 0;
- }
- path = cfstring_create_with_utf8_cstring (SDATA (file));
- if (path)
- {
- url = CFURLCreateWithFileSystemPath (NULL, path,
- kCFURLPOSIXPathStyle, 0);
- CFRelease (path);
- if (url)
- {
- source = CGImageSourceCreateWithURL (url, NULL);
- CFRelease (url);
- }
- }
- }
- else
- {
- CFDataRef data = CFDataCreate (NULL, SDATA (specified_data),
- SBYTES (specified_data));
-
- if (data)
- {
- source = CGImageSourceCreateWithData (data, options);
- CFRelease (data);
- }
- }
- CFRelease (options);
-
- if (source)
- {
- CFStringRef real_type = CGImageSourceGetType (source);
-
- if (real_type && UTTypeEqual (type, real_type))
- src_props = CGImageSourceCopyProperties (source, NULL);
- if (src_props)
- {
- EMACS_INT ino = 0;
-
- count = CGImageSourceGetCount (source);
- if (gif_p)
- {
- Lisp_Object image = image_spec_value (img->spec, QCindex, NULL);
-
- if (INTEGERP (image))
- ino = XFASTINT (image);
- }
- if (ino >= 0 && ino < count)
- {
- props = CGImageSourceCopyPropertiesAtIndex (source, ino, NULL);
- if (props)
- image = CGImageSourceCreateImageAtIndex (source, ino, NULL);
- }
- }
- CFRelease (source);
- }
-
- if (image == NULL)
- {
- if (src_props)
- CFRelease (src_props);
- if (props)
- CFRelease (props);
- image_error ("Error reading image `%s'", img->spec, Qnil);
- return 0;
- }
- else
- {
- CFBooleanRef boolean;
-
- if (CFDictionaryGetValueIfPresent (props, kCGImagePropertyHasAlpha,
- (const void **) &boolean))
- has_alpha_p = CFBooleanGetValue (boolean);
- if (gif_p)
- {
- CFDictionaryRef dict;
- CFNumberRef number;
-
- dict = CFDictionaryGetValue (src_props,
- kCGImagePropertyGIFDictionary);
- if (dict
- && CFDictionaryGetValueIfPresent (dict,
- kCGImagePropertyGIFLoopCount,
- (const void **) &number))
- CFNumberGetValue (number, kCFNumberIntType, &loop_count);
-
- dict = CFDictionaryGetValue (props, kCGImagePropertyGIFDictionary);
- if (dict
- && CFDictionaryGetValueIfPresent (dict,
- kCGImagePropertyGIFDelayTime,
- (const void **) &number))
- CFNumberGetValue (number, kCFNumberDoubleType, &delay_time);
- }
- CFRelease (src_props);
- CFRelease (props);
- }
-
- width = img->width = CGImageGetWidth (image);
- height = img->height = CGImageGetHeight (image);
-
- if (!check_image_size (f, width, height))
- {
- CGImageRelease (image);
- image_error ("Invalid image size", Qnil, Qnil);
- return 0;
- }
-
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
- {
- CGImageRelease (image);
- image_error ("Out of memory (%s)", img->spec, Qnil);
- return 0;
- }
- rectangle = CGRectMake (0, 0, width, height);
-
- context = CGBitmapContextCreate (ximg->data, ximg->width, ximg->height, 8,
- ximg->bytes_per_line,
- mac_cg_color_space_rgb,
- kCGImageAlphaNoneSkipFirst
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
- | kCGBitmapByteOrder32Host
-#endif
- );
- if (has_alpha_p)
- {
- Lisp_Object specified_bg;
- XColor color;
-
- specified_bg = image_spec_value (img->spec, QCbackground, NULL);
- if (!STRINGP (specified_bg)
- || !mac_defined_color (f, SDATA (specified_bg), &color, 0))
- {
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
- color.red = RED16_FROM_ULONG (color.pixel);
- color.green = GREEN16_FROM_ULONG (color.pixel);
- color.blue = BLUE16_FROM_ULONG (color.pixel);
- }
- CGContextSetRGBFillColor (context, color.red / 65535.0,
- color.green / 65535.0,
- color.blue / 65535.0, 1.0);
- CGContextFillRect (context, rectangle);
- }
- CGContextDrawImage (context, rectangle, image);
- CGContextRelease (context);
- CGImageRelease (image);
-
- /* Save GIF image extension data for `image-extension-data'.
- Format is (count IMAGES
- 0xff "NETSCAPE2.0" 0x00 DATA_SUB_BLOCK_FOR_LOOP_COUNT
- 0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK). */
- if (gif_p)
- {
- img->data.lisp_val = Qnil;
- if (delay_time >= 0)
- {
- Lisp_Object gce = make_uninit_string (4);
- int centisec = delay_time * 100.0 + 0.5;
-
- /* Fill the delay time field. */
- SSET (gce, 1, centisec & 0xff);
- SSET (gce, 2, (centisec >> 8) & 0xff);
- /* We don't know about other fields. */
- SSET (gce, 0, 0);
- SSET (gce, 3, 0);
- img->data.lisp_val = Fcons (make_number (0xf9),
- Fcons (gce,
- img->data.lisp_val));
- }
- if (loop_count >= 0)
- {
- Lisp_Object data_sub_block = make_uninit_string (3);
-
- SSET (data_sub_block, 0, 0x01);
- SSET (data_sub_block, 1, loop_count & 0xff);
- SSET (data_sub_block, 2, (loop_count >> 8) & 0xff);
- img->data.lisp_val = Fcons (make_number (0),
- Fcons (data_sub_block,
- img->data.lisp_val));
- img->data.lisp_val = Fcons (make_number (0xff),
- Fcons (build_string ("NETSCAPE2.0"),
- img->data.lisp_val));
- }
- if (count > 1)
- img->data.lisp_val = Fcons (Qcount,
- Fcons (make_number (count),
- img->data.lisp_val));
- }
-
- /* Maybe fill in the background field while we have ximg handy. */
- if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
- IMAGE_BACKGROUND (img, f, ximg);
-
- /* Put the image into the pixmap. */
- x_put_x_image (f, ximg, img->pixmap, width, height);
- x_destroy_x_image (ximg);
- return 1;
-}
-#else /* !USE_MAC_IMAGE_IO */
-static int image_load_quicktime P_ ((struct frame *, struct image *img,
- OSType));
-#ifdef MAC_OSX
-static int image_load_quartz2d P_ ((struct frame *, struct image *img, int));
-#endif
-
-static OSErr
-find_image_fsspec (specified_file, file, fss)
- Lisp_Object specified_file, *file;
- FSSpec *fss;
-{
- OSErr err;
- AEDesc desc;
-
- *file = x_find_image_file (specified_file);
- if (!STRINGP (*file))
- return fnfErr; /* file or directory not found;
- incomplete pathname */
- /* Try to open the image file. */
- err = AECoercePtr (TYPE_FILE_NAME, SDATA (*file),
- SBYTES (*file), typeFSS, &desc);
- if (err == noErr)
- {
-#if TARGET_API_MAC_CARBON
- err = AEGetDescData (&desc, fss, sizeof (FSSpec));
-#else
- *fss = *(FSSpec *)(*(desc.dataHandle));
-#endif
- AEDisposeDesc (&desc);
- }
- return err;
-}
-
-static int
-image_load_qt_1 (f, img, type, fss, dh)
- struct frame *f;
- struct image *img;
- OSType type;
- const FSSpec *fss;
- Handle dh;
-{
- ComponentResult err;
- GraphicsImportComponent gi;
- Rect rect;
- int width, height;
- ImageDescriptionHandle desc_handle;
- short draw_all_pixels;
- Lisp_Object specified_bg;
- XColor color;
- XImagePtr ximg;
- RGBColor bg_color;
-
- err = OpenADefaultComponent (GraphicsImporterComponentType, type, &gi);
- if (err != noErr)
- {
- image_error ("Cannot get importer component for `%s'", img->spec, Qnil);
- return 0;
- }
- if (dh == NULL)
- {
- /* read from file system spec */
- err = GraphicsImportSetDataFile (gi, fss);
- if (err != noErr)
- {
- image_error ("Cannot set fsspec to graphics importer for '%s'",
- img->spec, Qnil);
- goto error;
- }
- }
- else
- {
- /* read from data handle */
- err = GraphicsImportSetDataHandle (gi, dh);
- if (err != noErr)
- {
- image_error ("Cannot set data handle to graphics importer for `%s'",
- img->spec, Qnil);
- goto error;
- }
- }
- err = GraphicsImportGetImageDescription (gi, &desc_handle);
- if (err != noErr || desc_handle == NULL)
- {
- image_error ("Error reading `%s'", img->spec, Qnil);
- goto error;
- }
- width = img->width = (*desc_handle)->width;
- height = img->height = (*desc_handle)->height;
- DisposeHandle ((Handle)desc_handle);
-
- if (!check_image_size (f, width, height))
- {
- image_error ("Invalid image size", Qnil, Qnil);
- goto error;
- }
-
- err = GraphicsImportDoesDrawAllPixels (gi, &draw_all_pixels);
-#if 0
- /* Don't check the error code here. It may have an undocumented
- value -32766. */
- if (err != noErr)
- {
- image_error ("Error reading `%s'", img->spec, Qnil);
- goto error;
- }
-#endif
- if (draw_all_pixels != graphicsImporterDrawsAllPixels)
- {
- specified_bg = image_spec_value (img->spec, QCbackground, NULL);
- if (!STRINGP (specified_bg) ||
- !mac_defined_color (f, SDATA (specified_bg), &color, 0))
- {
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
- color.red = RED16_FROM_ULONG (color.pixel);
- color.green = GREEN16_FROM_ULONG (color.pixel);
- color.blue = BLUE16_FROM_ULONG (color.pixel);
- }
- }
-
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
- goto error;
- if (draw_all_pixels != graphicsImporterDrawsAllPixels)
- {
- CGrafPtr old_port;
- GDHandle old_gdh;
-
- GetGWorld (&old_port, &old_gdh);
- SetGWorld (ximg, NULL);
- bg_color.red = color.red;
- bg_color.green = color.green;
- bg_color.blue = color.blue;
- RGBBackColor (&bg_color);
-#if TARGET_API_MAC_CARBON
- GetPortBounds (ximg, &rect);
- EraseRect (&rect);
-#else
- EraseRect (&(ximg->portRect));
-#endif
- SetGWorld (old_port, old_gdh);
- }
- GraphicsImportSetGWorld (gi, ximg, NULL);
- GraphicsImportDraw (gi);
- CloseComponent (gi);
-
- /* Maybe fill in the background field while we have ximg handy. */
- if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
- IMAGE_BACKGROUND (img, f, ximg);
-
- /* Put the image into the pixmap. */
- x_put_x_image (f, ximg, img->pixmap, width, height);
- x_destroy_x_image (ximg);
- return 1;
-
- error:
- CloseComponent (gi);
- return 0;
-}
-
-
-/* Load an image using the QuickTime Graphics Importer.
- Note: The alpha channel does not work for PNG images. */
-static int
-image_load_quicktime (f, img, type)
- struct frame *f;
- struct image *img;
- OSType type;
-{
- Lisp_Object specified_file;
- Lisp_Object specified_data;
- OSErr err;
-
- specified_file = image_spec_value (img->spec, QCfile, NULL);
- specified_data = image_spec_value (img->spec, QCdata, NULL);
-
- if (NILP (specified_data))
- {
- /* Read from a file */
- Lisp_Object file;
- FSSpec fss;
-
- err = find_image_fsspec (specified_file, &file, &fss);
- if (err != noErr)
- {
- if (err == fnfErr)
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- else
- image_error ("Cannot open `%s'", file, Qnil);
- return 0;
- }
- return image_load_qt_1 (f, img, type, &fss, NULL);
- }
- else
- {
- /* Memory source! */
- int success_p;
- Handle dh;
-
- err = PtrToHand (SDATA (specified_data), &dh, SBYTES (specified_data));
- if (err != noErr)
- {
- image_error ("Cannot allocate data handle for `%s'",
- img->spec, Qnil);
- return 0;
- }
- success_p = image_load_qt_1 (f, img, type, NULL, dh);
- DisposeHandle (dh);
- return success_p;
- }
-}
-
-
-#ifdef MAC_OSX
-static int
-image_load_quartz2d (f, img, png_p)
- struct frame *f;
- struct image *img;
- int png_p;
-{
- Lisp_Object file, specified_file;
- Lisp_Object specified_data, specified_bg;
- struct gcpro gcpro1;
- CGDataProviderRef source;
- CGImageRef image;
- int width, height;
- XColor color;
- XImagePtr ximg = NULL;
- CGContextRef context;
- CGRect rectangle;
-
- /* Open the file. */
- specified_file = image_spec_value (img->spec, QCfile, NULL);
- specified_data = image_spec_value (img->spec, QCdata, NULL);
-
- file = Qnil;
- GCPRO1 (file);
-
- if (NILP (specified_data))
- {
- CFStringRef path;
- CFURLRef url;
-
- file = x_find_image_file (specified_file);
- if (!STRINGP (file))
- {
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
- return 0;
- }
- path = cfstring_create_with_utf8_cstring (SDATA (file));
- url = CFURLCreateWithFileSystemPath (NULL, path,
- kCFURLPOSIXPathStyle, 0);
- CFRelease (path);
- source = CGDataProviderCreateWithURL (url);
- CFRelease (url);
- }
- else
- source = CGDataProviderCreateWithData (NULL, SDATA (specified_data),
- SBYTES (specified_data), NULL);