mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 20:40:47 +00:00
Method to get all images from an ICNS file.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@33062 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
73ae595130
commit
a2088a66a9
4 changed files with 149 additions and 84 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2011-05-18 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
|
* Source/NSBitmapImageRep+ICNS.h
|
||||||
|
* Source/NSBitmapImageRep+ICNS.m: New method to load all the
|
||||||
|
images from file. Plus a few additional changes.
|
||||||
|
* Source/NSBitmapImageRep.m (+imageRepsWithData:): Use new ICNS
|
||||||
|
method to get all images from file.
|
||||||
|
* Source/NSBitmapImageRep.m (+imageRepWithData:): Use
|
||||||
|
-initWithData: instead of +imageRepsWithData:.
|
||||||
|
|
||||||
2011-05-15 Fred Kiefer <FredKiefer@gmx.de>
|
2011-05-15 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
* Source/NSView.m (-removeFromSuperview): Use
|
* Source/NSView.m (-removeFromSuperview): Use
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
@interface NSBitmapImageRep (ICNS)
|
@interface NSBitmapImageRep (ICNS)
|
||||||
+ (BOOL) _bitmapIsICNS: (NSData *)imageData;
|
+ (BOOL) _bitmapIsICNS: (NSData *)imageData;
|
||||||
|
+ (NSArray*) _imageRepsWithICNSData: (NSData *)imageData;
|
||||||
- (id) _initBitmapFromICNS: (NSData *)imageData;
|
- (id) _initBitmapFromICNS: (NSData *)imageData;
|
||||||
// - (NSData *) _ICNSRepresentationWithProperties: (NSDictionary *) properties;
|
// - (NSData *) _ICNSRepresentationWithProperties: (NSDictionary *) properties;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -307,6 +307,11 @@ static int icns_init_image_for_type(icns_type_t iconType,
|
||||||
icns_icon_info_t info;
|
icns_icon_info_t info;
|
||||||
|
|
||||||
info = icns_get_image_info_for_type(iconType);
|
info = icns_get_image_info_for_type(iconType);
|
||||||
|
if (info.iconChannels == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return icns_init_image(info.iconWidth, info.iconHeight, info.iconChannels,
|
return icns_init_image(info.iconWidth, info.iconHeight, info.iconChannels,
|
||||||
info.iconDepth, imageOut);
|
info.iconDepth, imageOut);
|
||||||
}
|
}
|
||||||
|
@ -477,6 +482,66 @@ typedef struct pixel_t
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (id) _initBitmapFromICNSImage: (icns_image_t*)iconImage
|
||||||
|
{
|
||||||
|
unsigned int iconWidth = 0, iconHeight = 0;
|
||||||
|
unsigned int rgbBufferPos = 0;
|
||||||
|
unsigned int rgbBufferSize = 0;
|
||||||
|
unsigned char *rgbBuffer = NULL; /* image converted to rgb */
|
||||||
|
int i = 0, j = 0;
|
||||||
|
int imageChannels = 0;
|
||||||
|
int sPP = 4;
|
||||||
|
|
||||||
|
iconWidth = iconImage->imageWidth;
|
||||||
|
iconHeight = iconImage->imageHeight;
|
||||||
|
|
||||||
|
// allocate the buffer...
|
||||||
|
rgbBufferSize = iconHeight * (iconWidth * sizeof(unsigned char) * sPP);
|
||||||
|
rgbBuffer = NSZoneMalloc([self zone], rgbBufferSize);
|
||||||
|
if (rgbBuffer == NULL)
|
||||||
|
{
|
||||||
|
NSLog(@"Couldn't allocate memory for image data from ICNS.");
|
||||||
|
RELEASE(self);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
imageChannels = iconImage->imageChannels;
|
||||||
|
rgbBufferPos = 0;
|
||||||
|
for (i = 0; i < iconHeight; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < iconWidth; j++)
|
||||||
|
{
|
||||||
|
pixel_t *src_rgb_pixel;
|
||||||
|
|
||||||
|
src_rgb_pixel = (pixel_t *)&(iconImage->imageData[i*iconWidth*imageChannels+j*imageChannels]);
|
||||||
|
|
||||||
|
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->r;
|
||||||
|
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->g;
|
||||||
|
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->b;
|
||||||
|
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize self */
|
||||||
|
[self initWithBitmapDataPlanes: &rgbBuffer
|
||||||
|
pixelsWide: iconWidth
|
||||||
|
pixelsHigh: iconHeight
|
||||||
|
bitsPerSample: 8
|
||||||
|
samplesPerPixel: sPP
|
||||||
|
hasAlpha: YES
|
||||||
|
isPlanar: NO
|
||||||
|
colorSpaceName: NSCalibratedRGBColorSpace
|
||||||
|
// FIXME: Not sure whether this format is pre-multiplied
|
||||||
|
bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
|
||||||
|
bytesPerRow: iconWidth * sPP
|
||||||
|
bitsPerPixel: 8 * sPP];
|
||||||
|
|
||||||
|
_imageData = [[NSData alloc] initWithBytesNoCopy: rgbBuffer
|
||||||
|
length: rgbBufferSize];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
- (id) _initBitmapFromICNS: (NSData *)imageData
|
- (id) _initBitmapFromICNS: (NSData *)imageData
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
@ -486,17 +551,10 @@ typedef struct pixel_t
|
||||||
unsigned long dataOffset = 0;
|
unsigned long dataOffset = 0;
|
||||||
icns_byte_t *data = NULL;
|
icns_byte_t *data = NULL;
|
||||||
icns_type_t typeStr = ICNS_NULL_TYPE;
|
icns_type_t typeStr = ICNS_NULL_TYPE;
|
||||||
unsigned int iconWidth = 0, iconHeight = 0;
|
|
||||||
icns_image_t iconImage;
|
icns_image_t iconImage;
|
||||||
int sPP = 4;
|
|
||||||
unsigned char *rgbBuffer = NULL; /* image converted to rgb */
|
|
||||||
unsigned int rgbBufferPos = 0;
|
|
||||||
unsigned int rgbBufferSize = 0;
|
|
||||||
int i = 0, j = 0;
|
|
||||||
int imageChannels = 0;
|
|
||||||
|
|
||||||
error = icns_import_family_data(size, bytes, &iconFamily);
|
error = icns_import_family_data(size, bytes, &iconFamily);
|
||||||
if(error != ICNS_STATUS_OK)
|
if (error != ICNS_STATUS_OK)
|
||||||
{
|
{
|
||||||
NSLog(@"Error reading ICNS data.");
|
NSLog(@"Error reading ICNS data.");
|
||||||
RELEASE(self);
|
RELEASE(self);
|
||||||
|
@ -514,10 +572,8 @@ typedef struct pixel_t
|
||||||
|
|
||||||
memcpy(&element, (data + dataOffset), 8);
|
memcpy(&element, (data + dataOffset), 8);
|
||||||
|
|
||||||
//
|
|
||||||
// Temporarily limit to 48 until we can find a way to
|
// Temporarily limit to 48 until we can find a way to
|
||||||
// utilize the other representations in the icns file.
|
// utilize the other representations in the icns file.
|
||||||
//
|
|
||||||
if (icns_types_equal(element.elementType, ICNS_48x48_32BIT_DATA)
|
if (icns_types_equal(element.elementType, ICNS_48x48_32BIT_DATA)
|
||||||
|| (icns_types_equal(typeStr, ICNS_NULL_TYPE)
|
|| (icns_types_equal(typeStr, ICNS_NULL_TYPE)
|
||||||
&& (icns_types_equal(element.elementType, ICNS_32x32_32BIT_DATA)
|
&& (icns_types_equal(element.elementType, ICNS_32x32_32BIT_DATA)
|
||||||
|
@ -543,59 +599,72 @@ typedef struct pixel_t
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
iconWidth = iconImage.imageWidth;
|
self = [self _initBitmapFromICNSImage: &iconImage];
|
||||||
iconHeight = iconImage.imageHeight;
|
|
||||||
|
|
||||||
// allocate the buffer...
|
|
||||||
rgbBufferSize = iconHeight * (iconWidth * sizeof(unsigned char) * sPP);
|
|
||||||
rgbBuffer = NSZoneMalloc([self zone], rgbBufferSize);
|
|
||||||
if (rgbBuffer == NULL)
|
|
||||||
{
|
|
||||||
NSLog(@"Couldn't allocate memory for image data from ICNS.");
|
|
||||||
RELEASE(self);
|
|
||||||
icns_free_image(&iconImage);
|
|
||||||
free(iconFamily);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
imageChannels = iconImage.imageChannels;
|
|
||||||
rgbBufferPos = 0;
|
|
||||||
for (i = 0; i < iconHeight; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < iconWidth; j++)
|
|
||||||
{
|
|
||||||
pixel_t *src_rgb_pixel;
|
|
||||||
|
|
||||||
src_rgb_pixel = (pixel_t *)&(iconImage.imageData[i*iconWidth*imageChannels+j*imageChannels]);
|
|
||||||
|
|
||||||
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->r;
|
|
||||||
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->g;
|
|
||||||
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->b;
|
|
||||||
rgbBuffer[rgbBufferPos++] = src_rgb_pixel->a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
icns_free_image(&iconImage);
|
icns_free_image(&iconImage);
|
||||||
free(iconFamily);
|
free(iconFamily);
|
||||||
|
|
||||||
/* initialize self */
|
|
||||||
[self initWithBitmapDataPlanes: &rgbBuffer
|
|
||||||
pixelsWide: iconWidth
|
|
||||||
pixelsHigh: iconHeight
|
|
||||||
bitsPerSample: 8
|
|
||||||
samplesPerPixel: sPP
|
|
||||||
hasAlpha: YES
|
|
||||||
isPlanar: NO
|
|
||||||
colorSpaceName: NSCalibratedRGBColorSpace
|
|
||||||
// FIXME: Not sure whether this format is pre-multiplied
|
|
||||||
bitmapFormat: NSAlphaNonpremultipliedBitmapFormat
|
|
||||||
bytesPerRow: iconWidth * sPP
|
|
||||||
bitsPerPixel: 8 * sPP];
|
|
||||||
|
|
||||||
_imageData = [[NSData alloc] initWithBytesNoCopy: rgbBuffer
|
|
||||||
length: rgbBufferSize];
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSArray*) _imageRepsWithICNSData: (NSData *)imageData
|
||||||
|
{
|
||||||
|
NSMutableArray *array = [NSMutableArray array];
|
||||||
|
int error = 0;
|
||||||
|
int size = [imageData length];
|
||||||
|
icns_byte_t *bytes = (icns_byte_t *)[imageData bytes];
|
||||||
|
icns_family_t *iconFamily = NULL;
|
||||||
|
unsigned long dataOffset = 0;
|
||||||
|
icns_byte_t *data = NULL;
|
||||||
|
|
||||||
|
error = icns_import_family_data(size, bytes, &iconFamily);
|
||||||
|
if (error != ICNS_STATUS_OK)
|
||||||
|
{
|
||||||
|
NSLog(@"Error reading ICNS data.");
|
||||||
|
RELEASE(self);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip the header...
|
||||||
|
dataOffset = sizeof(icns_type_t) + sizeof(icns_size_t);
|
||||||
|
data = (icns_byte_t *)iconFamily;
|
||||||
|
|
||||||
|
// read each icon...
|
||||||
|
while (((dataOffset + 8) < iconFamily->resourceSize))
|
||||||
|
{
|
||||||
|
icns_element_t element;
|
||||||
|
icns_type_t typeStr = ICNS_NULL_TYPE;
|
||||||
|
icns_image_t iconImage;
|
||||||
|
|
||||||
|
memcpy(&element, (data + dataOffset), 8);
|
||||||
|
memcpy(&typeStr, &(element.elementType), 4);
|
||||||
|
|
||||||
|
// extract the image...
|
||||||
|
memset(&iconImage, 0, sizeof(icns_image_t));
|
||||||
|
error = icns_get_image32_with_mask_from_family(iconFamily,
|
||||||
|
typeStr,
|
||||||
|
&iconImage);
|
||||||
|
//NSLog(@"Read image %c %c %c %c result %d size %d", typeStr.c[0], typeStr.c[1], typeStr.c[2], typeStr.c[3], error, element.elementSize);
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
NSBitmapImageRep* imageRep;
|
||||||
|
|
||||||
|
imageRep = [[self alloc] _initBitmapFromICNSImage: &iconImage];
|
||||||
|
if (imageRep)
|
||||||
|
{
|
||||||
|
[array addObject: imageRep];
|
||||||
|
RELEASE(imageRep);
|
||||||
|
}
|
||||||
|
|
||||||
|
icns_free_image(&iconImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// next...
|
||||||
|
dataOffset += element.elementSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(iconFamily);
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -180,14 +180,7 @@
|
||||||
*/
|
*/
|
||||||
+ (id) imageRepWithData: (NSData *)imageData
|
+ (id) imageRepWithData: (NSData *)imageData
|
||||||
{
|
{
|
||||||
NSArray* array;
|
return [[self alloc] initWithData: imageData];
|
||||||
|
|
||||||
array = [self imageRepsWithData: imageData];
|
|
||||||
if ([array count])
|
|
||||||
{
|
|
||||||
return [array objectAtIndex: 0];
|
|
||||||
}
|
|
||||||
return nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**<p>Returns an array containing newly allocated NSBitmapImageRep
|
/**<p>Returns an array containing newly allocated NSBitmapImageRep
|
||||||
|
@ -211,7 +204,7 @@
|
||||||
NSBitmapImageRep *rep;
|
NSBitmapImageRep *rep;
|
||||||
NSArray *a;
|
NSArray *a;
|
||||||
|
|
||||||
rep=[[self alloc] _initBitmapFromPNG: imageData];
|
rep = [[self alloc] _initBitmapFromPNG: imageData];
|
||||||
if (!rep)
|
if (!rep)
|
||||||
return [NSArray array];
|
return [NSArray array];
|
||||||
a = [NSArray arrayWithObject: rep];
|
a = [NSArray arrayWithObject: rep];
|
||||||
|
@ -224,7 +217,7 @@
|
||||||
NSBitmapImageRep *rep;
|
NSBitmapImageRep *rep;
|
||||||
NSArray *a;
|
NSArray *a;
|
||||||
|
|
||||||
rep=[[self alloc] _initBitmapFromPNM: imageData
|
rep = [[self alloc] _initBitmapFromPNM: imageData
|
||||||
errorMessage: NULL];
|
errorMessage: NULL];
|
||||||
if (!rep)
|
if (!rep)
|
||||||
return [NSArray array];
|
return [NSArray array];
|
||||||
|
@ -238,7 +231,7 @@
|
||||||
NSBitmapImageRep *rep;
|
NSBitmapImageRep *rep;
|
||||||
NSArray *a;
|
NSArray *a;
|
||||||
|
|
||||||
rep=[[self alloc] _initBitmapFromJPEG: imageData
|
rep = [[self alloc] _initBitmapFromJPEG: imageData
|
||||||
errorMessage: NULL];
|
errorMessage: NULL];
|
||||||
if (!rep)
|
if (!rep)
|
||||||
return [NSArray array];
|
return [NSArray array];
|
||||||
|
@ -252,7 +245,7 @@
|
||||||
NSBitmapImageRep *rep;
|
NSBitmapImageRep *rep;
|
||||||
NSArray *a;
|
NSArray *a;
|
||||||
|
|
||||||
rep=[[self alloc] _initBitmapFromGIF: imageData
|
rep = [[self alloc] _initBitmapFromGIF: imageData
|
||||||
errorMessage: NULL];
|
errorMessage: NULL];
|
||||||
if (!rep)
|
if (!rep)
|
||||||
return [NSArray array];
|
return [NSArray array];
|
||||||
|
@ -263,15 +256,7 @@
|
||||||
|
|
||||||
if ([self _bitmapIsICNS: imageData])
|
if ([self _bitmapIsICNS: imageData])
|
||||||
{
|
{
|
||||||
NSBitmapImageRep *rep;
|
return [self _imageRepsWithICNSData: imageData];
|
||||||
NSArray *a;
|
|
||||||
|
|
||||||
rep=[[self alloc] _initBitmapFromICNS: imageData];
|
|
||||||
if (!rep)
|
|
||||||
return [NSArray array];
|
|
||||||
a = [NSArray arrayWithObject: rep];
|
|
||||||
DESTROY(rep);
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
|
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
|
||||||
|
@ -298,11 +283,11 @@
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads only the default (first) image from the TIFF image contained in
|
/** Loads only the default (first) image from the image contained in
|
||||||
data. */
|
data. */
|
||||||
- (id) initWithData: (NSData *)imageData
|
- (id) initWithData: (NSData *)imageData
|
||||||
{
|
{
|
||||||
TIFF *image;
|
TIFF *image;
|
||||||
|
|
||||||
if (imageData == nil)
|
if (imageData == nil)
|
||||||
{
|
{
|
||||||
|
@ -328,7 +313,6 @@
|
||||||
if ([isa _bitmapIsICNS: imageData])
|
if ([isa _bitmapIsICNS: imageData])
|
||||||
return [self _initBitmapFromICNS: imageData];
|
return [self _initBitmapFromICNS: imageData];
|
||||||
|
|
||||||
|
|
||||||
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
|
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
|
||||||
if (image == NULL)
|
if (image == NULL)
|
||||||
{
|
{
|
||||||
|
@ -337,8 +321,9 @@
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _initFromTIFFImage:image number: -1];
|
[self _initFromTIFFImage: image number: -1];
|
||||||
NSTiffClose(image);
|
NSTiffClose(image);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue