1// 2// PRInvert.m 3// PRICE 4// 5// Created by Riccardo Mottola on Fri Dec 07 2007. 6// Copyright (c) 2007-2014 Carduus. All rights reserved. 7// 8// This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 9// This program 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 General Public License for more details. 10 11#include <limits.h> 12#import "PRInvert.h" 13 14 15@implementation PRInvert 16 17- (PRImage *)filterImage:(PRImage *)image with:(NSArray *)parameters progressPanel:(PRCProgress *)progressPanel 18{ 19 /* interpret the parameters */ 20 21 return [self filterImage:image]; 22} 23 24- (NSString *)actionName 25{ 26 return @"Invert"; 27} 28 29- (PRImage *)filterImage:(PRImage *)srcImage 30{ 31 NSBitmapImageRep *srcImageRep; 32 PRImage *destImage; 33 NSBitmapImageRep *destImageRep; 34 NSInteger w, h; 35 NSInteger x, y; 36 BOOL hasAlpha; 37 NSInteger srcBytesPerRow; 38 NSInteger destBytesPerRow; 39 NSInteger bitsPerPixel; 40 NSInteger srcBytesPerPixel; 41 NSInteger destBytesPerPixel; 42 register NSInteger maxPerChannel; 43 44 45 /* get source image representation and associated information */ 46 srcImageRep = [srcImage bitmapRep]; 47 w = [srcImageRep pixelsWide]; 48 h = [srcImageRep pixelsHigh]; 49 srcBytesPerRow = [srcImageRep bytesPerRow]; 50 hasAlpha = [srcImageRep hasAlpha]; 51 bitsPerPixel = [srcImageRep bitsPerPixel]; 52 srcBytesPerPixel = bitsPerPixel / 8; 53 maxPerChannel = pow(2, [srcImageRep bitsPerSample])-1; 54 55 /* allocate destination image and its representation */ 56 destImage = [[PRImage alloc] initWithSize:[srcImage size]]; 57 destImageRep = [[NSBitmapImageRep alloc] 58 initWithBitmapDataPlanes:NULL 59 pixelsWide:w 60 pixelsHigh:h 61 bitsPerSample:[srcImageRep bitsPerSample] 62 samplesPerPixel:[srcImageRep samplesPerPixel] 63 hasAlpha:hasAlpha 64 isPlanar:NO 65 colorSpaceName:[srcImageRep colorSpaceName] 66 bytesPerRow:0 67 bitsPerPixel:0]; 68 69 destBytesPerRow = [destImageRep bytesPerRow]; 70 destBytesPerPixel = [destImageRep bitsPerPixel] / 8; 71 72 /* execute the actual filtering */ 73 /* take in account if image has alpha and if it is has one or 3 samples */ 74 /* alpha shall be preserved and not inverted */ 75 if ([srcImageRep bitsPerSample] == 8) 76 { 77 unsigned char *srcData; 78 unsigned char *destData; 79 unsigned char *p1; 80 unsigned char *p2; 81 82 srcData = [srcImageRep bitmapData]; 83 destData = [destImageRep bitmapData]; 84 if (![srcImage hasColor]) 85 for (y = 0; y < h; y++) 86 for (x = 0; x < w; x++) 87 { 88 p1 = srcData + srcBytesPerRow * y + srcBytesPerPixel * x; 89 p2 = destData + destBytesPerRow * y + destBytesPerPixel * x; 90 p2[0] = maxPerChannel - p1[0]; 91 if (hasAlpha) 92 p2[1] = p1[1]; 93 } 94 else 95 for (y = 0; y < h; y++) 96 for (x = 0; x < w; x++) 97 { 98 p1 = srcData + srcBytesPerRow * y + srcBytesPerPixel * x; 99 p2 = destData + destBytesPerRow * y + destBytesPerPixel * x; 100 p2[0] = maxPerChannel - p1[0]; 101 p2[1] = maxPerChannel - p1[1]; 102 p2[2] = maxPerChannel - p1[2]; 103 if(hasAlpha) 104 p2[3] = p1[3]; 105 } 106 } 107 else if ([srcImageRep bitsPerSample] == 16) 108 { 109 unsigned short *srcData; 110 unsigned short *destData; 111 unsigned short *p1; 112 unsigned short *p2; 113 114 srcData = (unsigned short*)[srcImageRep bitmapData]; 115 destData = (unsigned short*)[destImageRep bitmapData]; 116 if (![srcImage hasColor]) 117 for (y = 0; y < h; y++) 118 for (x = 0; x < w; x++) 119 { 120 p1 = (unsigned short*)((unsigned char*)srcData + srcBytesPerRow * y + srcBytesPerPixel * x); 121 p2 = (unsigned short*)((unsigned char*)destData + destBytesPerRow * y + destBytesPerPixel * x); 122 p2[0] = maxPerChannel - p1[0]; 123 if (hasAlpha) 124 p2[1] = p1[1]; 125 } 126 else 127 for (y = 0; y < h; y++) 128 for (x = 0; x < w; x++) 129 { 130 p1 = (unsigned short*)((unsigned char*)srcData + srcBytesPerRow * y + srcBytesPerPixel * x); 131 p2 = (unsigned short*)((unsigned char*)destData + destBytesPerRow * y + destBytesPerPixel * x); 132 p2[0] = maxPerChannel - p1[0]; 133 p2[1] = maxPerChannel - p1[1]; 134 p2[2] = maxPerChannel - p1[2]; 135 if(hasAlpha) 136 p2[3] = p1[3]; 137 } 138 } 139 else 140 { 141 NSLog(@"Unhandled bits per sample: %ld", (long int)[srcImageRep bitsPerSample]); 142 } 143 [destImage setBitmapRep:destImageRep]; 144 [destImageRep release]; 145 [destImage autorelease]; 146 return destImage; 147} 148 149- (BOOL)displayProgress 150{ 151 return NO; 152} 153 154 155@end 156