Flipping Vertices with C

160 views Asked by At

I am trying to flip an image in C vertically so if the image is < it will end up > and my function includes

//Setting the struct up for the pixel's
struct pixel
 {
   unsigned char red;
   unsigned char green;
   unsigned char blue;
};

//Setting the struct up for the Image Type and scanning in the pxiels into an array
struct ImageType 
{  
   char ppImage[3];
   char comment[256];
   char newlinechar;
   int width, height;
   int maxColor = 255;
   struct pixel image[100][100];
};


//Function in order to flip the image, going from the left most pixel flipping with the      right most
void MirrorVertical(struct ImageType imgur)
{
   int x,y;
   const int middle = imgur.width / 2;
   struct pixel tmp;
   struct *pixel p;

   for(y=0; y < imgur.height; ++y)
      {
         p = tmp + y * imgur.width;

         for(x=0; x < middle; ++x)
           {
               tmp = p[x];
               p[x] = p[imgur.width - 1 - x];
               p[imgur.width - 1 - x] = tmp;
           }
      }
}

I got my structs to work but for some reason my function will not output it, I am scanning in the image into from a struct so....

//Scanning in the pixels for the first image
   for(i=imageA.height-1; i <= 0; i--)
      {
         for(j=0; j < imageA.width; j++)
            {
               scanf("%hhu", &imageA.image[i][j].red);
               scanf("%hhu", &imageA.image[i][j].green);
               scanf("%hhu", &imageA.image[i][j].blue);
            }
      }

What am I doing wrong in my function?

It should be

   for(x=0; x < width; x++)
      {
         for(y = 0; y < height/2; y++)
            {
               temp = imgur.image[x][y];
               imgur.image[x][y] = imgur.image[x][height-y-1]
               imgur.image[x][height-y-1] = temp;
            }
      }
}
2

There are 2 answers

3
yasen On

Shouldn't this: for(i=imageA.height-1; i <= 0; i--) be for(i=imageA.height-1; i >= 0; i--)? (in the "scanning in the pixels for the first image" code)

5
Floris On

I imagine your compiler must be complaining about

struct pixel tmp;
struct *pixel p;

for(y=0; y < imgur.height; ++y)
  {
     p = tmp + y * imgur.width;

You are adding a struct to an int and allocating the result to a pointer. How is it supposed to work?

EDIT now that you have updated your question with "better" code and it's still not working, here are a few things you could / should change.

  1. You declare a variable tmp then try to access temp. Recipe for failure
  2. You pass the entire struct imgur to the function. That means "make a copy of everything". You should really pass a pointer to the object - change the prototype to reflect that, and access the elements as imgur->height etc
  3. You never declare the variables height and width in your MirrorVertical function
  4. (minor) you compute the value height - 1 - y twice per inner loop - 20000 times in total. If you swap the inner and outer loops and compute it just once (and assign to a new variable newY) you can save a little bit of time (not sure it it's really more efficient since you end up looping over X which might destroy cache coherence instead, especially with big images).
  5. My compiler (and the C standard) complains about the statement int maxColor = 256; in the definition of the struct; you cannot initialize a value in the typedef.
  6. Miscellaneous other errors thrown by the compiler.

I took the liberty of fixing many of them - that leads to the following code which appears to compile and run; now all you need is add your "input image" and "output image" functions (maybe).

#include <stdio.h>

//Setting the struct up for the pixels
struct pixel
 {
   unsigned char red;
   unsigned char green;
   unsigned char blue;
};

//Setting the struct up for the Image Type and scanning in the pixels into an array
struct ImageType
{
   char ppImage[3];
   char comment[256];
   char newlinechar;
   int width;
   int height;
   int maxColor;  // cannot initialize this here; removed "=256"
   struct pixel image[100][100];
};


//Function in order to flip the image, going from the left most pixel flipping with the      right most
void MirrorVertical(struct ImageType *imgur) // using a pointer to the struct
{
   int x,y, height, width;  // added declaration of height, width
   // const int middle = imgur->width / 2; // removed, not used
   struct pixel tmp;  // use same name here and in loop
   height = imgur->height;  // initialize once - save a redirect later
   width = imgur->width;    // ditto
   for(y = 0; y < imgur->height/2; y++)  // made this the outer loop
   {
     int newY = height - y - 1; // so we only compute it once
     for(x=0; x < imgur->width; x++)
     {
         tmp = imgur->image[x][y];  // use "tmp" not "temp"
         imgur->image[x][y] = imgur->image[x][newY];
         imgur->image[x][newY] = tmp;
       }
   }
}

// a simple main program… this doesn't really do anything except call the function
int main(void) {
struct ImageType i1;
// … need to add code to import the image
MirrorVertical(&i1);  // note - passing POINTER to i1, not the entire struct
// … need to add code to export the image
}

Let me know if that works.