mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +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
6c54fd6be5
commit
2608a790ed
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>
|
||||
|
||||
* Source/NSView.m (-removeFromSuperview): Use
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
@interface NSBitmapImageRep (ICNS)
|
||||
+ (BOOL) _bitmapIsICNS: (NSData *)imageData;
|
||||
+ (NSArray*) _imageRepsWithICNSData: (NSData *)imageData;
|
||||
- (id) _initBitmapFromICNS: (NSData *)imageData;
|
||||
// - (NSData *) _ICNSRepresentationWithProperties: (NSDictionary *) properties;
|
||||
@end
|
||||
|
|
|
@ -307,6 +307,11 @@ static int icns_init_image_for_type(icns_type_t iconType,
|
|||
icns_icon_info_t info;
|
||||
|
||||
info = icns_get_image_info_for_type(iconType);
|
||||
if (info.iconChannels == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return icns_init_image(info.iconWidth, info.iconHeight, info.iconChannels,
|
||||
info.iconDepth, imageOut);
|
||||
}
|
||||
|
@ -477,6 +482,66 @@ typedef struct pixel_t
|
|||
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
|
||||
{
|
||||
int error = 0;
|
||||
|
@ -486,17 +551,10 @@ typedef struct pixel_t
|
|||
unsigned long dataOffset = 0;
|
||||
icns_byte_t *data = NULL;
|
||||
icns_type_t typeStr = ICNS_NULL_TYPE;
|
||||
unsigned int iconWidth = 0, iconHeight = 0;
|
||||
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);
|
||||
if(error != ICNS_STATUS_OK)
|
||||
if (error != ICNS_STATUS_OK)
|
||||
{
|
||||
NSLog(@"Error reading ICNS data.");
|
||||
RELEASE(self);
|
||||
|
@ -514,10 +572,8 @@ typedef struct pixel_t
|
|||
|
||||
memcpy(&element, (data + dataOffset), 8);
|
||||
|
||||
//
|
||||
// Temporarily limit to 48 until we can find a way to
|
||||
// utilize the other representations in the icns file.
|
||||
//
|
||||
if (icns_types_equal(element.elementType, ICNS_48x48_32BIT_DATA)
|
||||
|| (icns_types_equal(typeStr, ICNS_NULL_TYPE)
|
||||
&& (icns_types_equal(element.elementType, ICNS_32x32_32BIT_DATA)
|
||||
|
@ -543,59 +599,72 @@ typedef struct pixel_t
|
|||
return nil;
|
||||
}
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
self = [self _initBitmapFromICNSImage: &iconImage];
|
||||
icns_free_image(&iconImage);
|
||||
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;
|
||||
}
|
||||
|
||||
+ (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
|
||||
|
|
|
@ -180,14 +180,7 @@
|
|||
*/
|
||||
+ (id) imageRepWithData: (NSData *)imageData
|
||||
{
|
||||
NSArray* array;
|
||||
|
||||
array = [self imageRepsWithData: imageData];
|
||||
if ([array count])
|
||||
{
|
||||
return [array objectAtIndex: 0];
|
||||
}
|
||||
return nil;
|
||||
return [[self alloc] initWithData: imageData];
|
||||
}
|
||||
|
||||
/**<p>Returns an array containing newly allocated NSBitmapImageRep
|
||||
|
@ -211,7 +204,7 @@
|
|||
NSBitmapImageRep *rep;
|
||||
NSArray *a;
|
||||
|
||||
rep=[[self alloc] _initBitmapFromPNG: imageData];
|
||||
rep = [[self alloc] _initBitmapFromPNG: imageData];
|
||||
if (!rep)
|
||||
return [NSArray array];
|
||||
a = [NSArray arrayWithObject: rep];
|
||||
|
@ -224,7 +217,7 @@
|
|||
NSBitmapImageRep *rep;
|
||||
NSArray *a;
|
||||
|
||||
rep=[[self alloc] _initBitmapFromPNM: imageData
|
||||
rep = [[self alloc] _initBitmapFromPNM: imageData
|
||||
errorMessage: NULL];
|
||||
if (!rep)
|
||||
return [NSArray array];
|
||||
|
@ -238,7 +231,7 @@
|
|||
NSBitmapImageRep *rep;
|
||||
NSArray *a;
|
||||
|
||||
rep=[[self alloc] _initBitmapFromJPEG: imageData
|
||||
rep = [[self alloc] _initBitmapFromJPEG: imageData
|
||||
errorMessage: NULL];
|
||||
if (!rep)
|
||||
return [NSArray array];
|
||||
|
@ -252,7 +245,7 @@
|
|||
NSBitmapImageRep *rep;
|
||||
NSArray *a;
|
||||
|
||||
rep=[[self alloc] _initBitmapFromGIF: imageData
|
||||
rep = [[self alloc] _initBitmapFromGIF: imageData
|
||||
errorMessage: NULL];
|
||||
if (!rep)
|
||||
return [NSArray array];
|
||||
|
@ -263,15 +256,7 @@
|
|||
|
||||
if ([self _bitmapIsICNS: imageData])
|
||||
{
|
||||
NSBitmapImageRep *rep;
|
||||
NSArray *a;
|
||||
|
||||
rep=[[self alloc] _initBitmapFromICNS: imageData];
|
||||
if (!rep)
|
||||
return [NSArray array];
|
||||
a = [NSArray arrayWithObject: rep];
|
||||
DESTROY(rep);
|
||||
return a;
|
||||
return [self _imageRepsWithICNSData: imageData];
|
||||
}
|
||||
|
||||
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
|
||||
|
@ -298,11 +283,11 @@
|
|||
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. */
|
||||
- (id) initWithData: (NSData *)imageData
|
||||
{
|
||||
TIFF *image;
|
||||
TIFF *image;
|
||||
|
||||
if (imageData == nil)
|
||||
{
|
||||
|
@ -328,7 +313,6 @@
|
|||
if ([isa _bitmapIsICNS: imageData])
|
||||
return [self _initBitmapFromICNS: imageData];
|
||||
|
||||
|
||||
image = NSTiffOpenDataRead((char *)[imageData bytes], [imageData length]);
|
||||
if (image == NULL)
|
||||
{
|
||||
|
@ -337,8 +321,9 @@
|
|||
return nil;
|
||||
}
|
||||
|
||||
[self _initFromTIFFImage:image number: -1];
|
||||
[self _initFromTIFFImage: image number: -1];
|
||||
NSTiffClose(image);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue