//OScale2x //By Omni // //An implementation of the Scale2x algorithm in Verge, as an image converter. //For more information, see http://scale2x.sourceforge.net. // //Note that this is _not_ the same as the 2xSAI or Eagle enhancers. //2xSAI info here: http://elektron.its.tudelft.nl/~dalikifa/ //and here: http://bob.allegronetwork.com/projects.html //Just in case you're interested. Couldn't find anything on Eagle. // //Last updated Tuesday, April 12, 2005 /*Notes Creation --Just so you know, I'm not a C programming expert, so I could be a little rough on my translation of this to VergeC. Use 1. Load an image. 2. Convert it using oScale2x(). 3. If you desire, you can repeat the conversion recursively for more detail. 4. Use the image. Algorithm Each pixel is expanded to a 2x2 square. The surrounded pixels are all taken into account. A B C D X F X is the pixel we're focusing on here. G H I Target pixel X is expanded to X1 X2 X3 X4 Using this logic. Here, X = E, the center pixel. if (B != H && D != F) { E0 = D == B ? D : E; Guesses here: 1. I assume 'D : E" means blend D with E. 2. Or, I assume if true, use D, else, use E. #2 IS CORRECT E1 = B == F ? F : E; E2 = D == H ? D : E; E3 = H == F ? F : E; } else { E0 = E; E1 = E; E2 = E; E3 = E; } */ int oScale2x(int srcimg, int blur_type) { //Psuedo-implementation of the Scale2x algorithm in VergeC. //Converts the given image and returns a new image handle. // //type = 0 uses normal pixel calculation. //type = 1 uses some blending thing I came up with. int srcw = ImageWidth(srcimg), srch = ImageHeight(srcimg); int final_img = NewImage(srcw*2, srch*2); int pcountx, pcounty; int destx, desty; int Apx, Bpx, Cpx, Dpx, Fpx, Gpx, Hpx, Ipx; //surrounding pixels int Epx; //current altering pixel int Epx1, Epx2, Epx3, Epx4; //newly created pixel data while (pcounty < ImageHeight(srcimg)) { pcountx = 0; destx = 0; while (pcountx < ImageWidth(srcimg)) { //Get pixel values from srcimg. Epx = GetPixel(pcountx, pcounty, srcimg); //Get surrounding values. Apx = GetPixel(oSbV(pcountx-1, srcw), oSbV(pcounty-1, srch), srcimg); Bpx = GetPixel(oSbV(pcountx, srcw), oSbV(pcounty-1, srch), srcimg); Cpx = GetPixel(oSbV(pcountx+1, srcw), oSbV(pcounty-1, srch), srcimg); Dpx = GetPixel(oSbV(pcountx-1, srcw), oSbV(pcounty, srch), srcimg); Fpx = GetPixel(oSbV(pcountx+1, srcw), oSbV(pcounty, srch), srcimg); Gpx = GetPixel(oSbV(pcountx-1, srcw), oSbV(pcounty+1, srch), srcimg); Hpx = GetPixel(oSbV(pcountx, srcw), oSbV(pcounty+1, srch), srcimg); Ipx = GetPixel(oSbV(pcountx+1, srcw), oSbV(pcounty+1, srch), srcimg); if (Bpx != Hpx && Dpx != Fpx) { if (blur_type) { //Use my guess #1, and blend colors. (Could be useful). Epx1 = C_eqR_Blend(Dpx, Bpx, Dpx, Epx); Epx2 = C_eqR_Blend(Bpx, Fpx, Fpx, Epx); Epx3 = C_eqR_Blend(Dpx, Hpx, Dpx, Epx); Epx4 = C_eqR_Blend(Hpx, Fpx, Fpx, Epx); } else { //Use my guess #2 (I believe this is the correct method. In fact, I am 100% sure). Epx1 = C_eqReturn(Dpx, Bpx, Dpx, Epx); Epx2 = C_eqReturn(Bpx, Fpx, Fpx, Epx); Epx3 = C_eqReturn(Dpx, Hpx, Dpx, Epx); Epx4 = C_eqReturn(Hpx, Fpx, Fpx, Epx); } } else { Epx1 = Epx; Epx2 = Epx; Epx3 = Epx; Epx4 = Epx; } //Assign pixels in destination image. SetPixel(destx, desty, Epx1, final_img); SetPixel(destx+1, desty, Epx2, final_img); SetPixel(destx, desty+1, Epx3, final_img); SetPixel(destx+1, desty+1, Epx4, final_img); destx+=2; pcountx++; } desty+=2; pcounty++; } return final_img; } int oSbV(int value, int bound) { //If value is out of bounds, keep it in bounds. //Used for when we get pixels on the borders. //Essentially, get whatever pixel we can without wrapping. /* Thus if E F Where E is the upper-left pixel, H I A = E These values will be used by oScale2x() after bounding. D = E G = H B = E C = F */ if (value >= bound) return bound-1; if (value < 0) return 0; return value; } int C_eqReturn(int v1, int v2, int sol1, int sol2) { //Boolean comparison. Returns solution1 if v1 == v2, solution2 if v1 != v2. if (v1 == v2) return sol1; return sol2; } int C_eqR_Blend(int v1, int v2, int sol1, int sol2) { //Boolean comparison. If true, mixes colors sol1 & sol2. If not, returns sol2. if (v1 == v2) return MixColor(sol1, sol2, 128); return sol2; }