// // TKPXMResource.m // ThemeKit // // Created by David Watson on Mon Dec 08 2003. // Copyright (c) 2003 Carpe Stellarem. All rights reserved. // // Updated by Colin Cornaby on Mon Dec 08 2003. // Copyright (c) 2003 Carpe Stellarem. All rights reserved. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #import "TKPXMResource.h" #include //#include SInt32 GetPixMapRowBytes(Rect inRect,SInt16 inPixelDepth); SInt32 GetMaskSize(Rect inRect); SInt32 GetImageSize(Rect inRect,SInt16 inDepth); UInt8 *newPtr=0; @implementation TKPXMResource -(void)dealloc { //if(newPtr) // free(newPtr); [super dealloc]; } - (void)awakeFromFetch { [self parseHeader]; } SInt32 GetPixMapRowBytes(Rect inRect,SInt16 inPixelDepth) { SInt16 width = inRect.right - inRect.left; return (((width * inPixelDepth + 15) / 16) * 2); } SInt32 GetPixMapSize(Rect inRect, const SInt16 inPixelDepth) { SInt16 height = inRect.bottom - inRect.top; return GetPixMapRowBytes(inRect,inPixelDepth) * height; } SInt32 GetMaskSize(Rect inRect) { return GetPixMapSize(inRect, 1); } SInt32 GetImageSize(Rect inRect,SInt16 inDepth) { return GetPixMapSize(inRect,inDepth); } - (id)init { self = [super init]; //[super initWithEntity:(NSEntityDescription*)entity insertIntoManagedObjectContext:(NSManagedObjectContext*)context]; pxmHeader.mMaskCount = 0; pxmHeader.mCTSeedValue = pxmHeader.mImageCount = 0; pxmHeader.mPixelDepth = 1; pxmHeader.mBounds.left = pxmHeader.mBounds.top = 0; pxmHeader.mBounds.right = pxmHeader.mBounds.bottom = 32; return self; } +(id)pxmWithData:(NSData *)inData { return [[[TKPXMResource alloc] initWithData:inData] autorelease]; } -(id)initWithData:(NSData *)inData { [self setResourceData:inData]; [self parseHeader]; return self; } -(void)setResourceData:(NSData *)data { [super setResourceData:data]; [self parseHeader]; return; } -(int)numImages { return (int)pxmHeader.mImageCount; } -(NSString *)humanReadableType { return @"Widget Image"; } -(void)parseHeader { UInt8 *thePtr; SInt16 maskMode; // First, we set the pointer to the beginning of the data object thePtr=(UInt8 *)[[NSMutableData dataWithData:[self resourceData]] bytes]; // Get the image count with a +22 offset // this needs to be obtained before the mask // pxmHeader.mImageCount=NSSwapBigShortToHost(*((SInt16*)(thePtr+22))); pxmHeader.mImageCount=swapShort(*((SInt16*)(thePtr+22)),[self endianness], kNativeEndian); // Get the mask mode which is offset +2 from the beginning // the mask mode will either be 4,5,12 or 13 // 4 & 12 mean that there will be an individual mask for each image while // 5 & 13 mean that there is a single mask for all images in the pxm# maskMode=swapShort(*((SInt16*)(thePtr+2)),[self endianness], kNativeEndian); if((maskMode==4)||(maskMode==12)) { pxmHeader.mMaskCount=pxmHeader.mImageCount; } else { pxmHeader.mMaskCount=1; } // Get the bounds of the rect. We use a standard rect rather than an NSRect // to allow us to use the simpler code base pxmHeader.mBounds.bottom=swapShort(*((SInt16*)(thePtr+8)),[self endianness], kNativeEndian); pxmHeader.mBounds.right=swapShort(*((SInt16*)(thePtr+10)),[self endianness], kNativeEndian); // Get the pixel depth for the images pxmHeader.mPixelDepth=swapShort(*((SInt16*)(thePtr+12)),[self endianness], kNativeEndian); // Get the CLUT id number if the PXM uses one pxmHeader.mCTSeedValue=swapShort(*((SInt16*)(thePtr+20)),[self endianness], kNativeEndian); } -(NSData *)resourceDataForPlatform:(int)platform { if(resolveEndianness([self endianness]==resolveEndianness(platform))) return [self resourceData]; NSMutableData *dataToReturn = [NSMutableData dataWithData:[self resourceData]]; //swap out the entire header, short by short int i; for(i=0;i<24;i=i+2){ short bytes = swapShort(*((SInt16*)([dataToReturn bytes]+i)),[self endianness], platform); [dataToReturn replaceBytesInRange:NSMakeRange(i, sizeof(bytes)) withBytes:&bytes]; } return dataToReturn; } -(void)setImage:(NSImage *)inImage atIndex:(int)index type:(int)inType { UInt8 *thePtr=(UInt8 *)[[NSMutableData dataWithData:[self resourceData]] bytes],*newPtr,*tempPtr; SInt32 theMaskSize,theImageSize,maskIndex; NSBitmapImageRep *theRep; int counter,counter1; // Set two temporary variables that store the image and mask sizes for offsets theMaskSize = GetMaskSize(pxmHeader.mBounds); theImageSize = GetImageSize(pxmHeader.mBounds,pxmHeader.mPixelDepth); // Fast forward past the header thePtr+=24; // Switch based on the image type switch(inType) { case CSPXMMask: if(pxmHeader.mMaskCount==1) maskIndex=0; else maskIndex=index; thePtr+=maskIndex*theMaskSize; theRep=[[NSBitmapImageRep alloc] initWithData:[inImage TIFFRepresentation]]; newPtr=[theRep bitmapData]; // Create a temporary holding spot to store the mask tempPtr=malloc(theMaskSize); // Zero out tempPtr for(counter=0;counter> 24; unsigned short g = (color & 0x00FF0000) >> 16; unsigned short b = (color & 0x0000FF00) >> 8; unsigned short a = (color & 0x000000FF) >> 0; r = (int)((((double)r) / (double)0xFF) * (double)0x1F); g = (int)((((double)g) / (double)0xFF) * (double)0x1F); b = (int)((((double)b) / (double)0xFF) * (double)0x1F); a = (a == 0) ? 0 : 1; unsigned short lower2 = (a << 15) | (r << 10) | (g << 5) | (b << 0); tempPtr[tctr++] = *((unsigned char *)&lower2); tempPtr[tctr++] = *((unsigned char *)&lower2) + 1; } } else { for(counter=0;counter