Пример #1
0
/**
 * Apply the Scale effect on a bitmap.
 * This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
 * \param scale Scale factor. 2, 3 or 4.
 * \param void_dst Pointer at the first pixel of the destination bitmap.
 * \param dst_slice Size in bytes of a destination bitmap row.
 * \param void_src Pointer at the first pixel of the source bitmap.
 * \param src_slice Size in bytes of a source bitmap row.
 * \param pixel Bytes per pixel of the source and destination bitmap.
 * \param width Horizontal size in pixels of the source bitmap.
 * \param height Vertical size in pixels of the source bitmap.
 */
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
{
	switch (scale) {
	case 2 : scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height); break;
	case 3 : scale3x(void_dst, dst_slice, void_src, src_slice, pixel, width, height); break;
	case 4 : scale4x(void_dst, dst_slice, void_src, src_slice, pixel, width, height); break;
	}
}
Пример #2
0
/**
 * Apply the Scale effect on a bitmap.
 * This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
 * \param scale Scale factor. 2, 203 (fox 2x3), 204 (for 2x4), 3 or 4.
 * \param void_dst Pointer at the first pixel of the destination bitmap.
 * \param dst_slice Size in bytes of a destination bitmap row.
 * \param void_src Pointer at the first pixel of the source bitmap.
 * \param src_slice Size in bytes of a source bitmap row.
 * \param pixel Bytes per pixel of the source and destination bitmap.
 * \param width Horizontal size in pixels of the source bitmap.
 * \param height Vertical size in pixels of the source bitmap.
 */
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned width, unsigned height)
{
	switch (scale) {
	case 202 :
	case 2 :
		scale2x(void_dst, dst_slice, void_src, src_slice, width, height);
		break;
	case 203 :
		scale2x3(void_dst, dst_slice, void_src, src_slice, 4, width, height);
		break;
	case 204 :
		scale2x4(void_dst, dst_slice, void_src, src_slice, 4, width, height);
		break;
	case 303 :
	case 3 :
		scale3x(void_dst, dst_slice, void_src, src_slice, width, height);
		break;
	case 404 :
	case 4 :
		scale4x(void_dst, dst_slice, void_src, src_slice, width, height);
		break;
	}
}
Пример #3
0
void drawPNG() {
    double h = gHeight;
    double w = gWidth;

    glClearColor(0.0, 0.0, 0.0, 0.0);

    double max;
    if (gHeight > gWidth) {
        max = gHeight;
    } else {
        max = gWidth;
    }

    /*
     * This is for pressing the key '1'. It renders the png image as it is.
     * It can be blown up to whatever size the user desires, and the pixels/pixel 
     * size will be scaled accordingly with no algorithm attempted to depixel the
     * png image.
     *
     */
    if (gDrawMode == 1) {
        glClearColor(0.0, 0.0, 0.0, 0.0);
        double pointSize = int(yRes/h) + 1.0;

        glPointSize(pointSize);
        glBegin(GL_POINTS);
        glVertex3f(0.95,-0.95,0);

        for(int y=0; y<h; y++) {
            for (int x = 0; x < gWidth; x ++) {
                int index = 4 * x + (4 * w * y);

                glColor4d(int(gData[index]) / 256.0, int(gData[index+1]) / 256.0, int(gData[index+2]) / 256.0, int(gData[index+3]) / 256.0) ;
                glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max, -1 + (pointSize / yRes)+ 2*y/max, 0);
            }
        }
        glEnd();
    }
    
    /*
     * This is for pressing the key '2'. It renders the png image using the EPX algorithm. Basically, 
     * we break down each pixel into a 2x2 (so 4 pixels). If two same-color pixels of the original 
     * png image are adjacent to a pixel of the original png image such that the three pixels form 
     * a 90 degree angle, then the corresponding pixel in the blown up 2x2 is that color as well. So,
     * for example, let's say that pixel A and pixel B are the same color white such that pixel A 
     * is adjacently above pixel C and pixel B is adjacently to the right of pixel C. We then blow up
     * pixel C into a 2x2 set of pixels. Since pixels A and B are above and right of pixel C, we would 
     * then render the top right pixel of the 2x2 with the same color, white. This is essentially the 
     * EPX algorithm.
     *
     */ 

    else if (gDrawMode == 2) {
        glClearColor(0.0, 0.0, 0.0, 0.0);
        double pointSize = round(0.5 * yRes/h + 0.5);

        glPointSize(pointSize);
        glBegin(GL_POINTS);
        glVertex3f(0.95,-0.95,0);

        for(int y=0; y<h; y++) {
            for (int x = 0; x < gWidth; x ++) {
                int index = 4 * x + (4 * w * y);

                glColor4d(int(gData[index]) / 256.0, int(gData[index+1]) / 256.0, int(gData[index+2]) / 256.0, int(gData[index+3]) / 256.0) ;

                int upIndex = getUpNeighbor(x,y, gWidth, gHeight);
                int downIndex = getDownNeighbor(x,y, gWidth, gHeight);
                int leftIndex = getLeftNeighbor(x,y, gWidth, gHeight);
                int rightIndex = getRightNeighbor(x,y, gWidth, gHeight);

                // this is for the corner cases
                if ((upIndex == -1 && leftIndex == -1) ||
                    (upIndex == -1 && rightIndex == -1) ||
                    (downIndex == -1 && leftIndex == -1) ||
                    (downIndex == -1 && rightIndex == -1))
                {
                    // bottom-left pixel of the 2x2
                    glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max, -1 + (pointSize / yRes)+ 2*y/max, 0);
                    // bottom-right pixel of the 2x2
                    glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max + 2*pointSize/xRes, -1 + (pointSize / yRes)+ 2*y/max , 0);
                    // top-left pixel of the 2x2
                    glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max, -1 + (pointSize / yRes)+ 2*y/max + 2*pointSize/yRes, 0);
                    // top-right pixel of the 2x2
                    glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max + 2*pointSize/xRes, -1 + (pointSize / yRes)+ 2*y/max + 2*pointSize/yRes, 0);                    
                }
                
                else
                {
                    Vec3 up, down, left, right;
                    up.x = gData[upIndex];
                    up.y = gData[upIndex+1];
                    up.z = gData[upIndex+2];
                    down.x = gData[downIndex];
                    down.y = gData[downIndex+1];
                    down.z = gData[downIndex+2];
                    right.x = gData[rightIndex];
                    right.y = gData[rightIndex+1];
                    right.z = gData[rightIndex+2];
                    left.x = gData[leftIndex];
                    left.y = gData[leftIndex+1];
                    left.z = gData[leftIndex+2];

                    bool upLeft = (up == left);
                    bool upRight = (up == right);
                    bool downLeft = (down == left);
                    bool downRight = (down == right);
                    //std::cout << upLeft << std::endl;
                    //std::cout << upRight << std::endl;
                    //std::cout << downLeft << std::endl;
                    //std::cout << downRight << std::endl;

                    if (downLeft) {
                        glColor4d(down.x / 256.0, down.y / 256.0, down.z / 256.0, int(gData[downIndex+3]) / 256.0);
                    } 
                    // bottom-left pixel of the 2x2
                    glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max, -1 + (pointSize / yRes)+ 2*y/max, 0);
                    glColor4d(int(gData[index]) / 256.0, int(gData[index+1]) / 256.0, int(gData[index+2]) / 256.0, int(gData[index+3]) / 256.0);

                    if (downRight) {
                        glColor4d(down.x / 256.0, down.y / 256.0, down.z / 256.0, int(gData[downIndex+3]) / 256.0);
                    } 
                    // bottom-right pixel of the 2x2
                    glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max + 2*pointSize/xRes, -1 + (pointSize / yRes)+ 2*y/max , 0);
                    glColor4d(int(gData[index]) / 256.0, int(gData[index+1]) / 256.0, int(gData[index+2]) / 256.0, int(gData[index+3]) / 256.0);

                    if (upLeft) {
                        glColor4d(up.x / 256.0, up.y / 256.0, up.z / 256.0, int(gData[upIndex+3]) / 256.0);
                    }
                    // top-left pixel of the 2x2
                    glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max, -1 + (pointSize / yRes)+ 2*y/max + 2*pointSize/yRes, 0);
                    glColor4d(int(gData[index]) / 256.0, int(gData[index+1]) / 256.0, int(gData[index+2]) / 256.0, int(gData[index+3]) / 256.0);

                    if (upRight) {
                        glColor4d(up.x / 256.0, up.y / 256.0, up.z / 256.0, int(gData[downIndex+3]) / 256.0);
                    }
                    // top-right pixel of the 2x2
                    glVertex3f(-1 + (pointSize / xRes) + 2*(x)/max + 2*pointSize/xRes, -1 + (pointSize / yRes)+ 2*y/max + 2*pointSize/yRes, 0);
                    glColor4d(int(gData[index]) / 256.0, int(gData[index+1]) / 256.0, int(gData[index+2]) / 256.0, int(gData[index+3]) / 256.0);
                }
            }
        }
        glEnd();
    }

    // glDrawPixels, no EPX, just regular image
    else if (gDrawMode == 3) {
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glColor3f(0.0f, 0.0f, 0.0f);
        //GLubyte color[2][2][4];

        
        GLubyte color[gHeight][gWidth][4];
        for(int y = 0; y < gHeight; y++) {
            for (int x = 0; x < gWidth; x ++) {
                int index = 4 * x + (4 * w * y);

                color[y][x][0] = int(gData[index]);
                color[y][x][1] = int(gData[index+1]);
                color[y][x][2] = int(gData[index+2]);
                color[y][x][3] = int(gData[index+3]);

                //std::cout << "X: " << x/3 << " Y: " << y << "  rgb: " << int(gData[index]) << " " << int(gData[index + 1]) << " " << int(gData[index+2]) << std::endl;

                //glColor3d(int(gData[index]) / 256.0, int(gData[index+1]) / 256.0, int(gData[index+2]) / 256.0);
                //glVertex3f(-1 + (pointSize / xRes) + 2*(x/3)/max, -1 + (pointSize / yRes)+ 2*y/max, 0);
            }
        }
        
        //GLfloat scaleX = 1.0f * xRes / 2;
        //GLfloat scaleY = 1.0f * yRes / 2;
        //std::cout << scaleX << " " << scaleY << std::endl;
        //glPixelZoom(scaleX/15.99, scaleY/15.99);
        glPixelZoom(floor(xRes/max), floor(yRes/max));

        //glPixelZoom(5,5);
        glRasterPos2d(-1.0, -1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawPixels( gWidth, gHeight, GL_RGBA, GL_UNSIGNED_BYTE, color );
        glFlush();
    }

    /* EPX algorithm with gldrawPixels */
    else if (gDrawMode == 4) {
        epx(gHeight, gWidth, h, w, xRes, yRes, max, gData);
    }

    /* scale2x algorithm with gldrawPixels */
    else if (gDrawMode == 5) {
        scale2x(gHeight, gWidth, h, w, xRes, yRes, max, gData);
    }
    /* scale3x algorithm with gldrawPixels */
    else if (gDrawMode == 6) {
        scale3x(gHeight, gWidth, h, w, xRes, yRes, max, gData);
    }

    /* scale4x algorithm with gldrawPixels */
    else if (gDrawMode == 7) {
        scale4x(gHeight, gWidth, h, w, xRes, yRes, max, gData);
    }

    /* eagle algorithm with gldrawPixels */
    else if (gDrawMode == 8) {
        eagle(gHeight, gWidth, h, w, xRes, yRes, max, gData);
    }

    /* bilinear interpolation! */
    else if (gDrawMode == 9) {
        bilinear2x(gHeight, gWidth, h, w, xRes, yRes, max, gData);
    }

    /* bicubic interpolation! */
    else if (gDrawMode == 10) {
        bicubic2x(gHeight, gWidth, h, w, xRes, yRes, max, gData);
    }

     /* eagle3x! */
    else if (gDrawMode == 11) {
        eagle3x(gHeight, gWidth, h, w, xRes, yRes, max, gData);
    }

    // no matter what draw mode, draw nearest neighbor on the right side
    // Set matrix mode
    glMatrixMode(GL_PROJECTION);
    // push current projection matrix on the matrix stack
    glPushMatrix();
    // Set an ortho projection based on window size
    glLoadIdentity();
    glOrtho(0, xRes * 2, 0, yRes, 0, 1);
    // Switch back to model-view matrix
    glMatrixMode(GL_MODELVIEW);
    // Store current model-view matrix on the stack
    glPushMatrix();
    // Clear the model-view matrix
    glLoadIdentity();
    // You can specify this in window coordinates now
    glRasterPos2i(2*xRes,0);
    glPixelZoom(floor(xRes/max), floor(yRes/max));
    glDrawPixels(gWidth, gHeight, GL_RGBA, GL_UNSIGNED_BYTE, gData);
    // Restore the model-view matrix
    glPopMatrix();
    // Switch to projection matrix and restore it
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

}