0

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;
            }
      }
}
Dave Boz
  • 49
  • 8
  • "My function will not output it". Can you be more specific about your problem? Can you remove everything that is not directly relevant? – Floris Dec 07 '13 at 21:47
  • @Floris Sorry, my problem is within my function, I am trying to switch my swap my pixels, when scanned in from a PPM image, to reverse or (mirror). I can't seem to figure out how to take what I scanned in for the struct pixel, which is the image.A.image[i][j].red etc..etc.. and call it within the function to swap below – Dave Boz Dec 07 '13 at 21:52

2 Answers2

1

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.

Floris
  • 45,857
  • 6
  • 70
  • 122
  • yes exactly, I am trying to call the first struct, pixel and give it a temporary file, and then switching it and returning it into p. – Dave Boz Dec 07 '13 at 21:53
  • 1
    i definitly overthought this one... all i had to do was imgur.image[y][x] = imgur.image[width-x][y]; Sorry.... ha – Dave Boz Dec 07 '13 at 22:03
  • You are mixing pointers and values. Perhaps you mean `p=&tmp + y*imgur.width;`? – Floris Dec 07 '13 at 22:03
  • Yes, I am just going to define the width and height in my program myself and not worry about it, so i believe it should just crop it. Look at my edit above... I think I fixed it.. but am i just flipping or am i mirroring it? – Dave Boz Dec 07 '13 at 22:08
  • in C how to I assign temp to the structure though for temp = imgur.image[x][y] to hold the value? since its an interger it wont let me.... – Dave Boz Dec 07 '13 at 22:22
1

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)

yasen
  • 1,250
  • 7
  • 13
  • I am going from the top down, so you are starting at one less than the height and column 0. Which is why I had <= instead of >= – Dave Boz Dec 07 '13 at 22:23
  • @user3078582 But this value is supposed to be positive, isn't it? – yasen Dec 07 '13 at 22:24
  • I thought it was suppose to be negative because I am decrementing each time, because I'm outputting the image from top down – Dave Boz Dec 07 '13 at 22:29