/hw5/hw5data/vision_utilities.c

https://github.com/kscottz/ClassCrap · C · 486 lines · 396 code · 64 blank · 26 comment · 56 complexity · 92a63dceae6f780bbdc99ccb6d6bfd08 MD5 · raw file

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "vision_utilities.h"
  5. int setSize(Image *im, int rows, int columns) {
  6. im->rows=rows;
  7. im->columns=columns;
  8. im->data = (uchar *) malloc(rows * columns * sizeof(char));
  9. if(im->data == NULL) {
  10. fprintf(stderr, "Insufficient memory for new image\n");
  11. exit(1);
  12. }
  13. return 0;
  14. }
  15. int setSizeColor(ImageColor *im, int rows, int columns) {
  16. im->rows=rows;
  17. im->columns=columns;
  18. im->dataR = (uchar *) malloc(rows * columns * sizeof(char));
  19. if(im->dataR == NULL) {
  20. fprintf(stderr, "Insufficient memory for new image\n");
  21. exit(1);
  22. }
  23. im->dataG = (uchar *) malloc(rows * columns * sizeof(char));
  24. if(im->dataG == NULL) {
  25. fprintf(stderr, "Insufficient memory for new image\n");
  26. exit(1);
  27. }
  28. im->dataB = (uchar *) malloc(rows * columns * sizeof(char));
  29. if(im->dataB == NULL) {
  30. fprintf(stderr, "Insufficient memory for new image\n");
  31. exit(1);
  32. }
  33. return 0;
  34. }
  35. int getNCols(const Image *im) {
  36. return im->columns;
  37. }
  38. int getNColsColor(const ImageColor *im) {
  39. return im->columns;
  40. }
  41. int getNRows(const Image *im) {
  42. return im->rows;
  43. }
  44. int getNRowsColor(const ImageColor *im) {
  45. return im->rows;
  46. }
  47. int setColors(Image *im, int colors) {
  48. im->colors=colors;
  49. return 0;
  50. }
  51. int setColorsColor(ImageColor *im, int colors) {
  52. im->colors=colors;
  53. return 0;
  54. }
  55. int getColors(const Image *im) {
  56. return im->colors;
  57. }
  58. int getColorsColor(const ImageColor *im) {
  59. return im->colors;
  60. }
  61. int setPixel(Image *im, int i, int j, int color) {
  62. i=CLAMP(i, 0, im->rows-1);
  63. j=CLAMP(j, 0, im->columns-1);
  64. im->data[i*(im->columns)+j]=color;
  65. return 0;
  66. }
  67. int setPixelColor(ImageColor *im, int i, int j, int colorR, int colorG, int colorB) {
  68. i=CLAMP(i, 0, im->rows-1);
  69. j=CLAMP(j, 0, im->columns-1);
  70. im->dataR[i*(im->columns)+j]=colorR;
  71. im->dataG[i*(im->columns)+j]=colorG;
  72. im->dataB[i*(im->columns)+j]=colorB;
  73. return 0;
  74. }
  75. int getPixel(const Image *im, int i, int j) {
  76. i=CLAMP(i, 0, im->rows-1);
  77. j=CLAMP(j, 0, im->columns-1);
  78. return (int) im->data[i*(im->columns)+j];
  79. }
  80. int getPixelColor(const ImageColor *im, int i, int j, int colorNum) {
  81. i=CLAMP(i, 0, im->rows-1);
  82. j=CLAMP(j, 0, im->columns-1);
  83. if (colorNum==1) return (int) im->dataR[i*(im->columns)+j];
  84. if (colorNum==2) return (int) im->dataG[i*(im->columns)+j];
  85. if (colorNum==3) return (int) im->dataB[i*(im->columns)+j];
  86. return -1;
  87. }
  88. int readImage(Image *im, const char *fname) {
  89. FILE *input;
  90. char line[1024];
  91. int nCols,nRows;
  92. int levels;
  93. int i, j;
  94. /* open it */
  95. if (!fname || (input=fopen(fname,"rb"))==0)
  96. return-1;
  97. /* check for the right "magic number" */
  98. if (
  99. fread(line,1,3,input)!=3
  100. ||strncmp(line,"P5\n",3)
  101. )
  102. {
  103. fclose(input);
  104. return -1;
  105. }
  106. /* skip the comments */
  107. do
  108. fgets(line,sizeof line,input);
  109. while(*line=='#');
  110. /* read the width and height */
  111. sscanf(line,"%d %d\n",&nCols,&nRows);
  112. setSize(im, nRows, nCols);
  113. /* read # of gray levels */
  114. fgets(line,sizeof line,input);
  115. sscanf(line,"%d\n",&levels);
  116. setColors(im, levels);
  117. /* read pixel row by row */
  118. for(i=0;i<nRows;i++)
  119. {
  120. for(j=0;j<nCols;j++)
  121. {
  122. int byte=fgetc(input);
  123. if (byte==EOF) /* short file */
  124. {
  125. fclose(input);
  126. return -1;
  127. }
  128. else
  129. setPixel(im,i,j,byte);
  130. }
  131. }
  132. /* close the file */
  133. fclose(input);
  134. return 0; /* OK */
  135. }
  136. int readImageColor(ImageColor *im, const char *fname) {
  137. FILE *input;
  138. char line[1024];
  139. int nCols,nRows;
  140. int levels;
  141. int i, j;
  142. /* open it */
  143. if (!fname || (input=fopen(fname,"rb"))==0)
  144. return-1;
  145. /* check for the right "magic number" */
  146. if (
  147. fread(line,1,3,input)!=3
  148. ||strncmp(line,"P6\n",3)
  149. )
  150. {
  151. fclose(input);
  152. return -1;
  153. }
  154. /* skip the comments */
  155. do
  156. fgets(line,sizeof line,input);
  157. while(*line=='#');
  158. /* read the width and height */
  159. sscanf(line,"%d %d\n",&nCols,&nRows);
  160. setSizeColor(im, nRows, nCols);
  161. /* read # of gray levels */
  162. fgets(line,sizeof line,input);
  163. sscanf(line,"%d\n",&levels);
  164. setColorsColor(im, levels);
  165. /* read pixel row by row */
  166. for(i=0;i<nRows;i++)
  167. {
  168. for(j=0;j<nCols;j++)
  169. {
  170. int byteR, byteG, byteB;
  171. byteR=fgetc(input);
  172. if (byteR==EOF) /* short file */
  173. {
  174. fclose(input);
  175. return -1;
  176. }
  177. byteG=fgetc(input);
  178. if (byteG==EOF) /* short file */
  179. {
  180. fclose(input);
  181. return -1;
  182. }
  183. byteB=fgetc(input);
  184. if (byteB==EOF) /* short file */
  185. {
  186. fclose(input);
  187. return -1;
  188. }
  189. else
  190. setPixelColor(im,i,j, byteR, byteG, byteB);
  191. }
  192. }
  193. /* close the file */
  194. fclose(input);
  195. return 0; /* OK */
  196. }
  197. int writeImage(const Image *im, const char *fname) {
  198. FILE *output;
  199. int nRows;
  200. int nCols;
  201. int colors;
  202. int i, j;
  203. /* open the file */
  204. if (!fname || (output=fopen(fname,"wb"))==0)
  205. return(-1);
  206. nRows=getNRows(im);
  207. nCols=getNCols(im);
  208. colors=getColors(im);
  209. /* write the header */
  210. fprintf(output,"P5\n"); /* magic number */
  211. fprintf(output,"#\n"); /* empty comment */
  212. fprintf(output,"%d %d\n%03d\n",nCols,nRows,colors); /* image info */
  213. /* write pixels row by row */
  214. for(i=0;i<nRows;i++)
  215. {
  216. for(j=0;j<nCols;j++)
  217. {
  218. int byte=getPixel(im,i,j);
  219. if (fputc(byte,output)==EOF) /* couldn't write */
  220. {
  221. fclose(output);
  222. return -1;
  223. }
  224. }
  225. }
  226. /* close the file */
  227. fclose(output);
  228. return 0; /* OK */
  229. }
  230. int writeImageColor(const ImageColor *im, const char *fname) {
  231. FILE *output;
  232. int nRows;
  233. int nCols;
  234. int colors;
  235. int i, j;
  236. /* open the file */
  237. if (!fname || (output=fopen(fname, "wb"))==0)
  238. return(-1);
  239. nRows=getNRowsColor(im);
  240. nCols=getNColsColor(im);
  241. colors=getColorsColor(im);
  242. /* write the header */
  243. fprintf(output,"P6\n"); /* magic number */
  244. fprintf(output,"#\n"); /* empty comment */
  245. fprintf(output,"%d %d\n%03d\n",nCols,nRows,colors); /* image info */
  246. /* write pixels row by row */
  247. for(i=0;i<nRows;i++)
  248. {
  249. for(j=0;j<nCols;j++)
  250. {
  251. int byteR, byteG, byteB;
  252. byteR=getPixelColor(im,i,j, 1);
  253. if (fputc(byteR,output)==EOF) /* couldn't write */
  254. {
  255. fclose(output);
  256. return -1;
  257. }
  258. byteG=getPixelColor(im,i,j, 2);
  259. if (fputc(byteG,output)==EOF) /* couldn't write */
  260. {
  261. fclose(output);
  262. return -1;
  263. }
  264. byteB=getPixelColor(im,i,j, 3);
  265. if (fputc(byteB,output)==EOF) /* couldn't write */
  266. {
  267. fclose(output);
  268. return -1;
  269. }
  270. }
  271. }
  272. /* close the file */
  273. if (fclose(output)==EOF) return -1;
  274. return 0; /* OK */
  275. }
  276. int line(Image *im, int y0, int x0, int y1, int x1, int color) {
  277. int xmin,xmax; /* line coordinates */
  278. int ymin,ymax;
  279. int dir; /* scan direction */
  280. int dx; /* distance along X */
  281. int dy; /* distance along Y */
  282. /* increments: East, North-East, South, South-East, North */
  283. int incrE,
  284. incrNE,
  285. incrSE;
  286. int d; /* the D */
  287. int x,y; /* running coordinates */
  288. int mpCase; /* midpoint algorithm's case */
  289. int done; /* set to 1 when done */
  290. /* TODO note that the x and y are switched! */
  291. xmin=y0;
  292. xmax=y1;
  293. ymin=x0;
  294. ymax=x1;
  295. dx=xmax-xmin;
  296. dy=ymax-ymin;
  297. if (dx*dx>dy*dy) /* horizontal scan */
  298. {
  299. dir=DIR_X;
  300. if (xmax<xmin)
  301. {
  302. SWAP(xmin,xmax);
  303. SWAP(ymin,ymax);
  304. }
  305. dx=xmax-xmin;
  306. dy=ymax-ymin;
  307. if (dy>=0)
  308. {
  309. mpCase=1;
  310. d=2*dy-dx;
  311. }
  312. else
  313. {
  314. mpCase=2;
  315. d=2*dy+dx;
  316. }
  317. incrNE=2*(dy-dx);
  318. incrE=2*dy;
  319. incrSE=2*(dy+dx);
  320. }
  321. else /* vertical scan */
  322. {
  323. dir=DIR_Y;
  324. if (ymax<ymin)
  325. {
  326. SWAP(xmin,xmax);
  327. SWAP(ymin,ymax);
  328. }
  329. dx=xmax-xmin;
  330. dy=ymax-ymin;
  331. if (dx>=0)
  332. {
  333. mpCase=1;
  334. d=2*dx-dy;
  335. }
  336. else
  337. {
  338. mpCase=2;
  339. d=2*dx+dy;
  340. }
  341. incrNE=2*(dx-dy);
  342. incrE=2*dx;
  343. incrSE=2*(dx+dy);
  344. }
  345. /* start the scan */
  346. x=xmin;
  347. y=ymin;
  348. done=0;
  349. while(!done)
  350. {
  351. setPixel(im,x,y,color);
  352. /* move to the next point */
  353. switch(dir)
  354. {
  355. case DIR_X: /* horizontal */
  356. {
  357. if (x<xmax)
  358. {
  359. switch(mpCase)
  360. {
  361. case 1:
  362. if (d<=0)
  363. {
  364. d+=incrE; x++;
  365. }
  366. else
  367. {
  368. d+=incrNE; x++; y++;
  369. }
  370. break;
  371. case 2:
  372. if (d<=0)
  373. {
  374. d+=incrSE; x++; y--;
  375. }
  376. else
  377. {
  378. d+=incrE; x++;
  379. }
  380. break;
  381. } /* mpCase */
  382. } /* x<xmax */
  383. else
  384. done=1;
  385. }
  386. break;
  387. case DIR_Y: /* vertical */
  388. {
  389. if (y<ymax)
  390. {
  391. switch(mpCase)
  392. {
  393. case 1:
  394. if (d<=0)
  395. {
  396. d+=incrE; y++;
  397. }
  398. else
  399. {
  400. d+=incrNE; y++; x++;
  401. }
  402. break;
  403. case 2:
  404. if (d<=0)
  405. {
  406. d+=incrSE; y++; x--;
  407. }
  408. else
  409. {
  410. d+=incrE; y++;
  411. }
  412. break;
  413. } /* mpCase */
  414. } /* y<ymin */
  415. else
  416. done=1;
  417. }
  418. break;
  419. }
  420. }
  421. return 0; /* no error */
  422. }