1// 2// PRScale.m 3// PRICE 4// 5// Created by Riccardo Mottola on Wed Jan 19 2005. 6// Copyright (c) 2005-2017 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#include <math.h> 12#import "PRScale.h" 13 14#if !defined (GNUSTEP) && (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4) 15#ifndef NSInteger 16#define NSInteger int 17#endif 18#endif 19 20@implementation PRScale 21 22- (NSImage *)filterImage:(NSImage *)image with:(NSArray *)parameters progressPanel:(PRCProgress *)progressPanel 23{ 24 int pixelsX; 25 int pixelsY; 26 int method; 27 28 /* interpret the parameters */ 29 pixelsX = [[parameters objectAtIndex:0] intValue]; 30 pixelsY = [[parameters objectAtIndex:1] intValue]; 31 method = [[parameters objectAtIndex:2] intValue]; 32 33 return [self scaleImage:image :pixelsX :pixelsY :method :progressPanel]; 34} 35 36- (NSString *)actionName 37{ 38 return @"Scale"; 39} 40 41- (NSImage *)scaleImage :(NSImage *)srcImage :(int)sizeX :(int)sizeY :(int)method :(PRCProgress *)prPanel 42{ 43 NSBitmapImageRep *srcImageRep; 44 NSImage *destImage; 45 NSBitmapImageRep *destImageRep; 46 NSInteger origW, origH; 47 NSInteger x, y; 48 NSInteger i; 49 NSSize newSize; 50 unsigned char *srcData; 51 unsigned char *destData; 52 NSInteger srcSamplesPerPixel; 53 NSInteger destSamplesPerPixel; 54 register NSInteger srcBytesPerPixel; 55 register NSInteger destBytesPerPixel; 56 register NSInteger srcBytesPerRow; 57 register NSInteger destBytesPerRow; 58 float xRatio, yRatio; 59 60 /* get source image representation and associated information */ 61 srcImageRep = [[srcImage representations] objectAtIndex:0]; 62 srcBytesPerRow = [srcImageRep bytesPerRow]; 63 srcSamplesPerPixel = [srcImageRep samplesPerPixel]; 64 srcBytesPerPixel = [srcImageRep bitsPerPixel] / 8; 65 66 origW = [srcImageRep pixelsWide]; 67 origH = [srcImageRep pixelsHigh]; 68 69 70 xRatio = (float)origW / (float)sizeX; 71 yRatio = (float)origH / (float)sizeY; 72 73 74 destImage = [[NSImage alloc] initWithSize:NSMakeSize(sizeX, sizeY)]; 75 destSamplesPerPixel = [srcImageRep samplesPerPixel]; 76 destImageRep = [[NSBitmapImageRep alloc] 77 initWithBitmapDataPlanes:NULL 78 pixelsWide:sizeX 79 pixelsHigh:sizeY 80 bitsPerSample:8 81 samplesPerPixel:destSamplesPerPixel 82 hasAlpha:[srcImageRep hasAlpha] 83 isPlanar:NO 84 colorSpaceName:[srcImageRep colorSpaceName] 85 bytesPerRow:0 86 bitsPerPixel:0]; 87 88 srcData = [srcImageRep bitmapData]; 89 destData = [destImageRep bitmapData]; 90 destBytesPerRow = [destImageRep bytesPerRow]; 91 destBytesPerPixel = [destImageRep bitsPerPixel] / 8; 92 newSize = NSMakeSize([srcImageRep size].width / xRatio, [srcImageRep size].height / yRatio); 93 [destImageRep setSize:newSize]; 94 95 if (method == NEAREST_NEIGHBOUR) 96 { 97 for (y = 0; y < sizeY; y++) 98 for (x = 0; x < sizeX; x++) 99 for (i = 0; i < srcSamplesPerPixel; i++) 100 destData[destBytesPerRow * y + destBytesPerPixel * x + i] = srcData[srcBytesPerRow * (int)(y * yRatio) + srcBytesPerPixel * (int)(x * xRatio) + i]; 101 } 102 else if (method == BILINEAR) 103 { 104 /* 105 w,h : original width and height 106 v1, v2, v3, 4: four original corner values 107 v' : new computed value 108 109 v' = v1(1-w)(1-h) + v2(w)(1-h) + v3(h)(1-w) + v3(w)(h) 110 */ 111 int v1, v2, v3, v4; 112 register int x0, y0; 113 114 for (y = 0; y < sizeY; y++) 115 for (x = 0; x < sizeX; x++) 116 { 117 register float xDiff, yDiff; 118 float xFloat, yFloat; 119 120 xFloat = (float)x * xRatio; 121 yFloat = (float)y * yRatio; 122 x0 = (int)(xFloat); 123 y0 = (int)(yFloat); 124 xDiff = (xFloat - x0); 125 yDiff = (yFloat - y0); 126 for (i = 0; i < srcSamplesPerPixel; i++) 127 { 128 v1 = 0; 129 v2 = 0; 130 v3 = 0; 131 v4 = 0; 132 v1 = srcData[srcBytesPerRow * y0 + srcBytesPerPixel * x0 + i]; 133 if (x < sizeX-1 ) 134 v2 = srcData[srcBytesPerRow * y0 + srcBytesPerPixel * (x0+1) + i]; 135 if (y < sizeY-1 ) 136 v3 = srcData[srcBytesPerRow * (y0+1) + srcBytesPerPixel * x0 + i]; 137 if ((x < sizeX-1) && (y < sizeY-1)) 138 v4 = srcData[srcBytesPerRow * (y0+1) + srcBytesPerPixel * (x0+1) + i]; 139 140 destData[destBytesPerRow * y + destBytesPerPixel * x + i] = \ 141 (int)(v1*(1-xDiff)*(1-yDiff) + \ 142 v2*xDiff*(1-yDiff) + \ 143 v3*yDiff*(1-xDiff) + \ 144 v4*xDiff*yDiff); 145 } 146 } 147 } 148 else 149 NSLog(@"Unknown scaling method"); 150 151 [destImage addRepresentation:destImageRep]; 152 [destImageRep release]; 153 [destImage autorelease]; 154 return destImage; 155} 156 157@end 158