/* Veja {ex_ini.h}. */ /* Last edited on 2007-11-06 19:07:17 by stolfi */ #include /* PROTÓTIPOS ADICIONAIS: */ void ex_process_images(operation_t op, float_image_t *A, float_image_t *B, float_image_t *R); /* Aplica a operação {op} nas imagens {A} e {B}, colocando o resultado em {R}. */ /* PROGRAMA PRINCIPAL: */ int main(int argc, char** argv) { /* Pega os parâmetros da linha de comando: */ options_t *o = ex_parse_options(argc, argv); /* Lê as duas imagens de entrada {A,B}: */ float_image_t *A = ex_read_image(NULL, o->A_name); float_image_t *B = ex_read_image(NULL, o->B_name); /* Define o tamanho da imagem-resultado: */ int NC = (A->sz[0] < B->sz[0] ? A->sz[0] : B->sz[0]); /* Número de canais */ int NX = (A->sz[1] < B->sz[1] ? A->sz[1] : B->sz[1]); /* Número de colunas */ int NY = (A->sz[2] < B->sz[2] ? A->sz[2] : B->sz[2]); /* Número de linhas */ /* Cria a imagem-resultado {R} na memória: */ float_image_t *R = float_image_new(NC, NX, NY); /* Calcula a imagem-resultado: */ ex_process_images(o->op, A, B, R); /* Escreve a imagem-resultado na saída padrão: */ ex_write_image(stdout, NULL, R); return 0; } /* PROCESSAMENTO DAS IMAGENS: */ void ex_process_images(operation_t op, float_image_t *A, float_image_t *B, float_image_t *R) { /* Pega o tamanho da imagem: */ int NC = R->sz[0]; /* Número de canais */ int NX = R->sz[1]; /* Número de colunas */ int NY = R->sz[2]; /* Número de linhas */ /* Vetor de índices de amostra: */ int iC, iX, iY; for (iC = 0; iC < NC; iC++) for (iX = 0; iX < NX; iX++) for (iY = 0; iY < NY; iY++) { float *pA = float_image_get_sample_address(A, iC, iX, iY); /* Endereço da amostra de {A}. */ float *pB = float_image_get_sample_address(B, iC, iX, iY); /* Endereço da amostra de {B}. */ float *pR = float_image_get_sample_address(R, iC, iX, iY); /* Endereço da amostra de {R}. */ switch (op) { case op_ADD: (*pR) = (*pA) + (*pB); break; case op_MUL: (*pR) = (*pA) * (*pB); break; default: demand(FALSE, "operação inválida"); } } } /* ANÁLISE DA LINHA DE COMANDO: */ options_t *ex_parse_options(int argc, char **argv) { /* INICIALIZA A ANÁLISE: */ /* Cria e incializa o analisador de linha de comando {pp}: */ argparser_t *pp = argparser_new(stderr, argc, argv); argparser_set_help(pp, PROG_NAME " version " PROG_VERS ", usage:\n" PROG_HELP); argparser_set_info(pp, PROG_INFO); /* Processa as opções "-help" e "-info": */ argparser_process_help_info_options(pp); /* Aloca o registro {o} onde os parâmetros serão guardados: */ options_t *o = (options_t *)malloc(sizeof(options_t)); /* PEGA PARÂMETROS COM PALAVRA-CHAVE: */ /* Analiza a opção "-op {OP}": */ argparser_get_keyword(pp, "-op"); { char *op_name = argparser_get_next(pp); if (strcmp(op_name, "add") == 0) { o->op = op_ADD; } else if (strcmp(op_name, "mul") == 0) { o->op = op_MUL; } else { argparser_error(pp, "operação inválida"); } } /* PEGA PARÂMETROS POSICIONAIS: */ /* Pule para o primeiro parâmetro posicional: */ argparser_skip_parsed(pp); /* Pega o nome da imagem {A}: */ if (argparser_next(pp) != NULL) { o->A_name = argparser_get_next(pp); } else { o->A_name = "-"; } /* pega o nome da imagem {B}: */ if (argparser_next(pp) != NULL) { o->B_name = argparser_get_next(pp); } else { o->B_name = "-"; } /* FINALIZA A ANÁLISE: */ /* Verifica se há argumentos sobrando: */ argparser_finish(pp); return o; } /* LEITURA E GRAVACÃO DA IMAGEM */ float_image_t *ex_read_image(FILE *rd, char *name) { bool_t close_it = FALSE; if (rd == NULL) { rd = open_read(name, TRUE); close_it = TRUE; } pnm_image_t *pim = pnm_image_fread(rd); float_image_t *fim = float_image_from_pnm_image(pim, NULL, NULL, TRUE); pnm_image_free(pim); if (close_it) { fclose(rd); } return fim; } void ex_write_image(FILE *wr, char *name, float_image_t *img) { bool_t close_it = FALSE; if (wr == NULL) { wr = open_write(name, TRUE); close_it = TRUE; } int chns = img->sz[0]; pnm_image_t *pim = float_image_to_pnm_image(img, chns, NULL, NULL, NULL, 255, TRUE); pnm_image_fwrite(wr, pim, FALSE); if (close_it) { fclose(wr); } pnm_image_free(pim); }