PageRenderTime 202ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/solucion/src/tp2.c

https://bitbucket.org/a0viedo/orga2tp2
C | 592 lines | 406 code | 152 blank | 34 comment | 111 complexity | 5e07c82fd035c7958da16a9d7d90e229 MD5 | raw file
  1. #include <getopt.h>
  2. #include <highgui.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include "filtros.h"
  8. #include "tiempo.h"
  9. #include "utils.h"
  10. const char* nombre_programa;
  11. void imprimir_ayuda ( );
  12. void imprimir_tiempos_ejecucion(unsigned long long int start, unsigned long long int end, int cant_iteraciones);
  13. void aplicar_recortar (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada, int tam);
  14. void aplicar_colorizar (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada, float alpha);
  15. void aplicar_halftone (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada);
  16. void aplicar_rotar (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada);
  17. void aplicar_umbralizar (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada, unsigned char min, unsigned char max, unsigned char q);
  18. void aplicar_waves (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada, float x_scale, float y_scale, float g_scale);
  19. int main( int argc, char** argv ) {
  20. int siguiente_opcion;
  21. // Opciones
  22. const char* const op_cortas = "hi:vt:";
  23. const struct option op_largas[] = {
  24. { "help", 0, NULL, 'h' },
  25. { "implementacion", 1, NULL, 'i' },
  26. { "verbose", 0, NULL, 'v' },
  27. { "tiempo", 1, NULL, 't' },
  28. { NULL, 0, NULL, 0 }
  29. };
  30. // Parametros
  31. const char* nombre_implementacion = NULL;
  32. int cant_iteraciones = 0;
  33. // Flags de opciones
  34. int verbose = 0;
  35. int tiempo = 0;
  36. // Guardar nombre del programa para usarlo en la ayuda
  37. nombre_programa = argv[0];
  38. // Si se ejecuta sin parametros ni opciones
  39. if (argc == 1) {
  40. imprimir_ayuda ( );
  41. exit ( EXIT_SUCCESS );
  42. }
  43. // Procesar opciones
  44. while (1) {
  45. siguiente_opcion = getopt_long ( argc, argv, op_cortas, op_largas, NULL);
  46. // No hay mas opciones
  47. if ( siguiente_opcion == -1 )
  48. break;
  49. // Procesar opcion
  50. switch ( siguiente_opcion ) {
  51. case 'h' : /* -h o --help */
  52. imprimir_ayuda ( );
  53. exit ( EXIT_SUCCESS );
  54. break;
  55. case 'i' : /* -i o --implementacion */
  56. nombre_implementacion = optarg;
  57. break;
  58. case 't' : /* -t o --tiempo */
  59. tiempo = 1;
  60. cant_iteraciones = atoi ( optarg );
  61. break;
  62. case 'v' : /* -v o --verbose */
  63. verbose = 1;
  64. break;
  65. case '?' : /* opcion no valida */
  66. imprimir_ayuda ( );
  67. exit ( EXIT_SUCCESS );
  68. default : /* opcion no valida */
  69. abort ( );
  70. }
  71. }
  72. // Verifico nombre del proceso
  73. char *nomb_proceso = argv[optind++];
  74. if (nomb_proceso == NULL ||
  75. (strcmp(nomb_proceso, "recortar") != 0 &&
  76. strcmp(nomb_proceso, "colorizar") != 0 &&
  77. strcmp(nomb_proceso, "halftone") != 0 &&
  78. strcmp(nomb_proceso, "rotar") != 0 &&
  79. strcmp(nomb_proceso, "umbralizar") != 0 &&
  80. strcmp(nomb_proceso, "waves") != 0)) {
  81. imprimir_ayuda ( );
  82. exit ( EXIT_SUCCESS );
  83. }
  84. // Verifico nombre de la implementacion
  85. if (nombre_implementacion == NULL ||
  86. (strcmp(nombre_implementacion, "c") != 0 &&
  87. strcmp(nombre_implementacion, "asm") != 0)) {
  88. imprimir_ayuda ( );
  89. exit ( EXIT_SUCCESS );
  90. }
  91. // Verifico nombre de archivo
  92. const char *nomb_arch_entrada = argv[optind++];
  93. if (nomb_arch_entrada == NULL) {
  94. imprimir_ayuda ( );
  95. exit ( EXIT_SUCCESS );
  96. }
  97. if (access( nomb_arch_entrada, F_OK ) == -1) {
  98. printf("Error al intentar abrir el archivo: %s.\n", nomb_arch_entrada);
  99. exit ( EXIT_SUCCESS );
  100. }
  101. // Imprimo info
  102. if ( verbose ) {
  103. printf ( "Procesando imagen...\n");
  104. printf ( " Filtro : %s\n", nomb_proceso);
  105. printf ( " Implementación : %s\n", nombre_implementacion);
  106. printf ( " Archivo de entrada : %s\n", nomb_arch_entrada);
  107. }
  108. // Procesar imagen
  109. if (strcmp(nomb_proceso, "recortar") == 0)
  110. {
  111. int tam = atoi(argv[optind++]);
  112. aplicar_recortar(tiempo, cant_iteraciones, nombre_implementacion,
  113. nomb_arch_entrada, tam);
  114. }
  115. else if (strcmp(nomb_proceso, "colorizar") == 0)
  116. {
  117. float alpha = (float) atof(argv[optind++]);
  118. aplicar_colorizar(tiempo, cant_iteraciones, nombre_implementacion, nomb_arch_entrada, alpha);
  119. }
  120. else if (strcmp(nomb_proceso, "halftone") == 0)
  121. {
  122. aplicar_halftone(tiempo, cant_iteraciones, nombre_implementacion, nomb_arch_entrada);
  123. }
  124. else if (strcmp(nomb_proceso, "rotar") == 0)
  125. {
  126. aplicar_rotar(tiempo, cant_iteraciones, nombre_implementacion, nomb_arch_entrada);
  127. }
  128. else if (strcmp(nomb_proceso, "umbralizar") == 0)
  129. {
  130. int min = atoi(argv[optind++]);
  131. int max = atoi(argv[optind++]);
  132. int q = atoi(argv[optind++]);
  133. aplicar_umbralizar(tiempo, cant_iteraciones, nombre_implementacion,
  134. nomb_arch_entrada, min, max, q);
  135. }
  136. else if (strcmp(nomb_proceso, "waves") == 0)
  137. {
  138. float x_scale = (float) atof(argv[optind++]);
  139. float y_scale = (float) atof(argv[optind++]);
  140. float g_scale = (float) atof(argv[optind++]);
  141. aplicar_waves(tiempo, cant_iteraciones, nombre_implementacion,
  142. nomb_arch_entrada, x_scale, y_scale, g_scale);
  143. }
  144. return 0;
  145. }
  146. void imprimir_ayuda ( ) {
  147. printf ( "Uso: %s opciones filtro nombre_archivo_entrada parametros_filtro \n", nombre_programa );
  148. printf ( " Los filtros que se pueden aplicar son: \n" );
  149. printf ( " * recortar \n" );
  150. printf ( " Parámetros : tamaño \n" );
  151. printf ( " Ejemplo de uso : %s -i c recortar lena.bmp 100 \n", nombre_programa );
  152. printf ( " * colorizar \n" );
  153. printf ( " Parámetros : alpha : [0.0, 1.0] \n" );
  154. printf ( " Ejemplo de uso : %s -i c colorizar lena.bmp 0.5 \n", nombre_programa );
  155. printf ( " * halftone \n" );
  156. printf ( " * rotar \n" );
  157. printf ( " * umbralizar \n" );
  158. printf ( " Parámetros : min : [0, 255] \n" );
  159. printf ( " max : [0, 255] \n" );
  160. printf ( " q : [0, 255] \n" );
  161. printf ( " Ejemplo de uso : %s -i c umbralizar lena.bmp 64 128 16 \n", nombre_programa );
  162. printf ( " * waves \n" );
  163. printf ( " Parámetros : x_scale : [0.0, 32.0] \n" );
  164. printf ( " y_scale : [0.0, 32.0] \n" );
  165. printf ( " g_scale : [0.0, 255.0] \n" );
  166. printf ( " Ejemplo de uso : %s -i c recortar lena.bmp 2.0 4.0 16.0 \n", nombre_programa );
  167. printf ( " \n" );
  168. printf ( " -h, --help Imprime esta ayuda \n" );
  169. printf ( " \n" );
  170. printf ( " -i, --implementacion NOMBRE_MODO Implementación sobre la que se ejecutará el filtro \n" );
  171. printf ( " seleccionado. Los implementaciones disponibles \n" );
  172. printf ( " son: c, asm \n" );
  173. printf ( " \n" );
  174. printf ( " -t, --tiempo CANT_ITERACIONES Mide el tiempo que tarda en ejecutar el filtro sobre la \n" );
  175. printf ( " imagen de entrada una cantidad de veces igual a \n" );
  176. printf ( " CANT_ITERACIONES \n" );
  177. printf ( " \n" );
  178. printf ( " -v, --verbose Imprime información adicional \n" );
  179. printf ( " \n" );
  180. }
  181. void imprimir_tiempos_ejecucion(unsigned long long int start, unsigned long long int end, int cant_iteraciones) {
  182. unsigned long long int cant_ciclos = end-start;
  183. printf("Tiempo de ejecución:\n");
  184. printf(" Comienzo : %llu\n", start);
  185. printf(" Fin : %llu\n", end);
  186. printf(" # iteraciones : %d\n", cant_iteraciones);
  187. printf(" # de ciclos insumidos totales : %llu\n", cant_ciclos);
  188. printf(" # de ciclos insumidos por llamada : %.3f\n", (float)cant_ciclos/(float)cant_iteraciones);
  189. }
  190. void aplicar_recortar (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada, int tam) {
  191. IplImage *src = 0;
  192. IplImage *dst = 0;
  193. CvSize dst_size;
  194. // Cargo la imagen
  195. if( (src = cvLoadImage (nomb_arch_entrada, CV_LOAD_IMAGE_GRAYSCALE)) == 0 )
  196. exit(EXIT_FAILURE);
  197. dst_size.width = tam * 2;
  198. dst_size.height = tam * 2;
  199. // Chequeo de parametros
  200. if (!(tam < src->width || tam < src->height)) {
  201. imprimir_ayuda();
  202. cvReleaseImage(&src);
  203. exit ( EXIT_SUCCESS );
  204. }
  205. // Creo una IplImage para cada salida esperada
  206. if( (dst = cvCreateImage (dst_size, IPL_DEPTH_8U, 1) ) == 0 )
  207. exit(EXIT_FAILURE);
  208. typedef void (recortar_fn_t) (unsigned char*, unsigned char*, int, int, int, int, int);
  209. recortar_fn_t *proceso;
  210. if (strcmp(nomb_impl, "c") == 0) {
  211. proceso = recortar_c;
  212. } else {
  213. proceso = recortar_asm;
  214. }
  215. if (tiempo) {
  216. unsigned long long int start, end;
  217. MEDIR_TIEMPO_START(start);
  218. for(int i=0; i<cant_iteraciones; i++) {
  219. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, dst->widthStep, tam);
  220. }
  221. MEDIR_TIEMPO_STOP(end);
  222. imprimir_tiempos_ejecucion(start, end, cant_iteraciones);
  223. } else {
  224. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, dst->widthStep, tam);
  225. }
  226. // Guardo imagen y libero las imagenes
  227. char nomb_arch_salida[256];
  228. memset(nomb_arch_salida, 0, 256);
  229. sprintf(nomb_arch_salida, "%s.recortar.tam-%d.%s.bmp", nomb_arch_entrada, tam, nomb_impl);
  230. cvSaveImage(nomb_arch_salida, dst, NULL);
  231. cvReleaseImage(&src);
  232. cvReleaseImage(&dst);
  233. }
  234. void aplicar_colorizar (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada, float alpha) {
  235. IplImage *src = 0;
  236. IplImage *dst = 0;
  237. CvSize dst_size;
  238. // Cargo la imagen
  239. if( (src = cvLoadImage (nomb_arch_entrada, CV_LOAD_IMAGE_COLOR)) == 0 )
  240. exit(EXIT_FAILURE);
  241. dst_size.width = src->width;
  242. dst_size.height = src->height;
  243. // Creo una IplImage para cada salida esperada
  244. if( (dst = cvCreateImage (dst_size, IPL_DEPTH_8U, 3) ) == 0 )
  245. exit(EXIT_FAILURE);
  246. typedef void (colorizar_fn_t) (unsigned char*, unsigned char*, int, int, int, int, float);
  247. colorizar_fn_t *proceso;
  248. if (strcmp(nomb_impl, "c") == 0) {
  249. proceso = colorizar_c;
  250. } else {
  251. proceso = colorizar_asm;
  252. }
  253. if (tiempo) {
  254. unsigned long long int start, end;
  255. MEDIR_TIEMPO_START(start);
  256. for(int i=0; i<cant_iteraciones; i++) {
  257. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, dst->widthStep, alpha);
  258. }
  259. MEDIR_TIEMPO_STOP(end);
  260. imprimir_tiempos_ejecucion(start, end, cant_iteraciones);
  261. } else {
  262. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, dst->widthStep, alpha);
  263. }
  264. copiar_bordes_color((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep);
  265. // Guardo imagen y libero las imagenes
  266. char nomb_arch_salida[256];
  267. memset(nomb_arch_salida, 0, 256);
  268. sprintf(nomb_arch_salida, "%s.colorizar.alpha-%3.2f.%s.bmp", nomb_arch_entrada, alpha, nomb_impl);
  269. cvSaveImage(nomb_arch_salida, dst, NULL);
  270. cvReleaseImage(&src);
  271. cvReleaseImage(&dst);
  272. }
  273. void aplicar_halftone (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada) {
  274. IplImage *src = 0;
  275. IplImage *dst = 0;
  276. CvSize dst_size;
  277. // Cargo la imagen
  278. if( (src = cvLoadImage (nomb_arch_entrada, CV_LOAD_IMAGE_GRAYSCALE)) == 0 )
  279. exit(EXIT_FAILURE);
  280. dst_size.width = src->width - src->width % 2;
  281. dst_size.height = src->height - src->height % 2;
  282. // Creo una IplImage para cada salida esperada
  283. if( (dst = cvCreateImage (dst_size, IPL_DEPTH_8U, 1) ) == 0 )
  284. exit(EXIT_FAILURE);
  285. typedef void (halftone_fn_t) (unsigned char*, unsigned char*, int, int, int, int);
  286. halftone_fn_t *proceso;
  287. if (strcmp(nomb_impl, "c") == 0) {
  288. proceso = halftone_c;
  289. } else {
  290. proceso = halftone_asm;
  291. }
  292. if (tiempo) {
  293. unsigned long long int start, end;
  294. MEDIR_TIEMPO_START(start);
  295. for(int i=0; i<cant_iteraciones; i++) {
  296. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, dst->widthStep);
  297. }
  298. MEDIR_TIEMPO_STOP(end);
  299. imprimir_tiempos_ejecucion(start, end, cant_iteraciones);
  300. } else {
  301. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, dst->widthStep);
  302. }
  303. // Guardo imagen y libero las imagenes
  304. char nomb_arch_salida[256];
  305. memset(nomb_arch_salida, 0, 256);
  306. sprintf(nomb_arch_salida, "%s.halftone.%s.bmp", nomb_arch_entrada, nomb_impl);
  307. cvSaveImage(nomb_arch_salida, dst, NULL);
  308. cvReleaseImage(&src);
  309. cvReleaseImage(&dst);
  310. }
  311. void aplicar_rotar (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada) {
  312. IplImage *src = 0;
  313. IplImage *dst = 0;
  314. CvSize dst_size;
  315. // Cargo la imagen
  316. if( (src = cvLoadImage (nomb_arch_entrada, CV_LOAD_IMAGE_GRAYSCALE)) == 0 )
  317. exit(EXIT_FAILURE);
  318. dst_size.width = src->width;
  319. dst_size.height = src->height;
  320. // Creo una IplImage para cada salida esperada
  321. if( (dst = cvCreateImage (dst_size, IPL_DEPTH_8U, 1) ) == 0 )
  322. exit(EXIT_FAILURE);
  323. typedef void (rotar_fn_t) (unsigned char*, unsigned char*, int, int, int, int);
  324. rotar_fn_t *proceso;
  325. if (strcmp(nomb_impl, "c") == 0) {
  326. proceso = rotar_c;
  327. } else {
  328. proceso = rotar_asm;
  329. }
  330. if (tiempo) {
  331. unsigned long long int start, end;
  332. MEDIR_TIEMPO_START(start);
  333. for(int i=0; i<cant_iteraciones; i++) {
  334. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, dst->widthStep);
  335. }
  336. MEDIR_TIEMPO_STOP(end);
  337. imprimir_tiempos_ejecucion(start, end, cant_iteraciones);
  338. } else {
  339. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, dst->widthStep);
  340. }
  341. // Guardo imagen y libero las imagenes
  342. char nomb_arch_salida[256];
  343. memset(nomb_arch_salida, 0, 256);
  344. sprintf(nomb_arch_salida, "%s.rotar.%s.bmp", nomb_arch_entrada, nomb_impl);
  345. cvSaveImage(nomb_arch_salida, dst, NULL);
  346. cvReleaseImage(&src);
  347. cvReleaseImage(&dst);
  348. }
  349. void aplicar_umbralizar (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada, unsigned char min, unsigned char max, unsigned char q) {
  350. IplImage *src = 0;
  351. IplImage *dst = 0;
  352. CvSize dst_size;
  353. // Cargo la imagen
  354. if( (src = cvLoadImage (nomb_arch_entrada, CV_LOAD_IMAGE_GRAYSCALE)) == 0 )
  355. exit(EXIT_FAILURE);
  356. dst_size.width = src->width;
  357. dst_size.height = src->height;
  358. // Creo una IplImage para cada salida esperada
  359. if( (dst = cvCreateImage (dst_size, IPL_DEPTH_8U, 1) ) == 0 )
  360. exit(EXIT_FAILURE);
  361. // Chequeo de parametros
  362. if (!(min <= max && min >= 0 && max <= 255 && q >= 0 && q <= 255)) {
  363. imprimir_ayuda();
  364. cvReleaseImage(&src);
  365. cvReleaseImage(&dst);
  366. exit ( EXIT_SUCCESS );
  367. }
  368. typedef void (umbralizar_fn_t) (unsigned char*, unsigned char*, int, int, int, unsigned char, unsigned char, unsigned char);
  369. umbralizar_fn_t *proceso;
  370. if (strcmp(nomb_impl, "c") == 0) {
  371. proceso = umbralizar_c;
  372. } else {
  373. proceso = umbralizar_asm;
  374. }
  375. if (tiempo) {
  376. unsigned long long int start, end;
  377. MEDIR_TIEMPO_START(start);
  378. for(int i=0; i<cant_iteraciones; i++) {
  379. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, min, max, q);
  380. }
  381. MEDIR_TIEMPO_STOP(end);
  382. imprimir_tiempos_ejecucion(start, end, cant_iteraciones);
  383. } else {
  384. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, min, max, q);
  385. }
  386. // Guardo imagen y libero las imagenes
  387. char nomb_arch_salida[256];
  388. memset(nomb_arch_salida, 0, 256);
  389. sprintf(nomb_arch_salida, "%s.umbralizar.min-%d.max-%d.q-%d.%s.bmp", nomb_arch_entrada, min, max, q, nomb_impl);
  390. cvSaveImage(nomb_arch_salida, dst, NULL);
  391. cvReleaseImage(&src);
  392. cvReleaseImage(&dst);
  393. }
  394. void aplicar_waves (int tiempo, int cant_iteraciones, const char *nomb_impl, const char *nomb_arch_entrada, float x_scale, float y_scale, float g_scale) {
  395. IplImage *src = 0;
  396. IplImage *dst = 0;
  397. CvSize dst_size;
  398. // Cargo la imagen
  399. if( (src = cvLoadImage (nomb_arch_entrada, CV_LOAD_IMAGE_GRAYSCALE)) == 0 )
  400. exit(EXIT_FAILURE);
  401. dst_size.width = src->width;
  402. dst_size.height = src->height;
  403. // Creo una IplImage para cada salida esperada
  404. if( (dst = cvCreateImage (dst_size, IPL_DEPTH_8U, 1) ) == 0 )
  405. exit(EXIT_FAILURE);
  406. // Chequeo de parametros
  407. if (!(x_scale <= 32.0 && x_scale >= 0.0 &&
  408. y_scale <= 32.0 && y_scale >= 0.0 &&
  409. g_scale <= 255.0 && g_scale >= 0.0)) {
  410. imprimir_ayuda();
  411. cvReleaseImage(&src);
  412. cvReleaseImage(&dst);
  413. exit ( EXIT_SUCCESS );
  414. }
  415. typedef void (waves_fn_t) (unsigned char*, unsigned char*, int, int, int, float, float, float);
  416. waves_fn_t *proceso;
  417. if (strcmp(nomb_impl, "c") == 0) {
  418. proceso = waves_c;
  419. } else {
  420. proceso = waves_asm;
  421. }
  422. if (tiempo) {
  423. unsigned long long int start, end;
  424. MEDIR_TIEMPO_START(start);
  425. for(int i=0; i<cant_iteraciones; i++) {
  426. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, x_scale, y_scale, g_scale);
  427. }
  428. MEDIR_TIEMPO_STOP(end);
  429. imprimir_tiempos_ejecucion(start, end, cant_iteraciones);
  430. } else {
  431. proceso((unsigned char*)src->imageData, (unsigned char*)dst->imageData, src->height, src->width, src->widthStep, x_scale, y_scale, g_scale);
  432. }
  433. // Guardo imagen y libero las imagenes
  434. char nomb_arch_salida[256];
  435. memset(nomb_arch_salida, 0, 256);
  436. sprintf(nomb_arch_salida, "%s.waves.x_scale-%3.2f.y_scale-%3.2f.g_scale-%3.2f.%s.bmp", nomb_arch_entrada, x_scale, y_scale, g_scale, nomb_impl);
  437. cvSaveImage(nomb_arch_salida, dst, NULL);
  438. cvReleaseImage(&src);
  439. cvReleaseImage(&dst);
  440. }