1// 2// PRCurves.m 3// PRICE 4// 5// Created by Riccardo Mottola on 07/08/11. 6// Copyright 2011-2014 Riccardo Mottola. 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#import "PRCurves.h" 12 13 14@implementation PRCurves 15 16/* 17 * Paramters order: 18 * Luminance Array 19 * Red Array 20 * Green Array 21 * Blue Array 22 */ 23- (PRImage *)filterImage:(PRImage *)image with:(NSArray *)parameters progressPanel:(PRCProgress *)progressPanel 24{ 25 PRImage *retImage; 26 NSArray *array; 27 unsigned arrayL[UCHAR_MAX + 1]; 28 unsigned arrayR[UCHAR_MAX + 1]; 29 unsigned arrayG[UCHAR_MAX + 1]; 30 unsigned arrayB[UCHAR_MAX + 1]; 31 unsigned i; 32 33 if ([parameters count] != 1 && [parameters count] != 3) 34 { 35 NSLog(@"inconsistent number of parametetrs: %u", (unsigned int)[parameters count]); 36 return nil; 37 } 38 39 40 if ([parameters count] == 1) 41 { 42 array = [parameters objectAtIndex:0]; 43 if ([array count] > 0) 44 { 45 if ([array count] == UCHAR_MAX+1) 46 { 47 for (i = 0; i <= UCHAR_MAX; i++) 48 arrayL[i] = [(NSNumber *)[array objectAtIndex: i] unsignedIntValue]; 49 } 50 else 51 { 52 NSLog(@"Incompatible size of parameter array: %u", (unsigned int)[array count]); 53 } 54 } 55 retImage = [self adjustImage: image :arrayL :NULL :NULL :NULL]; 56 } 57 else 58 { 59 array = [parameters objectAtIndex:0]; 60 if ([array count] > 0) 61 { 62 if ([array count] == UCHAR_MAX+1) 63 { 64 for (i = 0; i <= UCHAR_MAX; i++) 65 arrayR[i] = [(NSNumber *)[array objectAtIndex: i] unsignedIntValue]; 66 } 67 else 68 { 69 NSLog(@"Incompatible size of parameter array: %u", (unsigned int)[array count]); 70 } 71 } 72 array = [parameters objectAtIndex:1]; 73 if ([array count] > 0) 74 { 75 if ([array count] == UCHAR_MAX+1) 76 { 77 for (i = 0; i <= UCHAR_MAX; i++) 78 arrayG[i] = [(NSNumber *)[array objectAtIndex: i] unsignedIntValue]; 79 } 80 else 81 { 82 NSLog(@"Incompatible size of parameter array: %u", (unsigned int)[array count]); 83 } 84 } 85 array = [parameters objectAtIndex:2]; 86 if ([array count] > 0) 87 { 88 if ([array count] == UCHAR_MAX+1) 89 { 90 for (i = 0; i <= UCHAR_MAX; i++) 91 arrayB[i] = [(NSNumber *)[array objectAtIndex: i] unsignedIntValue]; 92 } 93 else 94 { 95 NSLog(@"Incompatible size of parameter array: %u", (unsigned int)[array count]); 96 } 97 } 98 retImage = [self adjustImage: image :arrayL :arrayR :arrayG :arrayB]; 99 } 100 return retImage; 101} 102 103- (NSString *)actionName 104{ 105 return @"Curves"; 106} 107 108- (PRImage *)adjustImage :(PRImage *)srcImage :(unsigned *)arrayL :(unsigned *)arrayR :(unsigned *)arrayG :(unsigned *)arrayB 109{ 110 NSBitmapImageRep *srcImageRep; 111 PRImage *destImage; 112 NSBitmapImageRep *destImageRep; 113 NSInteger w, h; 114 NSInteger x, y; 115 unsigned char *srcData; 116 unsigned char *destData; 117 int tempValue; 118 NSInteger srcSamplesPerPixel; 119 NSInteger destSamplesPerPixel; 120 NSInteger srcBytesPerRow; 121 NSInteger destBytesPerRow; 122 NSInteger srcBytesPerPixel; 123 NSInteger destBytesPerPixel; 124 BOOL hasAlpha; 125 126 127 /* get source image representation and associated information */ 128 srcImageRep = [srcImage bitmapRep]; 129 130 w = [srcImageRep pixelsWide]; 131 h = [srcImageRep pixelsHigh]; 132 srcBytesPerRow = [srcImageRep bytesPerRow]; 133 srcSamplesPerPixel = [srcImageRep samplesPerPixel]; 134 srcBytesPerPixel = [srcImageRep bitsPerPixel] / 8; 135 136 /* check bith depth and color/greyscale image */ 137 hasAlpha = [srcImageRep hasAlpha]; 138 139 destSamplesPerPixel = srcSamplesPerPixel; 140 /* allocate destination image and its representation */ 141 destImage = [[PRImage alloc] initWithSize:NSMakeSize(w, h)]; 142 destImageRep = [[NSBitmapImageRep alloc] 143 initWithBitmapDataPlanes:NULL 144 pixelsWide:w 145 pixelsHigh:h 146 bitsPerSample:[srcImageRep bitsPerSample] 147 samplesPerPixel:destSamplesPerPixel 148 hasAlpha:hasAlpha 149 isPlanar:NO 150 colorSpaceName:[srcImageRep colorSpaceName] 151 bytesPerRow:0 152 bitsPerPixel:0]; 153 srcData = [srcImageRep bitmapData]; 154 destData = [destImageRep bitmapData]; 155 destBytesPerRow = [destImageRep bytesPerRow]; 156 destBytesPerPixel = [destImageRep bitsPerPixel] / 8; 157 158 if ([srcImage hasColor]) 159 { 160 for (y = 0; y < h; y++) 161 for (x = 0; x < w; x++) 162 { 163 tempValue = arrayR[srcData[srcBytesPerRow*y + srcBytesPerPixel*x]]; 164 destData[destBytesPerRow*y + destBytesPerPixel*x] = tempValue; 165 166 tempValue = arrayG[srcData[srcBytesPerRow*y + srcBytesPerPixel*x + 1]]; 167 destData[destBytesPerRow*y + destBytesPerPixel*x + 1] = tempValue; 168 169 tempValue = arrayB[srcData[srcBytesPerRow*y + srcBytesPerPixel*x + 2]]; 170 destData[destBytesPerRow*y + destBytesPerPixel*x + 2] = tempValue; 171 172 if (hasAlpha) 173 destData[destBytesPerRow*y + destBytesPerPixel*x + 3] = srcData[srcBytesPerRow*y + srcBytesPerPixel*x + 3]; 174 } 175 } 176 else 177 { 178 for (y = 0; y < h; y++) 179 for (x = 0; x < w; x++) 180 { 181 destData[destBytesPerRow*y + destBytesPerPixel*x] = arrayL[srcData[srcBytesPerRow*y + srcBytesPerPixel*x]]; 182 183 if (hasAlpha) 184 destData[destBytesPerRow*y + destBytesPerPixel*x + 1] = srcData[srcBytesPerRow*y + srcBytesPerPixel*x + 1]; 185 } 186 } 187 188 [destImage setBitmapRep:destImageRep]; 189 [destImageRep release]; 190 [destImage autorelease]; 191 return destImage; 192} 193 194- (BOOL)displayProgress 195{ 196 return NO; 197} 198 199@end 200