├── README ├── OptimizedPNG.h └── OptimizedPNG.m /README: -------------------------------------------------------------------------------- 1 | Modified by Basuke. 2 | The MIT License 3 | 4 | Original sources are came from: 5 | http://sonson-code.googlecode.com/svn/trunk/iPhone2.0/OptimizedPNG/ 6 | 7 | -------------------------------------------------------------------------------- /OptimizedPNG.h: -------------------------------------------------------------------------------- 1 | // 2 | // OptimizedPNG 3 | // OptimizedPNG.h 4 | // 5 | // The MIT License 6 | // 7 | // Copyright (c) 2009 sonson, sonson@Picture&Software 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | //// 27 | // Original source code 28 | // Created by takiuchi on 08/12/07. 29 | // Copyright 2008 s21g LLC. All rights reserved. 30 | // MIT Lisence 31 | // 32 | 33 | // 34 | // optimizedPNG.h 35 | // Created by sonson on 09/01/25. 36 | // Copyright 2009 sonson. All rights reserved. 37 | // 38 | 39 | #import 40 | #import 41 | 42 | @interface UIImage (optimizedPNG) 43 | - (NSData*)optimizedData; 44 | @end 45 | 46 | @interface NSData (optimizedPNG) 47 | - (NSData*)optimizedData; 48 | @end -------------------------------------------------------------------------------- /OptimizedPNG.m: -------------------------------------------------------------------------------- 1 | // 2 | // OptimizedPNG 3 | // OptimizedPNG.m 4 | // 5 | // The MIT License 6 | // 7 | // Copyright (c) 2009 sonson, sonson@Picture&Software 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | //// 27 | // Original source code 28 | // Created by takiuchi on 08/12/07. 29 | // Copyright 2008 s21g LLC. All rights reserved. 30 | // MIT Lisence 31 | // 32 | 33 | // 34 | // optimizedPNG.m 35 | // Created by sonson on 09/01/25. 36 | // Copyright 2009 sonson. All rights reserved. 37 | // 38 | 39 | #import "OptimizedPNG.h" 40 | #import 41 | 42 | #pragma mark NSMutableData for Making Optimized PNG Image 43 | 44 | @interface NSMutableData (pngTool) 45 | - (void)appendUInt:(NSUInteger)value; 46 | @end 47 | 48 | @implementation NSMutableData (pngTool) 49 | - (void) appendUInt:(NSUInteger)value { 50 | value = htonl(value); 51 | [self appendBytes:&value length:sizeof(value)]; 52 | } 53 | @end 54 | 55 | unsigned int crc(unsigned char *name, unsigned char *buf, int len) { 56 | unsigned int crc = crc32(0, name, 4); 57 | return crc32(crc, buf, len); 58 | } 59 | 60 | #pragma mark PNG Chunk 61 | 62 | unsigned char PNGHeader[8] = {137, 80, 78, 71, 13, 10, 26, 10}; 63 | unsigned char PNGChunkHdr[4] = {0x49, 0x48, 0x44, 0x52}; 64 | unsigned char PNGChunkData[4] = {0x49, 0x44, 0x41, 0x54}; // IDAT 65 | unsigned char PNGChunkEnd[8] = {0x49, 0x45, 0x4e, 0x44, 0xAE, 0x42, 0x60, 0x82}; // IEND 66 | unsigned char PNGChunkCgBI[12] = {0x43, 0x67, 0x42, 0x49, 0x30, 0x00, 0x20, 0x06, 0x17, 0x9E, 0x80, 0x65}; // CgBI 67 | 68 | #pragma mark Make Optimized PNG 69 | 70 | NSData* makeOptimizedPNGDataFromUIImage( UIImage *originalImage ) { 71 | NSMutableData *data = [NSMutableData new]; 72 | [data appendBytes:PNGHeader length:8]; 73 | 74 | // CgBI 75 | [data appendUInt:4]; 76 | [data appendBytes:PNGChunkCgBI length:12]; 77 | 78 | // IHDR 79 | unsigned char hdr[13]; 80 | int width = originalImage.size.width, height = originalImage.size.height; 81 | *(unsigned int*)(hdr + 0) = htonl(width); 82 | *(unsigned int*)(hdr + 4) = htonl(height); 83 | *(unsigned char*)(hdr + 8) = 8; 84 | *(unsigned char*)(hdr + 9) = 6; 85 | *(unsigned char*)(hdr + 10) = 0; 86 | *(unsigned char*)(hdr + 11) = 0; 87 | *(unsigned char*)(hdr + 12) = 0; 88 | [data appendUInt:13]; 89 | [data appendBytes:PNGChunkHdr length:4]; 90 | [data appendBytes:hdr length:13]; 91 | [data appendUInt:crc(PNGChunkHdr, hdr, 13)]; 92 | 93 | // IDAT 94 | int size = width*height*4; 95 | unsigned char *buffer = malloc(size); 96 | CGContextRef context = CGBitmapContextCreate(buffer, width, height, 8, width*4, CGImageGetColorSpace(originalImage.CGImage), kCGImageAlphaPremultipliedLast); 97 | CGRect rect = CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height); 98 | CGContextDrawImage(context, rect, originalImage.CGImage); 99 | CGContextRelease(context); 100 | 101 | int size_line = 1 + width*4; 102 | int size_in = height*size_line; 103 | unsigned char *buffer_in = malloc(size_in); 104 | for(int y = 0; y < height; ++y){ 105 | unsigned char *src = &buffer[y*width*4]; 106 | unsigned char *dst = &buffer_in[y*size_line]; 107 | *dst++ = 1; 108 | unsigned char r = 0, g = 0, b = 0, a = 0; 109 | for(int x = 0; x < width; ++x){ 110 | dst[0] = src[2] - b; 111 | dst[1] = src[1] - g; 112 | dst[2] = src[0] - r; 113 | dst[3] = src[3] - a; 114 | r = src[0], g = src[1], b = src[2], a = src[3]; 115 | src += 4; 116 | dst += 4; 117 | } 118 | } 119 | free(buffer); 120 | 121 | unsigned char *buffer_out = malloc(size_in); 122 | z_stream stream; 123 | stream.zalloc = Z_NULL; 124 | stream.zfree = Z_NULL; 125 | stream.opaque = Z_NULL; 126 | stream.avail_in = size_in; 127 | stream.next_in = buffer_in; 128 | stream.next_out = buffer_out; 129 | stream.avail_out = size_in; 130 | deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -8, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); 131 | deflate(&stream, Z_FINISH); 132 | free(buffer_in); 133 | 134 | [data appendUInt:stream.total_out]; 135 | [data appendBytes:PNGChunkData length:4]; 136 | [data appendBytes:buffer_out length:stream.total_out]; 137 | [data appendUInt:crc(PNGChunkData, buffer_out, stream.total_out)]; 138 | free(buffer_out); 139 | deflateEnd(&stream); 140 | 141 | // IEND 142 | [data appendUInt:0]; 143 | [data appendBytes:PNGChunkEnd length:8]; 144 | 145 | return data; 146 | } 147 | 148 | #pragma mark UIImage (optimizedPNG) implementation 149 | 150 | @implementation UIImage (optimizedPNG) 151 | - (NSData*)optimizedData { 152 | return makeOptimizedPNGDataFromUIImage( self ); 153 | } 154 | @end 155 | 156 | #pragma mark NSData (optimizedPNG) implementation 157 | 158 | @implementation NSData (optimizedPNG) 159 | - (NSData*)optimizedData { 160 | // decode image 161 | UIImage* originalImage = [UIImage imageWithData:self]; 162 | if( originalImage == nil ) { 163 | NSLog( @"Can't decode NSData into image." ); 164 | return nil; 165 | } 166 | return makeOptimizedPNGDataFromUIImage( originalImage ); 167 | } 168 | @end --------------------------------------------------------------------------------