Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: karelia/ICOFamily
base: d80493b739
...
head fork: karelia/ICOFamily
compare: 951e0fa66f
Checking mergeability… Don't worry, you can still create the pull request.
  • 7 commits
  • 15 files changed
  • 0 commit comments
  • 2 contributors
Commits on Oct 01, 2011
@alexzielenski alexzielenski Merge pull request #1 from karelia/master
Changes to allow ICOFamily to run under 10.5
e00b871
Commits on Nov 22, 2011
@matheweis matheweis Writing BMP based ICO files now works.
Functional in simple tests, but needs more testing for edge cases; it
makes heavy assumptions about the internal format of the
NSBitmapImageReps and has no error checking.
3f4c9b7
@alexzielenski alexzielenski Merge pull request #3 from matheweis/master
ICOFamily is no longer broken - writing ICO files works. - Thanks metheweis
ce6bfd5
Commits on Dec 12, 2011
@alexzielenski alexzielenski Made the saved ICO files actually look how they are supposed to when …
…using NSImage and fixed XCode project so it builds with newer changes.
a435c95
@alexzielenski alexzielenski Changed license c0bc477
@alexzielenski alexzielenski readme typo c31e8af
@alexzielenski alexzielenski Change copyright year 951e0fa
View
BIN  .DS_Store
Binary file not shown
View
24 ICOFamily.h
@@ -1,10 +1,24 @@
+// Copyright (c) 2011 Alex Zielenski
+// All Rights Reserved
//
-// ICOFamily.h
-// ICOFamily
-//
-// Created by Alex Zielenski on 8/2/10.
-// Copyright 2010 Alex Zielenski. All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import <Cocoa/Cocoa.h>
/** @typedef
View
418 ICOFamily.m
@@ -1,14 +1,68 @@
+// Copyright (c) 2011 Alex Zielenski
+// All Rights Reserved
//
-// ICOFamily.m
-// ICOFamily
-//
-// Created by Alex Zielenski on 8/2/10.
-// Copyright 2010 Alex Zielenski. All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#import <Accelerate/Accelerate.h>
+#import "NSMutableData+EndianValues.h"
#import "ICOFamily.h"
- // We use NSBitmapImageRep so we can get some extra specifications required by the ICO file type
+// According to http://msdn.microsoft.com/en-us/library/dd183376.aspx
+typedef struct BitMapInfoHeader
+{
+ uint32_t biSize; // bitmap header size - should be 40
+ int32_t biWidth; // bitmap pixel width
+ int32_t biHeight; // bitmap pixel height; double for ico due to and map
+ uint16_t biPlanes; // should be 1, 0 may work also
+ uint16_t biBitCount; // Bits per pixel
+ uint32_t biCompression; // 0 = uncompressed RGB/RGBA, 1 = run-length-encoded 8bpp, 2 = rle 4bpp
+ uint32_t biSizeImage; // bitmap data size
+ int32_t biXPelsPerMeter; // usually 2835
+ int32_t biYPelsPerMeter; // usually 2835
+ uint32_t biClrUsed; // 0 = 32 bit
+ uint32_t biClrImportant; // 0
+} __attribute__ ((__packed__)) BitMapInfoHeader;
+
+// According to http://msdn.microsoft.com/en-us/library/ms997538.aspx
+typedef struct IconDirEntry
+{
+ uint8_t bWidth; // Width, in pixels, of the image
+ uint8_t bHeight; // Height, in pixels, of the image
+ uint8_t bColorCount; // Number of colors in image (0 if >=8bpp)
+ uint8_t bReserved; // Reserved
+ uint16_t wPlanes; // Color Planes
+ uint16_t wBitCount; // Bits per pixel
+ uint32_t dwBytesInRes; // how many bytes in this resource?
+ uint32_t dwImageOffset; // Where in the file is this image?
+} __attribute__ ((__packed__)) IconDirEntry;
+
+// According to http://msdn.microsoft.com/en-us/library/ms997538.aspx
+typedef struct IconDir
+{
+ uint16_t idReserved; // Reserved (must be 0)
+ uint16_t idType; // Resource type (1 for icons)
+ uint16_t idCount; // How many images?
+ IconDirEntry idEntries[1]; // // The entries for each image
+} __attribute__ ((__packed__)) IconDir;
+
@interface ICOFamily (Private)
- (BOOL)verifyImageOfSize:(NSSize)size forElement:(kICOFamilyElement)element;
@@ -22,9 +76,6 @@ @implementation ICOFamily
- init {
if ((self = [super init])) {
self.elements=[[NSMutableDictionary alloc] init];
-
- //NSImage *im = [NSImage imageNamed:@"NSApplicationIcon"]; // That was for testing
- //[self setElements:kICOFamilyAllElements fromImage:im]; // For Testing
}
return self;
}
@@ -43,7 +94,6 @@ @implementation ICOFamily
}
- initWithData:(NSData*)data {
if ((self = [self init])) {
- // Use NSImage to read :P
[self setData:data forElement:kICOFamilyAllElements];
}
return self;
@@ -92,8 +142,7 @@ - (void)setBitmapImageRep:(NSBitmapImageRep*)rep forCustomSize:(NSSize)size {
if (size.width<=0||size.height>256||size.height<=0||size.width>256)
return; // Maximum dimensions
- if ([rep respondsToSelector:@selector(bitmapImageRepByConvertingToColorSpace:renderingIntent:)]) // 10.6+ runtime only
- {
+ if ([rep respondsToSelector:@selector(bitmapImageRepByConvertingToColorSpace:renderingIntent:)]) { // 10.6+ runtime only
rep = [rep bitmapImageRepByConvertingToColorSpace:[NSColorSpace genericRGBColorSpace]
renderingIntent:NSColorRenderingIntentPerceptual];
}
@@ -102,7 +151,7 @@ - (void)setBitmapImageRep:(NSBitmapImageRep*)rep forCustomSize:(NSSize)size {
- (void)setData:(NSData*)data forCustomSize:(NSSize)size {
if (!data)
return;
-
+
NSBitmapImageRep *nr = [NSBitmapImageRep imageRepWithData:data];
[self setBitmapImageRep:nr forCustomSize:size];
}
@@ -114,101 +163,46 @@ - (NSImage*)imageForCustomSize:(NSSize)size {
return [[[NSImage alloc] initWithData:[self dataForCustomSize:size]] autorelease];
}
- (NSBitmapImageRep*)bitmapImageRepForCustomSize:(NSSize)size {
- return [self bitmapImageRepForCustomSize:size];
+ return [elements objectForKey:NSStringFromSize(size)];
}
- (void)setElements:(kICOFamilyElement)element fromImage:(NSImage*)im {
if (!im)
return;
- NSImage *t = nil;
+
if ((element & kICOFamily256Element) == kICOFamily256Element || (element & kICOFamilyAllElements)==kICOFamilyAllElements) {
- t = [[NSImage alloc] initWithSize:NSMakeSize(256, 256)];
- [t lockFocus];
- [im drawInRect:NSMakeRect(0, 0, 256, 256)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0];
- [t unlockFocus];
- [self setImage:t
+ [im setSize:NSMakeSize(256, 256)];
+ [self setImage:im
forElement:kICOFamily256Element];
- [t release];
}
if ((element & kICOFamily128Element) == kICOFamily128Element || (element & kICOFamilyAllElements)==kICOFamilyAllElements) {
- t = [[NSImage alloc] initWithSize:NSMakeSize(128, 128)];
-
- [t lockFocus];
- [im drawInRect:NSMakeRect(0, 0, t.size.width, t.size.height)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0];
- [t unlockFocus];
- [self setImage:t
+ [im setSize:NSMakeSize(128, 128)];
+ [self setImage:im
forElement:kICOFamily128Element];
- [t release];
-
}
if ((element & kICOFamily64Element) == kICOFamily64Element || (element & kICOFamilyAllElements)==kICOFamilyAllElements) {
- t = [[NSImage alloc] initWithSize:NSMakeSize(64, 64)];
-
- [t lockFocus];
- [im drawInRect:NSMakeRect(0, 0, t.size.width, t.size.height)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0];
- [t unlockFocus];
- [self setImage:t
+ [im setSize:NSMakeSize(64, 64)];
+ [self setImage:im
forElement:kICOFamily64Element];
- [t release];
}
if ((element & kICOFamily48Element) == kICOFamily48Element || (element & kICOFamilyAllElements)==kICOFamilyAllElements) {
- t = [[NSImage alloc] initWithSize:NSMakeSize(48, 48)];
-
- [t lockFocus];
- [im drawInRect:NSMakeRect(0, 0, t.size.width, t.size.height)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0];
- [t unlockFocus];
- [self setImage:t
+ [im setSize:NSMakeSize(48, 48)];
+ [self setImage:im
forElement:kICOFamily48Element];
- [t release];
}
if ((element & kICOFamily32Element) == kICOFamily32Element || (element & kICOFamilyAllElements)==kICOFamilyAllElements) {
- t = [[NSImage alloc] initWithSize:NSMakeSize(32, 32)];
-
- [t lockFocus];
- [im drawInRect:NSMakeRect(0, 0, t.size.width, t.size.height)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0];
- [t unlockFocus];
- [self setImage:t
+ [im setSize:NSMakeSize(32, 32)];
+ [self setImage:im
forElement:kICOFamily32Element];
- [t release];
}
if ((element & kICOFamily24Element) == kICOFamily24Element || (element & kICOFamilyAllElements)==kICOFamilyAllElements) {
- t = [[NSImage alloc] initWithSize:NSMakeSize(24, 24)];
-
- [t lockFocus];
- [im drawInRect:NSMakeRect(0, 0, t.size.width, t.size.height)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0];
- [t unlockFocus];
- [self setImage:t
+ [im setSize:NSMakeSize(24, 24)];
+ [self setImage:im
forElement:kICOFamily24Element];
- [t release];
}
if ((element & kICOFamily16Element) == kICOFamily16Element || (element & kICOFamilyAllElements)==kICOFamilyAllElements) {
- t = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)];
- [t lockFocus];
- [im drawInRect:NSMakeRect(0, 0, t.size.width, t.size.height)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0];
- [t unlockFocus];
- [self setImage:t
+ [im setSize:NSMakeSize(16, 16)];
+ [self setImage:im
forElement:kICOFamily16Element];
- [t release];
}
}
- (NSImage*)imageWithAllReps {
@@ -227,9 +221,30 @@ - (void)setImage:(NSImage*)image forElement:(kICOFamilyElement)element {
return;
if ((element & kICOFamilyAllElements)==kICOFamilyAllElements) {
[self setElements:element fromImage:image];
+ return;
}
- [self setData:image.TIFFRepresentation
- forElement:element];
+ NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+ pixelsWide:image.size.width
+ pixelsHigh:image.size.height
+ bitsPerSample:8
+ samplesPerPixel:4
+ hasAlpha:YES
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bitmapFormat:NSAlphaFirstBitmapFormat
+ bytesPerRow:4 * image.size.width
+ bitsPerPixel:32];
+ NSGraphicsContext *ctx = [NSGraphicsContext graphicsContextWithBitmapImageRep:rep];
+ [NSGraphicsContext saveGraphicsState];
+ [NSGraphicsContext setCurrentContext:ctx];
+ [image drawAtPoint:NSZeroPoint
+ fromRect:NSZeroRect
+ operation:NSCompositeCopy
+ fraction:1.0];
+ [NSGraphicsContext restoreGraphicsState];
+
+ [self setBitmapImageRep:rep forElement:element];
+ [rep release];
}
- (void)setBitmapImageRep:(NSBitmapImageRep*)rep forElement:(kICOFamilyElement)element {
if (!rep)
@@ -243,14 +258,14 @@ - (void)setBitmapImageRep:(NSBitmapImageRep*)rep forElement:(kICOFamilyElement)e
}
if ([self verifyImageOfSize:NSMakeSize(rep.pixelsWide, rep.pixelsHigh)
forElement:element])
- {
- if ([rep respondsToSelector:@selector(bitmapImageRepByConvertingToColorSpace:renderingIntent:)]) // 10.6+ runtime only
{
+ if ([rep respondsToSelector:@selector(bitmapImageRepByConvertingToColorSpace:renderingIntent:)]) // 10.6+ runtime only
+ {
rep = [rep bitmapImageRepByConvertingToColorSpace:[NSColorSpace genericRGBColorSpace]
renderingIntent:NSColorRenderingIntentPerceptual];
- }
+ }
[elements setObject:rep forKey:[NSNumber numberWithInteger:element]];
- }
+ }
}
- (void)setData:(NSData*)data forElement:(kICOFamilyElement)element {
if (!data)
@@ -303,136 +318,133 @@ - (BOOL)verifyImageOfSize:(NSSize)size forElement:(kICOFamilyElement)element {
return (size.width == desiredSize.width && size.height == desiredSize.height);
}
-struct bmpfile_magic {
- unsigned char magic[2];
-};
-
-struct bmpfile_header {
- uint32_t filesz;
- uint16_t creator1;
- uint16_t creator2;
- uint32_t bmp_offset;
-};
-
#pragma mark -
#pragma mark Handling Data
-- (NSData*)data {
- // Write the BitmapInfoHeader to the data
+- (NSData*)data {
NSMutableData *data = [NSMutableData data];
- short zero = 0;
- short type = 1; // 1 for ICO and 2 for CUR cursor file
- short count = elements.count;
- // Write the header to the data
- [data appendBytes:&zero length:sizeof(short)];
- [data appendBytes:&type length:sizeof(short)];
- [data appendBytes:&count length:sizeof(short)];
-
-
- // Write Image Headers
+ IconDir iconDir;
+
+ iconDir.idReserved = 0;
+ iconDir.idType = 1;
+ iconDir.idCount = elements.count;
+
+ // Write ico header (icon directory)
+ [data appendLEUInt16:iconDir.idReserved];
+ [data appendLEUInt16:iconDir.idType];
+ [data appendLEUInt16:iconDir.idCount];
+
+ // Prepare image headers & image data
NSMutableData *headers = [[NSMutableData alloc] init];
NSMutableData *images = [[NSMutableData alloc] init];
- NSSortDescriptor *high = [[[NSSortDescriptor alloc] initWithKey:@"pixelsHigh" ascending:NO] autorelease];
- NSSortDescriptor *pixelsWide = [[[NSSortDescriptor alloc] initWithKey:@"pixelsWide" ascending:NO] autorelease];
- // Sort it so it is pretty
- NSArray *vals = [elements.allValues sortedArrayUsingDescriptors:[NSArray arrayWithObjects:
- high, pixelsWide, nil]];
+ // Sort the elements
+ NSSortDescriptor *sortHigh = [[[NSSortDescriptor alloc] initWithKey:@"pixelsHigh" ascending:NO] autorelease];
+ NSSortDescriptor *sortWide = [[[NSSortDescriptor alloc] initWithKey:@"pixelsWide" ascending:NO] autorelease];
+ NSArray *vals = [elements.allValues sortedArrayUsingDescriptors:[NSArray arrayWithObjects: sortHigh, sortWide, nil]];
+ // Work through each icon
for (NSBitmapImageRep *currentRep in vals) {
- NSData *fullBitmapData = [currentRep representationUsingType:NSBMPFileType
-
- properties:nil];
-
- if (!fullBitmapData)
- {
- NSLog(@"Could not convert size %d to BMP", currentRep.pixelsWide);
- continue; // no point continuing if it couldn't convert. How to express error?
- }
-
- [fullBitmapData writeToFile:[[NSString stringWithFormat:@"~/Desktop/converted_%d.bmp", currentRep.pixelsWide] stringByExpandingTildeInPath]
- atomically:NO];
- // Needs to be exclude the opening BITMAPFILEHEADER structure
- size_t bitmapFileHeaderSize = sizeof(struct bmpfile_magic) + sizeof(struct bmpfile_header);
- NSData *bitmapData = [fullBitmapData subdataWithRange:NSMakeRange(bitmapFileHeaderSize, [fullBitmapData length] - bitmapFileHeaderSize)];
-
- // Image header
-
- int iwidth = currentRep.pixelsWide;
- if (iwidth==256)
- iwidth=0;
- int iheight=currentRep.pixelsHigh;
- if (iheight==256)
- iheight=0;
- const char palette = 0;
- const char reserved = 0;
- short planes = currentRep.numberOfPlanes;
- short bpp = currentRep.bitsPerPixel; // bits per pixel
- int size = bitmapData.length;
- [headers appendBytes:&iwidth length:sizeof(const char)]; // 0 - 255 and 0 = 256
- [headers appendBytes:&iheight length:sizeof(const char)]; // 0 - 255 and 0 = 256
- [headers appendBytes:&palette length:sizeof(const char)];
- [headers appendBytes:&reserved length:sizeof(const char)];
- [headers appendBytes:&planes length:sizeof(short)];
- [headers appendBytes:&bpp length:sizeof(short)];
- [headers appendBytes:&size length:sizeof(int)];
+ BitMapInfoHeader bitmapHeader;
+ IconDirEntry entryHeader;
+
+ uint32_t bmpSize = currentRep.pixelsHigh * currentRep.bytesPerRow;
+ uint32_t andSize = ((((currentRep.pixelsWide) + 31) >> 5) << 2);
+
+ vImage_Buffer bmpBuf;
+ vImage_Buffer tmpBuf;
+ vImage_Buffer andBuf;
+
+ // Initialize the image buffers
+ bmpBuf.height = currentRep.pixelsHigh;
+ bmpBuf.width = currentRep.pixelsWide;
+ bmpBuf.rowBytes = currentRep.bytesPerRow;
+ bmpBuf.data = malloc(bmpSize);
+
+ tmpBuf.height = currentRep.pixelsHigh;
+ tmpBuf.width = currentRep.pixelsWide;
+ tmpBuf.rowBytes = currentRep.bytesPerRow;
+ tmpBuf.data = malloc(bmpSize);
+
+ andBuf.height = currentRep.pixelsHigh;
+ andBuf.width = currentRep.pixelsWide;
+ andBuf.rowBytes = currentRep.bytesPerRow;
+ andBuf.data = malloc(andSize);
- // Calculate the header offset
- int eachheader = 16; // The size of each image header in bytes (including the offset)
- int offset=eachheader*elements.count+images.length+data.length; // Gets the soon-to-be size of the file header and all of the image headers combined so an offset can be calculated for the image. Adding images.length adds the current offset for the image before the image gets added. Because we dont want offset+lengths. Data.lenght would be the root header's size in bytes. (6)
+ memcpy(bmpBuf.data, currentRep.bitmapData, bmpSize);
+ memset(andBuf.data, 0, andSize);
- [headers appendBytes:&offset length:sizeof(int)];
-
- // Add the raw image data the the images data
- [images appendBytes:bitmapData.bytes length:bitmapData.length];
+ // Initialize the ICO bitmap header
+ bitmapHeader.biSize = 40; // 40 byte header
+ bitmapHeader.biWidth = currentRep.pixelsWide;
+ bitmapHeader.biHeight = currentRep.pixelsHigh * 2; // double height due to and map
+ bitmapHeader.biPlanes = 1;
+ bitmapHeader.biBitCount = currentRep.bitsPerPixel;
+ bitmapHeader.biCompression = 0;
+ bitmapHeader.biSizeImage = bmpSize + andSize;
+ bitmapHeader.biXPelsPerMeter = 0;//2835;
+ bitmapHeader.biYPelsPerMeter = 0;//2835;
+ bitmapHeader.biClrUsed = 0;
+ bitmapHeader.biClrImportant = 0;
+
+ // Initialize the ICO directory entry
+ entryHeader.bWidth = (currentRep.pixelsWide == 256 ? 0 : currentRep.pixelsWide);
+ entryHeader.bHeight = (currentRep.pixelsHigh == 256 ? 0 : currentRep.pixelsHigh);
+ entryHeader.bColorCount = 0;
+ entryHeader.bReserved = 0;
+ entryHeader.wPlanes = currentRep.numberOfPlanes; // must be 1
+ entryHeader.wBitCount = currentRep.bitsPerPixel; // must be 32
+ entryHeader.dwBytesInRes = bitmapHeader.biSizeImage + 40;
+ entryHeader.dwImageOffset = 16 * elements.count+images.length+data.length;
+
+ // "Write" the ICO header data
+ [headers appendLEUInt8:entryHeader.bWidth];
+ [headers appendLEUInt8:entryHeader.bHeight];
+ [headers appendLEUInt8:entryHeader.bColorCount];
+ [headers appendLEUInt8:entryHeader.bReserved];
+ [headers appendLEUInt16:entryHeader.wPlanes];
+ [headers appendLEUInt16:entryHeader.wBitCount];
+ [headers appendLEUInt32:entryHeader.dwBytesInRes];
+ [headers appendLEUInt32:entryHeader.dwImageOffset];
+
+ // "Write" the bitmap header data
+ [images appendLEUInt32:bitmapHeader.biSize];
+ [images appendLESInt32:bitmapHeader.biWidth];
+ [images appendLESInt32:bitmapHeader.biHeight];
+ [images appendLEUInt16:bitmapHeader.biPlanes];
+ [images appendLEUInt16:bitmapHeader.biBitCount];
+ [images appendLEUInt32:bitmapHeader.biCompression];
+ [images appendLEUInt32:bitmapHeader.biSizeImage];
+ [images appendLESInt32:bitmapHeader.biXPelsPerMeter];
+ [images appendLESInt32:bitmapHeader.biYPelsPerMeter];
+ [images appendLEUInt32:bitmapHeader.biClrUsed];
+ [images appendLEUInt32:bitmapHeader.biClrImportant];
+
+ // Fix the bitmap image data to be compatible
+ const uint8_t permuteMap[4] = {3,2,1,0};
+ vImagePermuteChannels_ARGB8888 (&bmpBuf,&tmpBuf,permuteMap,kvImageDoNotTile);
+ vImageVerticalReflect_ARGB8888 (&tmpBuf,&bmpBuf,kvImageDoNotTile);
+
+ // "Write" the bitmap image/mask data
+ [images appendBytes:bmpBuf.data length:bmpSize];
+ [images appendBytes:andBuf.data length:andSize];
+
+ free(bmpBuf.data);
+ free(tmpBuf.data);
+ free(andBuf.data);
}
+
+ // Copy images & headers into ico data
[data appendBytes:headers.bytes length:headers.length];
[data appendBytes:images.bytes length:images.length];
+
[headers release];
[images release];
- return data;
+
+ return data;
}
+
- (void)readFromData:(NSData*)data { // Not yet. Might need help with this one. For now just use NSImage ;)
- NSData *header = [data subdataWithRange:NSMakeRange(0, 6)];
-
- short count = 0;
- [header getBytes:&count range:NSMakeRange(sizeof(short)*2, sizeof(short))];
- short type = 0;
- [header getBytes:&type range:NSMakeRange(sizeof(short), sizeof(short))];
- short zero = -1;
- [header getBytes:&zero range:NSMakeRange(0, sizeof(short))];
-
- if (zero != 0 || type != 1 || count < 1) {
- return; // FAIL
- }
- NSData *rest = [data subdataWithRange:NSMakeRange(6, data.length-6)];
- for (int x = 1;x<=count;x++) {
- // Each eacher should be 16?
- // Image header
-
- NSData *currentHeader = [rest subdataWithRange:NSMakeRange(16*x, 16)];
-
- const char *width = NULL;
- const char *height = NULL;
- const char *palette = NULL;
- const char *reserved = NULL;
- short planes = 0;
- short bpp = 0;
- int size = 0;
- int offset=0;
-
- [currentHeader getBytes:&width range:NSMakeRange(0, 1)];
- [currentHeader getBytes:&height range:NSMakeRange(1, 1)];
- [currentHeader getBytes:&palette range:NSMakeRange(2, 1)];
- [currentHeader getBytes:&reserved range:NSMakeRange(3, 1)];
- [currentHeader getBytes:&planes range:NSMakeRange(4, 2)];
- [currentHeader getBytes:&bpp range:NSMakeRange(6, 2)];
- [currentHeader getBytes:&size range:NSMakeRange(8, 4)];
- [currentHeader getBytes:&offset range:NSMakeRange(12, 4)];
-
- // bpp, planes, size, and offset are pretty much the only things that could possibly matter to use
-
- NSLog(@"%hi", offset);
- }
+ return;
}
#pragma mark -
View
0  ICOFamily.xcodeproj/Alex.pbxuser 100644 → 100755
File mode changed
View
0  ICOFamily.xcodeproj/Alex.perspectivev3 100644 → 100755
File mode changed
View
20 ICOFamily.xcodeproj/project.pbxproj 100644 → 100755
@@ -12,8 +12,9 @@
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ FA2C356B14969871000C9928 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA2C356A14969871000C9928 /* Accelerate.framework */; };
+ FA2C356E14969885000C9928 /* NSMutableData+EndianValues.m in Sources */ = {isa = PBXBuildFile; fileRef = FA2C356D14969885000C9928 /* NSMutableData+EndianValues.m */; };
FAB24F1B120760BB00003D13 /* ICOFamily.m in Sources */ = {isa = PBXBuildFile; fileRef = FAB24F1A120760BB00003D13 /* ICOFamily.m */; };
- FAB253B41207B88000003D13 /* Iconolatrous.icns in Resources */ = {isa = PBXBuildFile; fileRef = FAB253B31207B88000003D13 /* Iconolatrous.icns */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -29,9 +30,12 @@
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* ICOFamily-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ICOFamily-Info.plist"; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* ICOFamily.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ICOFamily.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ FA2C356814969859000C9928 /* vecLib.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = vecLib.framework; path = System/Library/Frameworks/vecLib.framework; sourceTree = SDKROOT; };
+ FA2C356A14969871000C9928 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
+ FA2C356C14969885000C9928 /* NSMutableData+EndianValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableData+EndianValues.h"; sourceTree = "<group>"; };
+ FA2C356D14969885000C9928 /* NSMutableData+EndianValues.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableData+EndianValues.m"; sourceTree = "<group>"; };
FAB24F19120760BB00003D13 /* ICOFamily.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ICOFamily.h; sourceTree = "<group>"; };
FAB24F1A120760BB00003D13 /* ICOFamily.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ICOFamily.m; sourceTree = "<group>"; };
- FAB253B31207B88000003D13 /* Iconolatrous.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Iconolatrous.icns; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -39,6 +43,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ FA2C356B14969871000C9928 /* Accelerate.framework in Frameworks */,
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -49,6 +54,8 @@
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
+ FA2C356C14969885000C9928 /* NSMutableData+EndianValues.h */,
+ FA2C356D14969885000C9928 /* NSMutableData+EndianValues.m */,
256AC3D80F4B6AC300CF3369 /* ICOFamilyAppDelegate.h */,
256AC3D90F4B6AC300CF3369 /* ICOFamilyAppDelegate.m */,
FAB24F19120760BB00003D13 /* ICOFamily.h */,
@@ -86,6 +93,8 @@
29B97314FDCFA39411CA2CEA /* ICOFamily */ = {
isa = PBXGroup;
children = (
+ FA2C356A14969871000C9928 /* Accelerate.framework */,
+ FA2C356814969859000C9928 /* vecLib.framework */,
080E96DDFE201D6D7F000001 /* Classes */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
@@ -107,7 +116,6 @@
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
- FAB253B31207B88000003D13 /* Iconolatrous.icns */,
8D1107310486CEB800E47090 /* ICOFamily-Info.plist */,
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
1DDD58140DA1D0A300B32029 /* MainMenu.xib */,
@@ -152,7 +160,11 @@
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ICOFamily" */;
compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
hasScannedForEncodings = 1;
+ knownRegions = (
+ en,
+ );
mainGroup = 29B97314FDCFA39411CA2CEA /* ICOFamily */;
projectDirPath = "";
projectRoot = "";
@@ -169,7 +181,6 @@
files = (
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */,
- FAB253B41207B88000003D13 /* Iconolatrous.icns in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -183,6 +194,7 @@
8D11072D0486CEB800E47090 /* main.m in Sources */,
256AC3DA0F4B6AC300CF3369 /* ICOFamilyAppDelegate.m in Sources */,
FAB24F1B120760BB00003D13 /* ICOFamily.m in Sources */,
+ FA2C356E14969885000C9928 /* NSMutableData+EndianValues.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
7 ICOFamily.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:ICOFamily.xcodeproj">
+ </FileRef>
+</Workspace>
View
BIN  ICOFamily.xcodeproj/project.xcworkspace/xcuserdata/Alex.xcuserdatad/UserInterfaceState.xcuserstate
Binary file not shown
View
84 ICOFamily.xcodeproj/xcuserdata/Alex.xcuserdatad/xcschemes/ICOFamily.xcscheme
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "8D1107260486CEB800E47090"
+ BuildableName = "ICOFamily.app"
+ BlueprintName = "ICOFamily"
+ ReferencedContainer = "container:ICOFamily.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ buildConfiguration = "Debug">
+ <Testables>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "8D1107260486CEB800E47090"
+ BuildableName = "ICOFamily.app"
+ BlueprintName = "ICOFamily"
+ ReferencedContainer = "container:ICOFamily.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ </TestAction>
+ <LaunchAction
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.GDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ buildConfiguration = "Debug"
+ debugDocumentVersioning = "YES"
+ allowLocationSimulation = "YES">
+ <BuildableProductRunnable>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "8D1107260486CEB800E47090"
+ BuildableName = "ICOFamily.app"
+ BlueprintName = "ICOFamily"
+ ReferencedContainer = "container:ICOFamily.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ buildConfiguration = "Release"
+ debugDocumentVersioning = "YES">
+ <BuildableProductRunnable>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "8D1107260486CEB800E47090"
+ BuildableName = "ICOFamily.app"
+ BlueprintName = "ICOFamily"
+ ReferencedContainer = "container:ICOFamily.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
View
22 ICOFamily.xcodeproj/xcuserdata/Alex.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>SchemeUserState</key>
+ <dict>
+ <key>ICOFamily.xcscheme</key>
+ <dict>
+ <key>orderHint</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <key>SuppressBuildableAutocreation</key>
+ <dict>
+ <key>8D1107260486CEB800E47090</key>
+ <dict>
+ <key>primary</key>
+ <true/>
+ </dict>
+ </dict>
+</dict>
+</plist>
View
25 ICOFamilyAppDelegate.h
@@ -1,11 +1,24 @@
+// Copyright (c) 2011 Alex Zielenski
+// All Rights Reserved
//
-// ICOFamilyAppDelegate.h
-// ICOFamily
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
//
-// Created by Alex Zielenski on 8/2/10.
-// Copyright 2010 Alex Zielenski. All rights reserved.
-//
-
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import <Cocoa/Cocoa.h>
@interface ICOFamilyAppDelegate : NSObject <NSApplicationDelegate> {
View
37 ICOFamilyAppDelegate.m 100644 → 100755
@@ -1,10 +1,24 @@
+// Copyright (c) 2011 Alex Zielenski
+// All Rights Reserved
//
-// ICOFamilyAppDelegate.m
-// ICOFamily
-//
-// Created by Alex Zielenski on 8/2/10.
-// Copyright 2010 Alex Zielenski. All rights reserved.
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "ICOFamilyAppDelegate.h"
#import "ICOFamily.h"
@@ -16,17 +30,8 @@ @implementation ICOFamilyAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
- ICOFamily *fam = [ICOFamily familyWithImage:[NSImage imageNamed:@"Iconolatrous"]];
-
- NSImage *ni = [[NSImage alloc] initWithSize:NSMakeSize(57, 57)];
- [ni lockFocus];
- [[NSImage imageNamed:@"NSApplicationIcon"] drawInRect:NSMakeRect(0, 0, 57, 57)
- fromRect:NSZeroRect
- operation:NSCompositeSourceOver
- fraction:1.0];
- [ni unlockFocus];
- [fam setImage:ni forCustomSize:ni.size];
- [fam.data writeToFile:@"/Users/Alex/Desktop/lol2.ico" atomically:NO];
+ ICOFamily *fam = [ICOFamily familyWithImage:[NSImage imageNamed:@"NSApplicationIcon"]];
+ [fam.data writeToFile:[@"~/Desktop/ICOFamilyTestIcon.ico" stringByExpandingTildeInPath] atomically:NO];
}
@end
View
29 NSMutableData+EndianValues.h
@@ -0,0 +1,29 @@
+//
+// NSMutableData+EndianValues.h
+// iConvertIcons
+//
+// Created by Mathew Eis on 22/11/2011.
+// Copyright (c) 2011 Mathew Eis. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSMutableData (EndianValues)
+
+- (void) appendBESInt8: (SInt8)value;
+- (void) appendBESInt16: (SInt16)value;
+- (void) appendBESInt32: (SInt32)value;
+
+- (void) appendBEUInt8: (UInt8)value;
+- (void) appendBEUInt16: (UInt16)value;
+- (void) appendBEUInt32: (UInt32)value;
+
+- (void) appendLESInt8: (SInt8)value;
+- (void) appendLESInt16: (SInt16)value;
+- (void) appendLESInt32: (SInt32)value;
+
+- (void) appendLEUInt8: (UInt8)value;
+- (void) appendLEUInt16: (UInt16)value;
+- (void) appendLEUInt32: (UInt32)value;
+
+@end
View
85 NSMutableData+EndianValues.m
@@ -0,0 +1,85 @@
+//
+// NSMutableData+EndianValues.m
+// iConvertIcons
+//
+// Created by Mathew Eis on 22/11/2011.
+// Copyright (c) 2011 Mathew Eis. All rights reserved.
+//
+
+#import "NSMutableData+EndianValues.h"
+
+@implementation NSMutableData (EndianValues)
+
+- (void) appendBESInt8: (SInt8)value
+{
+ [self appendBytes:&(value) length:1];
+}
+- (void) appendBESInt16: (SInt16)value
+{
+ UInt16 uvalue = *((UInt16 *)(&value));
+ [self appendBEUInt16:uvalue];
+}
+- (void) appendBESInt32: (SInt32)value
+{
+ UInt32 uvalue = *((UInt32 *)(&value));
+ [self appendBEUInt32:uvalue];
+}
+
+- (void) appendBEUInt8: (UInt8)value
+{
+ [self appendBytes:&(value) length:1];
+}
+- (void) appendBEUInt16: (UInt16)value
+{
+ UInt8 b[2];
+ b[0] = value >> 8;
+ b[1] = value;
+ [self appendBytes:&b[0] length:2];
+}
+- (void) appendBEUInt32: (UInt32)value
+{
+ UInt8 b[4];
+ b[0] = value >> 24;
+ b[1] = value >> 16;
+ b[2] = value >> 8;
+ b[3] = value;
+ [self appendBytes:&b[0] length:4];
+}
+
+- (void) appendLESInt8: (SInt8)value
+{
+ [self appendBytes:&(value) length:1];
+}
+- (void) appendLESInt16: (SInt16)value
+{
+ UInt16 uvalue = *((UInt16 *)(&value));
+ [self appendLEUInt16:uvalue];
+}
+- (void) appendLESInt32: (SInt32)value
+{
+ UInt32 uvalue = *((UInt32 *)(&value));
+ [self appendLEUInt32:uvalue];
+}
+
+- (void) appendLEUInt8: (UInt8)value
+{
+ [self appendBytes:&(value) length:1];
+}
+- (void) appendLEUInt16: (UInt16)value
+{
+ UInt8 b[2];
+ b[0] = value;
+ b[1] = value >> 8;
+ [self appendBytes:&b[0] length:2];
+}
+- (void) appendLEUInt32: (UInt32)value
+{
+ UInt8 b[4];
+ b[0] = value;
+ b[1] = value >> 8;
+ b[2] = value >> 16;
+ b[3] = value >> 24;
+ [self appendBytes:&b[0] length:4];
+}
+
+@end
View
13 README.textile
@@ -23,9 +23,16 @@ You should use ICOFamily just like any other class.
h2. License
-Uses the "Creative Commons 3.0 Attributed Unported License":http://creativecommons.org/licenses/by/3.0/
-
I prefer that I am credited in the About box of your app if you used some of my source code with the following format:
Uses "ICOFamily":http://github.com/alexzielenski/ICOFamily by "Alex Zielenski":http://alexzielenski.com/
-
+
+All code in this repository is licensed under the <b>MIT</b> license (with the exception of the NSMutableData category; courtesy of Mathew Eis). Here is some legal jargon:
+
+Copyright (c) 2011 Alex Zielenski All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

No commit comments for this range

Something went wrong with that request. Please try again.