//hq2xa filter //---------------------------------------------------------- //Copyright (C) 2003 MaxSt ( maxst@hiend3d.com ) //Copyright (C) 2006 Marc Lehmann //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU Lesser General Public //License as published by the Free Software Foundation; either //version 2.1 of the License, or (at your option) any later version. // //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 //Lesser General Public License for more details. // //You should have received a copy of the GNU Lesser General Public //License along with this program; if not, write to the Free Software //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include #include #include using namespace std; #if __BYTE_ORDER == __BIG_ENDIAN # define Rshift 24 # define Gshift 16 # define Bshift 8 # define Ashift 0 #else # define Rshift 0 # define Gshift 8 # define Bshift 16 # define Ashift 24 #endif #define Cmask 0xffUL # define trY 0x30 # define trU 0x17 # define trV 0x14 # define trA 0x40 typedef uint32_t pixel; inline pixel lerp (pixel c1, int w1, pixel c2, int w2, pixel c3, int w3, int shift) { #if 0 if (!(c1 >> Ashift) & Cmask) w1 = 0; if (!(c2 >> Ashift) & Cmask) w2 = 0; if (!(c3 >> Ashift) & Cmask) w3 = 0; #endif int w = w1 + w2 + w3; return ((((c1 >> shift) & Cmask) * w1 + ((c2 >> shift) & Cmask) * w2 + ((c3 >> shift) & Cmask) * w3 + w / 2) / w) << shift; } inline void lerp (unsigned char *pc, pixel c1, int w1, pixel c2, int w2, pixel c3 = 0, int w3 = 0) { *(pixel *)pc = lerp (c1, w1, c2, w2, c3, w3, Rshift) | lerp (c1, w1, c2, w2, c3, w3, Gshift) | lerp (c1, w1, c2, w2, c3, w3, Bshift) | lerp (c1, w1, c2, w2, c3, w3, Ashift); } inline void Interp1 (unsigned char *pc, pixel c1, pixel c2) { lerp (pc, c1, 3, c2, 1); } inline void Interp2 (unsigned char *pc, pixel c1, pixel c2, pixel c3) { lerp (pc, c1, 2, c2, 1, c3, 1); } inline void Interp5 (unsigned char *pc, pixel c1, pixel c2) { lerp (pc, c1, 1, c2, 1); } inline void Interp6 (unsigned char *pc, pixel c1, pixel c2, pixel c3) { lerp (pc, c1, 5, c2, 2, c3, 1); } inline void Interp7 (unsigned char *pc, pixel c1, pixel c2, pixel c3) { lerp (pc, c1, 6, c2, 1, c3, 1); } inline void Interp9 (unsigned char *pc, pixel c1, pixel c2, pixel c3) { lerp (pc, c1, 2, c2, 3, c2, 3); } inline void Interp10 (unsigned char *pc, pixel c1, pixel c2, pixel c3) { lerp (pc, c1, 14, c2, 1, c3, 1); } #define PIXEL00_0 *((pixel *)(pOut)) = w[5]; #define PIXEL00_10 Interp1(pOut, w[5], w[1]); #define PIXEL00_11 Interp1(pOut, w[5], w[4]); #define PIXEL00_12 Interp1(pOut, w[5], w[2]); #define PIXEL00_20 Interp2(pOut, w[5], w[4], w[2]); #define PIXEL00_21 Interp2(pOut, w[5], w[1], w[2]); #define PIXEL00_22 Interp2(pOut, w[5], w[1], w[4]); #define PIXEL00_60 Interp6(pOut, w[5], w[2], w[4]); #define PIXEL00_61 Interp6(pOut, w[5], w[4], w[2]); #define PIXEL00_70 Interp7(pOut, w[5], w[4], w[2]); #define PIXEL00_90 Interp9(pOut, w[5], w[4], w[2]); #define PIXEL00_100 Interp10(pOut, w[5], w[4], w[2]); #define PIXEL01_0 *((pixel *)(pOut + sizeof (pixel))) = w[5]; #define PIXEL01_10 Interp1(pOut + sizeof (pixel), w[5], w[3]); #define PIXEL01_11 Interp1(pOut + sizeof (pixel), w[5], w[2]); #define PIXEL01_12 Interp1(pOut + sizeof (pixel), w[5], w[6]); #define PIXEL01_20 Interp2(pOut + sizeof (pixel), w[5], w[2], w[6]); #define PIXEL01_21 Interp2(pOut + sizeof (pixel), w[5], w[3], w[6]); #define PIXEL01_22 Interp2(pOut + sizeof (pixel), w[5], w[3], w[2]); #define PIXEL01_60 Interp6(pOut + sizeof (pixel), w[5], w[6], w[2]); #define PIXEL01_61 Interp6(pOut + sizeof (pixel), w[5], w[2], w[6]); #define PIXEL01_70 Interp7(pOut + sizeof (pixel), w[5], w[2], w[6]); #define PIXEL01_90 Interp9(pOut + sizeof (pixel), w[5], w[2], w[6]); #define PIXEL01_100 Interp10(pOut + sizeof (pixel), w[5], w[2], w[6]); #define PIXEL10_0 *((pixel *)(pOut+BpL)) = w[5]; #define PIXEL10_10 Interp1(pOut+BpL, w[5], w[7]); #define PIXEL10_11 Interp1(pOut+BpL, w[5], w[8]); #define PIXEL10_12 Interp1(pOut+BpL, w[5], w[4]); #define PIXEL10_20 Interp2(pOut+BpL, w[5], w[8], w[4]); #define PIXEL10_21 Interp2(pOut+BpL, w[5], w[7], w[4]); #define PIXEL10_22 Interp2(pOut+BpL, w[5], w[7], w[8]); #define PIXEL10_60 Interp6(pOut+BpL, w[5], w[4], w[8]); #define PIXEL10_61 Interp6(pOut+BpL, w[5], w[8], w[4]); #define PIXEL10_70 Interp7(pOut+BpL, w[5], w[8], w[4]); #define PIXEL10_90 Interp9(pOut+BpL, w[5], w[8], w[4]); #define PIXEL10_100 Interp10(pOut+BpL, w[5], w[8], w[4]); #define PIXEL11_0 *((pixel *)(pOut+BpL + sizeof (pixel))) = w[5]; #define PIXEL11_10 Interp1(pOut+BpL + sizeof (pixel), w[5], w[9]); #define PIXEL11_11 Interp1(pOut+BpL + sizeof (pixel), w[5], w[6]); #define PIXEL11_12 Interp1(pOut+BpL + sizeof (pixel), w[5], w[8]); #define PIXEL11_20 Interp2(pOut+BpL + sizeof (pixel), w[5], w[6], w[8]); #define PIXEL11_21 Interp2(pOut+BpL + sizeof (pixel), w[5], w[9], w[8]); #define PIXEL11_22 Interp2(pOut+BpL + sizeof (pixel), w[5], w[9], w[6]); #define PIXEL11_60 Interp6(pOut+BpL + sizeof (pixel), w[5], w[8], w[6]); #define PIXEL11_61 Interp6(pOut+BpL + sizeof (pixel), w[5], w[6], w[8]); #define PIXEL11_70 Interp7(pOut+BpL + sizeof (pixel), w[5], w[6], w[8]); #define PIXEL11_90 Interp9(pOut+BpL + sizeof (pixel), w[5], w[6], w[8]); #define PIXEL11_100 Interp10(pOut+BpL + sizeof (pixel), w[5], w[6], w[8]); inline pixel RGBAtoYUVA (pixel w) { int r = (w >> Rshift) & Cmask; int g = (w >> Gshift) & Cmask; int b = (w >> Bshift) & Cmask; int a = (w >> Ashift) & Cmask; int Y = (r + g + b) / 4; int u = 128 + (r - b) / 4; int v = 128 + (2 * g - r - b) / 8; return (Y << Rshift) | (u << Gshift) | (v << Bshift) | (a << Ashift); } inline bool Diff (pixel w1, pixel w2) { pixel YUV1 = RGBAtoYUVA (w1); pixel YUV2 = RGBAtoYUVA (w2); return ((abs (((YUV1 >> Rshift) & Cmask) - ((YUV2 >> Rshift) & Cmask)) > trY) || (abs (((YUV1 >> Gshift) & Cmask) - ((YUV2 >> Gshift) & Cmask)) > trU) || (abs (((YUV1 >> Bshift) & Cmask) - ((YUV2 >> Bshift) & Cmask)) > trV) || (abs (((YUV1 >> Ashift) & Cmask) - ((YUV2 >> Ashift) & Cmask)) > trA) ); } void hq2x_32 (unsigned char *pIn, unsigned char *pOut, int Xres, int Yres, int BpL) { int i, j, k; int prevline, nextline; pixel w[10]; // +----+----+----+ // | | | | // | w1 | w2 | w3 | // +----+----+----+ // | | | | // | w4 | w5 | w6 | // +----+----+----+ // | | | | // | w7 | w8 | w9 | // +----+----+----+ for (j=0; j0) prevline = -Xres * sizeof (pixel); else prevline = 0; if (j0) { w[1] = *((pixel *)(pIn + prevline - sizeof (pixel))); w[4] = *((pixel *)(pIn - sizeof (pixel))); w[7] = *((pixel *)(pIn + nextline - sizeof (pixel))); } else { w[1] = w[2]; w[4] = w[5]; w[7] = w[8]; } if (ioutput.rgba\n"); printf("input file must be 32 bit rgba w*h.\n"); return 1; } int w = atoi (argv [1]); int h = atoi (argv [2]); int size = w * h * sizeof (pixel); unsigned char *in = new unsigned char [size]; unsigned char *out = new unsigned char [size * 4]; if (fread (in, size, 1, stdin) != 1) { perror ("unable to read input file\n"); exit (1); } hq2x_32 (in, out, w, h, w * sizeof (pixel) * 2); if (fwrite (out, size * 4, 1, stdout) != 1) { perror ("unable to read output file\n"); exit (1); } return 0; }