Question

im working on this assignment and for some reason its not copying all the rows. It skips certain lines of the bmp so it does not enlarge the picture entirely. I would greatly appreciate some feedback as to why its doing this. I know it's got to be related with the pointer arithmetic.

int enlarge(PIXEL* original, int rows, int cols, int scale, 
        PIXEL** new, int* newrows, int* newcols) 
{
    *newcols = cols * scale;
    *newrows = rows * scale;


    /* Allocate memory for enlarged bmp */ 
    *new = (PIXEL*)malloc( (*newrows)*(*newcols) * sizeof(PIXEL));
    if(!*new)
    {
        free(*new);
        fprintf(stderr, "Could not allocate memory.\n");
        return 1;
    }

    int i,j,k,l;
    int index = 0;
    int counter = scale*rows;
    PIXEL* o;
    PIXEL* n;


    for(i = 0; i < rows; i++)
    {
        for(j = 0; j < cols; j++)
        {

            for(k = 0; k < scale; k++)
            {

                o = original + (i*cols) + j;
                index++;
                for(l = 0; l < scale; l++)
                {
                    n = (*new) + ( i*cols*scale ) + index + (counter*l);
                    *n = *o;
                }

            }
        }
    }

    return 0;
}
Was it helpful?

Solution

You're copying a square block of pixels into your integer-scaled image. The outer two loops and your computation of the original pixel address are fine.

Now, looking at the inner two loops, you have this odd thing going on with counter and index which don't quite make sense. Let's rewrite that. All you need to do is copy a group of pixels for each row.

o = original + i*cols + j;
n = *new + (i*cols + j) * scale;

for(sy = 0; sy < scale; sy++)
{
    for(sx = 0; sx < scale; sx++)
    {
        n[sy*cols*scale + sx] = *o;
    }
}

I'm really not a fan of variables like i, j, k, and l. It's lazy and imparts no meaning. It's hard to see if k is a row or a column index. So I used sx and sy to mean "the scaled x- and y-coordinates" (I would recommend using x and y instead of j and i but I left them as is).


Now, here's a better way. Copy the pixels in scan lines, rather than jumping around writing a single scaled block. Here, you scale a single row, and do that multiple times. You can replace your four loops with this:

int srows = rows * scale;
int scols = cols * scale;

for( sy = 0; sy < srows; sy++ )
{
    y = sy / scale;
    o = original + y * cols;
    n = *new + sy * scols;

    for( x = 0; x < cols; x++ ) {
        for( i = 0; i < scale; i++ ) {
            *n++ = *o;
        }
        *o++;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top