Trabalho Prático 2
Processamento de Linguagens
imageraster.c
Ir para a documentação deste ficheiro.
1 /**
2  * @file imageraster.c
3  * @author
4  * - José Moura <a13742|at|alunos.ipca.pt>
5  * - Óscar Silva <a14383|at|alunos.ipca.pt>
6  * - Daniel Filipe <a17442|at|alunos.ipca.pt>
7  * @date 01 Jan 2020
8  * @brief
9  * Contem as instruções necessárias para manipular imagem PNM
10  */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15 #include <string.h>
16 #include <math.h>
17 #include "../src/imageraster.h"
18 
19 /**
20  * @brief
21  * Devolve o minimo de dois inteiros
22  * @param a inteiro 1
23  * @param b inteiro 2
24  * @return minimo ente a e b
25  */
26 int min(int a, int b) {
27  return (a < b) ? a : b;
28 }
29 
30 /**
31  * @brief
32  * Devolve o máximo de dois inteiros
33  * @param a inteiro 1
34  * @param b inteiro 2
35  * @return máximo ente a e b
36  */
37 int max(int a, int b) {
38  return (a > b) ? a : b;
39 }
40 
41 /**
42  * @brief
43  * Desenha um pixel na imagem
44  * @param img_in array da imagem
45  * @param x_size tamanho da imagem em x
46  * @param y_size tamanho da imagem em y
47  * @param x ponto em x
48  * @param y ponto em y
49  * @param r cor vermelha
50  * @param g cor verde
51  * @param b cor azul
52  */
53 void drawPoint(int *img_in, int x_size, int y_size, int x, int y, int r, int g, int b) {
54  if (x > x_size || y > x_size || x<=0 || y<=0) {
55  return;
56  }
57 
58  int imageindex = getArrayIndex(x,y,x_size,y_size);
59  img_in[imageindex] = r;
60  img_in[imageindex + 1] = g;
61  img_in[imageindex + 2] = b;
62 }
63 
64 /**
65  * @brief
66  * Desenha um circulo com um raio desde o ponto x e y
67  * @see drawPoint
68  * @param img_in array dos pixels da imagem
69  * @param x_size tamanho da imagem em x
70  * @param y_size tamanho da imagem em y
71  * @param raio raio do circulo
72  * @param x coordenada x do centro
73  * @param y coordenada y do centro
74  * @param r cor vermelha
75  * @param g cor verde
76  * @param b cor azul
77  */
78 void drawCircle(int *img_in, int x_size, int y_size,int raio,int x, int y, int r, int g, int b) {
79  float step = 0.001;
80  float theta = 0;
81  for ( ; theta <= 2 * M_PI; theta += step) {
82  int x_next = (int)(cos(theta) * raio + x);
83  int y_next = (int)(sin(theta) * raio + x);
84  drawPoint(img_in,x_size,y_size,x_next,y_next,r,g,b);
85  }
86 }
87 
88 /**
89  * @brief
90  * Desenha uma linha entre dois pontos x1,y1 x2,y2
91  * @see drawPoint
92  * @param img_in array dos pixels da imagem
93  * @param x_size tamanho da imagem em x
94  * @param y_size tamanho da imagem em y
95  * @param x1 coordenada x1
96  * @param y1 coordenada y1
97  * @param x2 coordenada x2
98  * @param y2 coordenada y2
99  * @param c_r cor vermelha
100  * @param c_g cor verde
101  * @param c_b cor azul
102  */
103 void drawLine(int *img_in, int x_size, int y_size,int x1, int y1 , int x2, int y2, int c_r, int c_g, int c_b) {
104  //printf("(%d-%d) > (%d-%d) %d>%d",x1,x2,y1,y2,x1-x2,y1-y2);
105 
106  // Vertical
107  if (x1 == x2) {
108  int ymin = min(y1,y2);
109  int ymax = max(y1,y2);
110  for (int y=ymin; y<=ymax; y++) {
111  drawPoint(img_in,x_size,y_size,x1,y,c_r,c_g,c_b);
112  }
113  } else if (y1 == y2) {
114  // Horizontal
115  int xmin = min(x1,x2);
116  int xmax = max(x1,x2);
117  for (int x=xmin; x<=xmax; x++) {
118  drawPoint(img_in,x_size,y_size,x,y1,c_r,c_g,c_b);
119  }
120  } else if (abs(x1-x2) > abs(y1-y2)) {
121  int xmin = min(x1,x2);
122  int xmax = max(x1,x2);
123  float m = (float)(y2-y1)/(float)(x2-x1);
124  float b = y1 - m * x1;
125  for (float x=xmin;x<= xmax;x += 0.01) {
126  float y = m * x + b;
127  drawPoint(img_in,x_size,y_size,x,y,c_r,c_g,c_b);
128  };
129  //printf("-1-");
130  } else if (abs(x1-x2) <= abs(y1-y2)) {
131 
132  int ymin = min(y1,y2);
133  int ymax = max(y1,y2);
134  float m = (float)(y2-y1)/(float)(x2-x1);
135  float b = y1 - m * x1;
136  for (float y=ymin;y<= ymax;y += 0.01) {
137  float x = (y-b)/m;
138  drawPoint(img_in,x_size,y_size,x,y,c_r,c_g,c_b);
139  }
140  //printf("-%d %d-2-", ymin,ymax);
141  }
142 }
143 
144 /**
145  * @brief
146  * Devolve o index no array para uma determinada coordenada.
147  * @see getImagePosition
148  * @param x coordenada a encontrar
149  * @param y coordenada a encontrar
150  * @param x_size tamanho em x da imagem
151  * @param y_size tamanho em y da imagem
152  * @return inteiro do indice no array correspondente
153  */
154 int getArrayIndex(int x, int y, int x_size, int y_size) {
155  return (x + ((y - 1) * x_size)) * 3 - 3;
156 }
157 
158 /**
159  * @brief
160  * Devolve a coordenada x e y para um determinado posicao no array
161  * @see getArrayIndex
162  * @param position inteiro da posicao no array
163  * @param x_size tamanho em x da imagem
164  * @param y_size tamanho em y da imagem
165  * @param x *POINTER - coordenada x devolvida por ref
166  * @param y *POINTER - coordenada y devolvida por ref
167  */
168 void getImagePosition(int position, int x_size, int y_size ,int *x, int *y) {
169  position = position / 3 ;
170  *y = (position) / x_size + 1;
171  *x = (position) % x_size + 1;
172 }
173 
174 /**
175  * @brief
176  * Preenche uma imagem completa com uma cor (utilizado para fazer backgrouds)
177  * @param img_in img_in array dos pixels da imagem
178  * @param x_size tamanho da imagem em x
179  * @param y_size tamanho da imagem em y
180  * @param r cor vermelha
181  * @param g cor verde
182  * @param b cor azul
183  */
184 void imageFill(int *img_in, int x_size, int y_size, int r, int g, int b) {
185 
186  for (int i = 0; i < y_size; i++) {
187  for (int j = 0; j < x_size; j++) {
188  img_in[3*(i*x_size+j)+0] = r;
189  img_in[3*(i*x_size+j)+1] = g;
190  img_in[3*(i*x_size+j)+2] = b;
191  }
192  }
193 }
194 
195 /**
196  * @brief
197  * Le a informação da imagem
198  * Esta funcao deve ser executada depois da readImageHeader
199  * @see readImageHeader
200  * @param f file pointer
201  * @param img_in img_in array dos pixels da imagem
202  */
203 void readImage(FILE *f, int *img_in)
204 {
205  int i=0, c;
206  int r_val, g_val, b_val;
207 
208  while ((c = fgetc(f)) != EOF) {
209  ungetc(c, f);
210 
211  r_val = fgetc(f);
212  g_val = fgetc(f);
213  b_val = fgetc(f);
214 
215  img_in[i++] = r_val;
216  img_in[i++] = g_val;
217  img_in[i++] = b_val;
218  }
219  fclose(f);
220 }
221 
222 /**
223  * @brief
224  * Le o cabeçalho de uma imagem ficheiro e devolve o x_size e y_size
225  * @param f file pointer
226  * @param x_size *POINTER - tamanho da imagem em x
227  * @param y_size *POINTER - tamanho da imagem em y
228  */
229 void readImageHeader(FILE *f, int *x_size, int *y_size)
230 {
231  int flag=0;
232  int x_val, y_val, maxcolors_val;
233  unsigned int i;
234  char magic[MAXLINE];
235  char line[MAXLINE];
236  int count=0;
237 
238  /* Read the PPM file header. */
239  while (fgets(line, MAXLINE, f) != NULL) {
240  flag = 0;
241  for (i = 0; i < strlen(line); i++) {
242  if (isgraph(line[i]) && (flag == 0)) {
243  if ((line[i] == '#') && (flag == 0)) {
244  flag = 1;
245  }
246  }
247  }
248  if (flag == 0) {
249  if (count == 0) {
250  count += sscanf(line, "%s %d %d %d", magic, &x_val, &y_val, &maxcolors_val);
251  } else if (count == 1) {
252  count += sscanf(line, "%d %d %d", &x_val, &y_val, &maxcolors_val);
253  } else if (count == 2) {
254  count += sscanf(line, "%d %d", &y_val, &maxcolors_val);
255  } else if (count == 3) {
256  count += sscanf(line, "%d", &maxcolors_val);
257  }
258  }
259  if (count == 4) {
260  break;
261  }
262  }
263 
264  if (!(strcmp(magic, "P6") == 0)) {
265  fprintf(stderr, "Error: Input file not in PPM format!\n");
266  exit(1);
267  }
268 
269  fprintf(stderr, "Read: type=%s, x_size=%d, y_size=%d, maxcolors_val=%d\n",
270  magic, x_val, y_val, maxcolors_val);
271  *x_size = x_val;
272  *y_size = y_val;
273 }
274 
275 /**
276  * @brief
277  * Grava num ficheiro uma imagem
278  * @param f file pointer
279  * @param img_out array dos pixels da imagem
280  * @param img_out_fname nome que damos à imagem (usado para comentario)
281  * @param x_size tamanho da imagem em x
282  * @param y_size tamanho da imagem em y
283  */
284 void writeImage(FILE *f, int *img_out, char *img_out_fname, int x_size, int y_size)
285 {
286  int i, j;
287  fprintf(f, "P6\n");
288 
289  fprintf(f, "# %s\n", img_out_fname);
290 
291  fprintf(f, "%d %d\n", x_size, y_size);
292 
293  fprintf(f, "%d\n", 255);
294 
295  /* Write the image data. */
296  for (i = 0; i < y_size; i++) {
297  for (j = 0; j < x_size; j++) {
298  fprintf(f, "%c%c%c",
299  img_out[3*(i*x_size+j)+0],
300  img_out[3*(i*x_size+j)+1],
301  img_out[3*(i*x_size+j)+2]);
302  }
303  }
304  fclose(f);
305 }
drawPoint
void drawPoint(int *img_in, int x_size, int y_size, int x, int y, int r, int g, int b)
Desenha um pixel na imagem.
Definition: imageraster.c:53
writeImage
void writeImage(FILE *f, int *img_out, char *img_out_fname, int x_size, int y_size)
Grava num ficheiro uma imagem.
Definition: imageraster.c:284
imageFill
void imageFill(int *img_in, int x_size, int y_size, int r, int g, int b)
Preenche uma imagem completa com uma cor (utilizado para fazer backgrouds)
Definition: imageraster.c:184
drawCircle
void drawCircle(int *img_in, int x_size, int y_size, int raio, int x, int y, int r, int g, int b)
Desenha um circulo com um raio desde o ponto x e y.
Definition: imageraster.c:78
getImagePosition
void getImagePosition(int position, int x_size, int y_size, int *x, int *y)
Devolve a coordenada x e y para um determinado posicao no array.
Definition: imageraster.c:168
max
int max(int a, int b)
Devolve o máximo de dois inteiros.
Definition: imageraster.c:37
min
int min(int a, int b)
Devolve o minimo de dois inteiros.
Definition: imageraster.c:26
drawLine
void drawLine(int *img_in, int x_size, int y_size, int x1, int y1, int x2, int y2, int c_r, int c_g, int c_b)
Desenha uma linha entre dois pontos x1,y1 x2,y2.
Definition: imageraster.c:103
readImageHeader
void readImageHeader(FILE *f, int *x_size, int *y_size)
Le o cabeçalho de uma imagem ficheiro e devolve o x_size e y_size.
Definition: imageraster.c:229
getArrayIndex
int getArrayIndex(int x, int y, int x_size, int y_size)
Devolve o index no array para uma determinada coordenada.
Definition: imageraster.c:154
readImage
void readImage(FILE *f, int *img_in)
Le a informação da imagem Esta funcao deve ser executada depois da readImageHeader.
Definition: imageraster.c:203
MAXLINE
#define MAXLINE
Definition: imageraster.h:15