1//
2//  PRBriCon.m
3//  PRICE
4//
5//  Created by Riccardo Mottola on Thu Mar 3 2005.
6//  Copyright (c) 2005-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 <math.h>
12#import <AppKit/AppKit.h>
13
14#include <limits.h>
15#define HALF_CHAR (UCHAR_MAX >> 1)
16
17#import "PRBriCon.h"
18
19
20@implementation PRBriCon
21
22- (PRImage *)filterImage:(PRImage *)image with:(NSArray *)parameters progressPanel:(PRCProgress *)progressPanel
23{
24    int   brightness;
25    float contrast;
26
27    /* interpret the parameters */
28    brightness = [[parameters objectAtIndex:0] intValue];
29    contrast = [[parameters objectAtIndex:1] floatValue];
30
31    return [self adjustImage:image :brightness :contrast];
32}
33
34- (NSString *)actionName
35{
36    return @"Brightness & Contrast";
37}
38
39- (PRImage *)adjustImage :(PRImage *)srcImage :(int)bri :(float)con
40{
41  NSBitmapImageRep *srcImageRep;
42  PRImage *destImage;
43  NSBitmapImageRep *destImageRep;
44  NSInteger w, h;
45  NSInteger x, y;
46  unsigned char *srcData;
47  unsigned char *destData;
48  int tempValue;
49  NSInteger srcSamplesPerPixel;
50  NSInteger destSamplesPerPixel;
51  register NSInteger srcBytesPerPixel;
52  register NSInteger destBytesPerPixel;
53  register NSInteger srcBytesPerRow;
54  register NSInteger destBytesPerRow;
55  BOOL hasAlpha;
56
57
58    /* get source image representation and associated information */
59    srcImageRep = [srcImage bitmapRep];
60
61    w = [srcImageRep pixelsWide];
62    h = [srcImageRep pixelsHigh];
63    srcBytesPerRow = [srcImageRep bytesPerRow];
64    srcSamplesPerPixel = [srcImageRep samplesPerPixel];
65    srcBytesPerPixel = [srcImageRep bitsPerPixel] / 8;
66
67    hasAlpha = [srcImageRep hasAlpha];
68
69    destSamplesPerPixel = srcSamplesPerPixel;
70    /* allocate destination image and its representation */
71    destImage = [[PRImage alloc] initWithSize:NSMakeSize(w, h)];
72    destImageRep = [[NSBitmapImageRep alloc]
73                initWithBitmapDataPlanes:NULL
74                pixelsWide:w
75                pixelsHigh:h
76                bitsPerSample:[srcImageRep bitsPerSample]
77                samplesPerPixel:destSamplesPerPixel
78                hasAlpha:hasAlpha
79                isPlanar:NO
80                colorSpaceName:[srcImageRep colorSpaceName]
81                bytesPerRow:0
82                bitsPerPixel:0];
83    srcData = [srcImageRep bitmapData];
84    destData = [destImageRep bitmapData];
85    destBytesPerRow = [destImageRep bytesPerRow];
86    destBytesPerPixel = [destImageRep bitsPerPixel] / 8;
87
88    if ([srcImage hasColor])
89    {
90        for (y = 0; y < h; y++)
91            for (x = 0; x < w; x++)
92            {
93                tempValue = (int)rint((float)(srcData[srcBytesPerRow*y + srcBytesPerPixel*x] - HALF_CHAR + bri) * con + HALF_CHAR);
94                if (tempValue > UCHAR_MAX)
95                    tempValue = UCHAR_MAX;
96                else if (tempValue < 0)
97                    tempValue = 0;
98                destData[destBytesPerRow * y + destBytesPerPixel * x] = tempValue;
99
100                tempValue = (int)rint((float)(srcData[srcBytesPerRow*y + srcBytesPerPixel*x + 1] - HALF_CHAR + bri) * con + HALF_CHAR);
101                if (tempValue > UCHAR_MAX)
102                    tempValue = UCHAR_MAX;
103                else if (tempValue < 0)
104                    tempValue = 0;
105                destData[destBytesPerRow * y + destBytesPerPixel * x + 1] = tempValue;
106
107                tempValue = (int)rint((float)(srcData[srcBytesPerRow*y + srcBytesPerPixel*x + 2] - HALF_CHAR + bri) * con + HALF_CHAR);
108                if (tempValue > UCHAR_MAX)
109                    tempValue = UCHAR_MAX;
110                else if (tempValue < 0)
111                    tempValue = 0;
112                destData[destBytesPerRow * y + destBytesPerPixel * x + 2] = tempValue;
113
114                if (hasAlpha)
115                  destData[destBytesPerRow * y + destBytesPerPixel * x + 3] = srcData[srcBytesPerRow*y + srcBytesPerPixel*x + 3];
116            }
117    } else
118    {
119        for (y = 0; y < h; y++)
120            for (x = 0; x < w; x++)
121            {
122                tempValue = (int)rint((float)(srcData[srcBytesPerRow*y + srcBytesPerPixel*x] - HALF_CHAR + bri) * con + HALF_CHAR);
123                if (tempValue > UCHAR_MAX)
124                    tempValue = UCHAR_MAX;
125                else if (tempValue < 0)
126                    tempValue = 0;
127                destData[destBytesPerRow * y + destBytesPerPixel * x] = tempValue;
128
129                if (hasAlpha)
130                  destData[destSamplesPerPixel*(y*w + x) + 1] = srcData[srcBytesPerRow*y + srcSamplesPerPixel*x + 1];
131            }
132    }
133
134    [destImage setBitmapRep:destImageRep];
135    [destImageRep release];
136    [destImage autorelease];
137    return destImage;
138}
139
140- (BOOL)displayProgress
141{
142    return NO;
143}
144
145
146@end
147