Luky/Gui/LLColorFilter.m

00001 //
00002 //  LLColorFilter.m
00003 //  MacTrek
00004 //
00005 //  Created by Aqua on 15/08/2006.
00006 //  Copyright 2006 Luky Soft. All rights reserved.
00007 //
00008 
00009 #import "LLColorFilter.h"
00010 
00011 
00012 @implementation LLColorFilter
00013 
00014 
00015 - (int)pixelForColor:(NSColor *)srcColor {
00016     
00017     NSColor* srcCol = [srcColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
00018    
00019     // components
00020     char srcRed   = (char) rint([srcCol redComponent] * 255);
00021     char srcGreen = (char) rint([srcCol greenComponent] * 255);
00022     char srcBlue  = (char) rint([srcCol blueComponent] * 255);
00023     char srcAlpha = (char) rint([srcCol alphaComponent] * 255);
00024     
00025     int color =   ((srcRed << 24) & 0xFF000000);
00026     color    |= ((srcGreen << 16) & 0x00FF0000);
00027     color    |=  ((srcBlue <<  8) & 0x0000FF00); 
00028     color    |= ((srcAlpha <<  0) & 0x000000FF); 
00029     
00030     return color;
00031 }
00032 
00033 - (NSImage *)replaceColor:(NSColor *)srcColor withColor:(NSColor *)dstColor 
00034                   inImage:(NSImage *)srcImage ignoreAlha:(bool)ignoreAlpha {
00035     
00036     NSBitmapImageRep *srcImageRep = [NSBitmapImageRep 
00037                         imageRepWithData:[srcImage TIFFRepresentation]];
00038     
00039     [srcImageRep setAlpha:YES];
00040     
00041     // check if source is ok    
00042     if ([srcImageRep bitsPerSample] != 8) {
00043             NSLog(@"LLColorFilter.replaceColor src has incompatible colordepth %d", [srcImageRep bitsPerSample]);
00044             return nil;
00045     }
00046     if (([srcImageRep samplesPerPixel] != 3) && ([srcImageRep samplesPerPixel] != 4)) { 
00047             NSLog(@"LLColorFilter.replaceColor src has incompatible samples per pixel %d", [srcImageRep samplesPerPixel]);
00048             return nil;
00049     }
00050     if ([srcImageRep isPlanar]) {
00051             NSLog(@"LLColorFilter.replaceColor src has incompatible planes");
00052             return nil;
00053     }
00054     
00055     if (sizeof(int) != 4) {
00056             NSLog(@"LLColorFilter.replaceColor platform error, int is not 4 bytes");
00057             return nil;
00058     }
00059     
00060     int w = [srcImageRep pixelsWide];
00061     int h = [srcImageRep pixelsHigh];
00062     int x, y;
00063     NSImage *destImage = [[NSImage alloc] initWithSize:NSMakeSize(w, h)];
00064     
00065     NSBitmapImageRep *destImageRep = [[[NSBitmapImageRep alloc] 
00066                                     initWithBitmapDataPlanes:NULL
00067                                   pixelsWide:w 
00068                                   pixelsHigh:h 
00069                                bitsPerSample:8 
00070                              samplesPerPixel:4
00071                                     hasAlpha:YES
00072                                     isPlanar:NO
00073                               colorSpaceName:NSCalibratedRGBColorSpace
00074                                  bytesPerRow:0 
00075                                 bitsPerPixel:0] autorelease];
00076        
00077     unsigned char *srcData = [srcImageRep bitmapData];
00078     unsigned char *dstData = [destImageRep bitmapData];
00079     unsigned int  *p1, *p2;  // point to entire pixels
00080     
00081     int srcCol = [self pixelForColor:srcColor];
00082     int dstCol = [self pixelForColor:dstColor];
00083     
00084     int mask = 0xFFFFFFFF;     // everything is interesing
00085     if ((ignoreAlpha) || ([srcImageRep samplesPerPixel] == 3)) {
00086             mask = 0xFFFFFF00; // except the alpha channel
00087             srcCol &= mask;
00088     }
00089     
00090     for ( y = 0; y < h; y++ ) {
00091         for ( x = 0; x < w; x++ ) {
00092                  
00093             // tiny bug, the last byte will be read outside the buffer...
00094             // when there is no alpha channel (3 bytes vs int)
00095             p1 = (unsigned int *)srcData;
00096             p2 = (unsigned int *)dstData;
00097             
00098             if (((*p1) & mask) == srcCol) {
00099                 // match found
00100                 (*p2) = dstCol;
00101                 
00102                 if (!ignoreAlpha) {
00103                     // keep exising alpha channel value
00104                     int alpha = 0x000000FF & (*p1);
00105                     (*p2) |= alpha;
00106                     }
00107             } else  {
00108                 // keep color
00109                 *p2 = *p1;
00110             } 
00111             
00112             srcData += [srcImageRep samplesPerPixel]; // move to next pixel
00113             dstData += 4; // always 4
00114         }
00115     }
00116         
00117     [destImage addRepresentation:destImageRep];
00118     return destImage;
00119     
00120 }
00121 
00122 - (NSImage *)grayScaleImage:(NSImage *)srcImage {
00123     
00124     NSBitmapImageRep *srcImageRep = [NSBitmapImageRep 
00125                         imageRepWithData:[srcImage TIFFRepresentation]];
00126     
00127     int w = [srcImageRep pixelsWide];
00128     int h = [srcImageRep pixelsHigh];
00129     int x, y;
00130     NSImage *destImage = [[NSImage alloc] initWithSize:NSMakeSize(w, h)];
00131     
00132     NSBitmapImageRep *destImageRep = [[[NSBitmapImageRep alloc] 
00133                                     initWithBitmapDataPlanes:NULL
00134                                   pixelsWide:w 
00135                                   pixelsHigh:h 
00136                                bitsPerSample:8 
00137                              samplesPerPixel:1
00138                                     hasAlpha:NO
00139                                     isPlanar:NO
00140                               colorSpaceName:NSCalibratedWhiteColorSpace
00141                                  bytesPerRow:0 
00142                                 bitsPerPixel:0] autorelease];
00143     
00144     unsigned char *srcData = [srcImageRep bitmapData];
00145     unsigned char *destData = [destImageRep bitmapData];
00146     unsigned char *p1, *p2;
00147     
00148     for ( y = 0; y < h; y++ ) {
00149         for ( x = 0; x < w; x++ ) {
00150             p1 = srcData + 3 * (y * w + x);       
00151             p2 = destData + y * w + x;
00152             
00153             *p2 = (char)rint((*p1 + *(p1 + 1) + *(p1 + 2)) / 3);
00154         }
00155     }
00156         
00157     [destImage addRepresentation:destImageRep];
00158     return destImage;
00159 }
00160 
00161 @end

Generated on Sat Aug 26 21:14:16 2006 for MacTrek by  doxygen 1.4.7