1//
2//  PXBicubicScaleAlgorithm.m
3//  Pixen-XCode
4//
5//  Created by Ian Henderson on 26.08.04.
6//  Copyright 2004 Open Sword Group. All rights reserved.
7//
8
9#import "PXBicubicScaleAlgorithm.h"
10#import "PXCanvas.h"
11#import "PXLayer.h"
12
13@implementation PXBicubicScaleAlgorithm
14
15- (NSString *)name
16{
17	return @"Bicubic";
18}
19
20- (NSString *)algorithmInfo
21{
22	return NSLocalizedString(@"BICUBIC_INFO", @"Bicubic Info Here");
23}
24
25- (BOOL)canScaleCanvas:canvas toSize:(NSSize)size
26{
27	if (canvas == nil || size.width == 0 || size.height == 0) {
28		return NO;
29	}
30	return YES;
31}
32
33
34float PXBicubicWeight(float x)
35{
36	return .1666 * (pow(MAX(0, x+2), 3) - 4*pow(MAX(0, x+1), 3) + 6*pow(MAX(0, x), 3) - 4*pow(MAX(0, x-1), 3));
37}
38
39- (void)scaleCanvas:canvas toSize:(NSSize)size
40{
41	if (canvas == nil) {
42		return;
43	}
44	NSEnumerator *layerEnumerator = [[canvas layers] objectEnumerator];
45	PXLayer *layer, *layerCopy;
46	int x, y, m, n;
47	float xScale = size.width / [canvas size].width;
48	float yScale = size.height / [canvas size].height;
49	float bicubicWeightedCoefficient, red, green, blue, alpha, dx, dy;
50	NSColor *color;
51
52	NSPoint currentPoint;
53	while ( ( layer = [layerEnumerator nextObject] ) ) {
54		layerCopy = [[layer copy] autorelease];
55		[layer setSize:size];
56		for (x=0; x<size.width; x++) {
57			for (y=0; y<size.height; y++) {
58				currentPoint = NSMakePoint((int)(x/xScale),(int)(y/yScale));
59				red = 0;
60				blue = 0;
61				green = 0;
62				alpha = 0;
63				dx = x/xScale - currentPoint.x;
64				dy = y/yScale - currentPoint.y;
65				for (m=-1; m<=2; m++) {
66					for (n=-1; n<=2; n++) {
67						color = [[layerCopy colorAtPoint:NSMakePoint(currentPoint.x + m, currentPoint.y + n)] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
68						bicubicWeightedCoefficient = PXBicubicWeight((float)m - dx) * PXBicubicWeight(dy - (float)n);
69						red += [color redComponent] * bicubicWeightedCoefficient;
70						green += [color greenComponent] * bicubicWeightedCoefficient;
71						blue += [color blueComponent] * bicubicWeightedCoefficient;
72						alpha += [color alphaComponent] * bicubicWeightedCoefficient;
73					}
74				}
75				[layer setColor:[NSColor colorWithCalibratedRed:red green:green blue:blue alpha:alpha] atPoint:NSMakePoint(x, y)];
76			}
77		}
78	}
79	[canvas layersChanged];
80    [canvas canvasShouldRedraw:nil];
81}
82
83@end
84
85