View Full Version : Scale2x?
Has anyone ported the scale2x image-smoothing algorithm to Pascal? (http://scale2x.sourceforge.net/) Or failing that, other scaling/smoothing algorithms? I would like to use one for my Multiplexity game to add perceived image quality without effort :lol:
I haven't seen it discussed or mentioned anywhere, so if nobody else has written code I will try translating from this source:
http://scale2x.sourceforge.net/contrib/sdl/scale2x.c
(it's very small, but it has some boilerplate and a handful of macros to work out, and I've never translated from C before)
Traveler
11-02-2007, 12:13 PM
I definitely have seen this site mentioned before. I'm not entirely sure though it was here at PGD or if it has been translated to Pascal.
JernejL
11-02-2007, 12:42 PM
http://scale2x.sourceforge.net/contrib/sdl/scale2x.c
who wrote it and what's the license for it?
dmantione
11-02-2007, 01:14 PM
It is the GPL.
If GPL isn't suitable for you, implement it using the algorithm description: http://scale2x.sourceforge.net/algorithm.html
Implementing from documentation normally makes you own all copyrights on your implementation.
cragwolf
11-02-2007, 11:17 PM
I've implemented scaling as part of my TGA unit. Download (http://www.ludicity.org/files/tgaconvert.tar.gz) it at your own risk (GPL license, 25 KB). Comes with a command-line image manipulation program, and a sparse but useful README.
It is the GPL.
If GPL isn't suitable for you, implement it using the algorithm description: http://scale2x.sourceforge.net/algorithm.html
Implementing from documentation normally makes you own all copyrights on your implementation.
The reference implementation is GPL. The SDL implementation which I linked is public domain.
paul_nicholls
12-02-2007, 01:25 AM
Has anyone ported the scale2x image-smoothing algorithm to Pascal? (http://scale2x.sourceforge.net/) Or failing that, other scaling/smoothing algorithms? I would like to use one for my Multiplexity game to add perceived image quality without effort :lol:
I haven't seen it discussed or mentioned anywhere, so if nobody else has written code I will try translating from this source:
http://scale2x.sourceforge.net/contrib/sdl/scale2x.c
(it's very small, but it has some boilerplate and a handful of macros to work out, and I've never translated from C before)
I don't know about scale2x, but how about these magnification algorithms?
They seem pretty neat :)
http://www.hiend3d.com/hq2x.html
http://www.hiend3d.com/hq3x.html
http://www.hiend3d.com/hq4x.html
cheers,
Paul.
I went ahead and did it, though this implementation is for 32-bit color and FPC only. It will probably port to Delphi or others with very little effort. My cpu stays at 60% with an 800x600x32x60fps SDL window. That could probably be sped up by moving the final render(the one onto the screen) to OpenGL.
http://img383.imageshack.us/img383/9592/scale2xrz3.th.png (http://img383.imageshack.us/my.php?image=scale2xrz3.png)
(a screen shot of Cave Story (http://agtp.romhack.net/doukutsu.html) run through the scaler.)
(*
32-bit only scale2x for SDL; by James Hofmann 2007
based on Pete Shinners' SDL scale2x.
Doubles the size of a surface with a smoothing algorithm.
This code is public domain.
*)
{$inline on}
{$mode objfpc}
unit scale2x32;
interface
uses sdl,sdl_video;
procedure scale2x(const src : PSDL_Surface; var dst : PSDL_Surface);
implementation
function max(const a,b : longint) : longint; inline;
begin
{ note: if we were to use unsigned numbers the border checks would cause a crash
because there would be a negative overflow }
if (a>b) then result:=a else result:=b;
end;
function min(const a,b : longint) : longint; inline;
begin
if (a<b) then result:=a else result:=b;
end;
(*
this requires a destination surface already setup to be twice as
large as the source. oh, and formats must match too. this will just
blindly assume you didn't flounder.
*)
procedure scale2x(const src : PSDL_Surface; var dst : PSDL_Surface);
var
srclinewidth : longint;
dstlinewidth : longint;
width : longint;
height : longint;
srcpix, dstpix : ^longint;
E0, E1, E2, E3, B, D, E, F, H : longint;
looph, loopw : longint;
begin
srclinewidth := (src^.pitch) div sizeof(longword);
dstlinewidth := (dst^.pitch) div sizeof(longword);
width := src^.w;
height := src^.h;
srcpix := src^.pixels;
dstpix := dst^.pixels;
for looph := 0 to height-1 do
begin
for loopw := 0 to width-1 do
begin
{ from this grid we get the values BDEFH:
ABC
DEF
GHI
and map them into a E0,E1,E2,E3:
E0 E1
E2 E3
we must also account for the borders(using the pixels nearest to border)
}
{ increment each pointer to the requested pixel }
B := (srcpix + srclinewidth * MAX(0,looph-1) + loopw)^;
D := (srcpix + srclinewidth * looph + MAX(0,loopw-1))^;
E := (srcpix + srclinewidth * looph + loopw)^;
F := (srcpix + srclinewidth * looph + MIN(width-1,loopw+1))^;
H := (srcpix + srclinewidth * MIN(height-1,looph+1) + loopw)^;
{ determine smoothing result }
if ((D = B) and (B <> F) and (D <> H)) then e0:=D else e0:=E;
if ((B = F) and (B <> D) and (F <> H)) then e1:=F else e1:=E;
if ((D = H) and (D <> B) and (H <> F)) then e2:=D else e2:=E;
if ((H = F) and (D <> H) and (B <> F)) then e3:=F else e3:=E;
{ blit the doubled pixel }
(dstpix+(looph*2*dstlinewidth + loopw*2))^:=E0;
(dstpix+(looph*2*dstlinewidth + (loopw*2+1)))^:=E1;
(dstpix+((looph*2+1)*dstlinewidth + loopw*2))^:=E2;
(dstpix+((looph*2+1)*dstlinewidth + (loopw*2+1)))^:=E3;
end;
end;
end;
end.
edit: optimized to remove unnecessary pointer and temp-value assignments.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.