/*+-------------------------------------------------------------------------+ | MORFOLOGIA MATEMATICA | | --------------------- | | | | IMAGEM.H | | | | Arquivo que contem as rotinas para ler/gravar imagens em for-| | mato PBM/PGM/PPM ASCII, que nada mais sao do que formatos textos simples| | para imagens binarias, numericas (niveis de cinza) e coloridas respecti-| | vamente. | | | +-------------------------------------------------------------------------+*/ #define TRUE 1 #define FALSE 0 #define CREATOR "# CREATOR: IMAGEM.H - by Luiz Eduardo V:2.00 R: 08/05/97\n" /*+-------------------------------------------------------------------------+ | Rotinas para ALOCAR e DESALOCAR dinamicamente espaco de memoria para um | | vetor monodimensional que armazenara' a imagem. | | PARAMETROS: | | I = Endereco do vetor (ponteiro de inteiros). | | nl = Numero de linhas. | | nc = Numero de colunas. | +-------------------------------------------------------------------------+*/ int aloca_memo (int **I, int nl, int nc) { *I = (int *) malloc (nl * nc * sizeof (int)); if (*I) return TRUE; else return FALSE; } int desaloca_memo (int **I) { free (*I); } /*+-------------------------------------------------------------------------+ | Rotina que faz a leitura de uma imagem em formato .PBM ASCII e armazena | | num vetor monodimensional. Um exemplo de imagem .PBM ASCII gravada neste| | formato: | | | | P1 | | # CREATOR: XV Version 3.10a Rev: 12/29/94 | | 115 81 | | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | | 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | | (...) | | | | Lin 1: contem P1, o que identifica este arquivo como PBM ASCII. | | Lin 2: contem um comentario qualquer iniciado com #. | | Lin 3: numero de colunas e numero de linhas da imagem. | | Lin 4 em diante: pixel's da imagem (0 e 1's) | | | | PARAMETROS: | | nome = nome do arquivo (entra) | | I = ponteiro para o vetor imagem (retorna) | | nl = numero de linhas da imagem. | | nc = numero de colunas da imagem. | +-------------------------------------------------------------------------+*/ int le_imagem_pbm (char *nome, int **I, int *nl, int *nc) { int i, j, k, LIMX, LIMY, MAX_NIVEL; char c, LINHA[100]; FILE *arq; if ((arq = fopen (nome, "r")) == NULL) { printf ("Erro na ABERTURA do arquivo <%s>\n\n", nome); return FALSE; } /*-- PBM = "P1" -----------*/ fgets(LINHA, 80, arq); if (!strstr (LINHA, "P1")) { printf ("Erro no FORMATO do arquivo <%s>\n", nome); printf ("%s\n\n", LINHA); return FALSE; } /*-- Dimensoes da imagem --*/ fgets (LINHA, 80, arq); do { fgets(LINHA, 80, arq); } while (strchr (LINHA, '#')); sscanf (LINHA, "%d %d", &LIMX, &LIMY); if (LIMX == 0 || LIMY == 0) { printf ("Erro nas DIMENSOES do arquivo <%s>\n\n", nome); return FALSE; } if (aloca_memo (I, LIMY, LIMX)) { for (i = 0; i < LIMY; i++) { for (j = 0; j < LIMX; j++) { fscanf (arq, "%d", &k); if (k != 0 && k != 1) { printf ("Erro nos DADOS do arquivo <%s>\n\n", nome); return FALSE; } *(*(I) + i * LIMX + j) = k; } } fclose (arq); } else { printf ("Erro na ALOCACAO DE MEMORIA para o arquivo <%s>\n\n"); printf ("Rotina: le_imagem_pbm\n\n"); fclose (arq); return FALSE; } *nc = LIMX; *nl = LIMY; return TRUE; } /*+-------------------------------------------------------------------------+ | Rotina que grava o arquivo da imagem em formato PBM ASCII. | | PARAMETROS: | | I = ponteiro para o vetor imagem (entra). | | nome = nome do arquivo (entra). | | nl = numero de linhas (entra). | | nc = numero de colunas (entra). | +-------------------------------------------------------------------------+*/ void grava_imagem_pbm (int *I, char *nome, int nl, int nc){ int i, j, x ,k, valores_por_linha; FILE *arq; if ((arq = fopen (nome, "wt")) == NULL) { printf ("Erro na CRIACAO do arquivo <%s>\n\n", nome); } else { fputs ("P1\n", arq); fputs (CREATOR, arq); fprintf (arq, "%d %d\n", nc, nl); valores_por_linha = 36; for (i =0, k=0; i < nl; i++) for (j = 0; j < nc; j++) { x = *(I + i * nc + j); fprintf (arq, "%d ", x); k++; if (k > valores_por_linha) { fprintf (arq, "\n"); k = 0; } } } fclose (arq); } /*+-------------------------------------------------------------------------+ | Rotina que faz a leitura de uma imagem em formato .PGM ASCII e armazena | | num vetor monodimensional. Um exemplo de imagem .PGM ASCII gravada neste| | formato: | | | | P2 | | # CREATOR: XV Version 3.10a Rev: 12/29/94 | | 124 122 | | 255 | | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 | | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 | | (...) | | | | Lin 1: contem P2, o que identifica este arquivo como PGM ASCII. | | Lin 2: contem um comentario qualquer iniciado com #. | | Lin 3: numero de colunas e numero de linhas da imagem. | | Lin 4: maximo nivel de cinza na imagem (255 normalmente). | | Lin 5 em diante: valores de cinza da imagem. | | | | PARAMETROS: | | nome = nome do arquivo (entra). | | I = ponteiro para o vetor imagem (retorna). | | nl = numero de linhas da imagem (retorna). | | nc = numero de colunas da imagem (retorna). | | mn = maximo nivel de cinza (retorna). | +-------------------------------------------------------------------------+*/ int le_imagem_pgm (char *nome, int **I, int *nl, int *nc, int *mn) { int i, j, k, LIMX, LIMY, MAX_NIVEL; char c, LINHA[100]; FILE *arq; if ((arq = fopen (nome, "r")) == NULL) { printf ("Erro na ABERTURA do arquivo <%s>\n\n", nome); return FALSE; } /*-- PGM = "P2" -----------*/ fgets(LINHA, 80, arq); if (!strstr (LINHA, "P2")) { printf ("Erro no FORMATO do arquivo <%s>\n\n", nome); return FALSE; } /*-- Dimensoes da imagem --*/ fgets (LINHA, 80, arq); do { fgets(LINHA, 80, arq); } while (strchr (LINHA, '#')); sscanf (LINHA, "%d %d", &LIMX, &LIMY); fscanf(arq,"%d",&MAX_NIVEL); if (LIMX == 0 || LIMY == 0 || MAX_NIVEL == 0) { printf ("Erro nas DIMENSOES do arquivo <%s>\n\n", nome); return FALSE; } if (aloca_memo (I, LIMY, LIMX)) { for (i = 0; i < LIMY; i++) { for (j = 0; j < LIMX; j++) { fscanf (arq, "%d", &k); if (k > MAX_NIVEL) { printf ("Erro nos DADOS do arquivo <%s>\n", nome); printf ("Valor lido: %d Max Nivel: %d\n\n", k, MAX_NIVEL); return FALSE; } *(*(I) + i * LIMX + j) = k; } } fclose (arq); } else { printf ("Erro na ALOCACAO DE MEMORIA para o arquivo <%s>\n\n"); printf ("Rotina: le_imagem_pgm\n\n"); fclose (arq); return FALSE; } *nc = LIMX; *nl = LIMY; *mn = MAX_NIVEL; return TRUE; } /*+-------------------------------------------------------------------------+ | Rotina que grava o arquivo da imagem em formato PGM ASCII. | | PARAMETROS: | | I = ponteiro para o vetor imagem (entra). | | nome = nome do arquivo (entra). | | nl = numero de linhas (entra). | | nc = numero de colunas (entra). | | mn = maximo nivel de cinza (entra). | +-------------------------------------------------------------------------+*/ void grava_imagem_pgm (int *I, char *nome, int nl, int nc, int mn){ int i, j, x ,k, valores_por_linha; FILE *arq; if ((arq = fopen (nome, "wt")) == NULL) { printf ("Erro na CRIACAO do arquivo <%s>\n\n", nome); } else { fputs ("P2\n", arq); fputs (CREATOR, arq); fprintf (arq, "%d %d\n", nc, nl); fprintf (arq, "%d\n", mn); valores_por_linha = 16; for (i =0, k=0; i < nl; i++) for (j = 0; j < nc; j++) { x = *(I + i * nc + j); fprintf (arq, "%3d ", x); k++; if (k > valores_por_linha) { fprintf (arq, "\n"); k = 0; } } } fclose (arq); } /*+-------------------------------------------------------------------------+ | Rotina que faz a leitura de uma imagem em formato .PPM ASCII e armazena | | em 3 (tres) vetores monodimensionais (cada vetor armazena uma BANDA do | | modelo RGB). Um exemplo de imagem .PPM ASCII gravada neste formato: | | | | P3 | | # CREATOR: XV Version 3.10a Rev: 12/29/94 | | 124 122 | | 255 | | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 | | 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 | | (...) | | | | Lin 1: contem P3, o que identifica este arquivo como PPM ASCII. | | Lin 2: contem um comentario qualquer iniciado com #. | | Lin 3: numero de colunas e numero de linhas da imagem. | | Lin 4: maximo valor em cada banda no modelo RGB. | | Lin 5 em diante: valores de cada banda na ordem Red, Blue e Green. | | | | PARAMETROS: | | nome = nome do arquivo (entra). | | R = ponteiro da banda R (Red) da Imagem (retorna). | | G = ponteiro da banda G (Green) da Imagem (retorna). | | B = ponterio da banda B (Blue) da Imagem (retorna). | | nl = numero de linhas da imagem (retorna). | | nc = numero de colunas da imagem (retorna). | | mn = maximo valor em cada banda (retorna). | +-------------------------------------------------------------------------+*/ int le_imagem_ppm (char *nome, int **R, int **G, int **B, int *nl, int *nc, int *mc) { int i, j, k, banda, OK, LIMX, LIMY, MAX_CORES; char c, LINHA[100]; FILE *arq; if ((arq = fopen (nome, "r")) == NULL) { printf ("Erro na ABERTURA do arquivo <%s>\n\n", nome); return FALSE; } /*-- PPM = "P3" -----------*/ fgets(LINHA, 80, arq); if (!strstr (LINHA, "P3")) { printf ("Erro no FORMATO do arquivo <%s>\n\n", nome); return FALSE; } /*-- Dimensoes da imagem --*/ fgets (LINHA, 80, arq); do { fgets(LINHA, 80, arq); } while (strchr (LINHA, '#')); sscanf (LINHA, "%d %d", &LIMX, &LIMY); fscanf(arq,"%d",&MAX_CORES); if (LIMX == 0 || LIMY == 0 || MAX_CORES == 0) { printf ("Erro nas DIMENSOES do arquivo <%s>\n\n", nome); return FALSE; } banda = 0; OK = aloca_memo (R, LIMY, LIMX); if (OK) aloca_memo (G, LIMY, LIMX); if (OK) aloca_memo (B, LIMY, LIMX); if (OK) { for (i = 0; i < LIMY; i++) { for (j = 0; j < LIMX; j++) { for (banda = 0; banda < 3; banda++) { fscanf (arq, "%d", &k); if (k < 0 || k > MAX_CORES) { printf ("Erro nos DADOS do arquivo <%s>\n\n", nome); return FALSE; } switch (banda) { case 0 : *(*(R) + i * LIMX + j) = k; break; case 1 : *(*(G) + i * LIMX + j) = k; break; case 2 : *(*(B) + i * LIMX + j) = k; break; } } } } fclose (arq); } else { printf ("Erro na ALOCACAO DE MEMORIA para o arquivo <%s>\n\n"); printf ("Rotina: le_imagem_ppm\n\n"); fclose (arq); return FALSE; } *nc = LIMX; *nl = LIMY; *mc = MAX_CORES; return TRUE; } /*+-------------------------------------------------------------------------+ | Rotina que grava o arquivo da imagem em formato PPM ASCII. | | PARAMETROS: | | R = banda R da imagem (entra). | | G = banda G da imagem (entra). | | B = banda B da imagem (entra). | | nome = nome do arquivo (entra). | | nl = numero de linhas (entra). | | nc = numero de colunas (entra). | | mn = maximo nivel de cinza (entra). | +-------------------------------------------------------------------------+*/ void grava_imagem_ppm (int *R, int *G, int *B, char *nome, int nl, int nc, int mn){ int i, j, x ,k, banda, valores_por_linha; FILE *arq; if ((arq = fopen (nome, "wt")) == NULL) { printf ("Erro na criacao do arquivo <%s>\n\n", nome); } else { fputs ("P3\n", arq); fputs (CREATOR, arq); fprintf (arq, "%d %d\n", nc, nl); fprintf (arq, "%d\n", mn); valores_por_linha = 14; banda = 0; for (i =0, k=0; i < nl; i++) for (j = 0; j < nc; j++) { for (banda = 0; banda < 3; banda++) { switch (banda) { case 0: x = *(R+i*nc+j); break; case 1: x = *(G+i*nc+j); break; case 2: x = *(B+i*nc+j); break; } fprintf (arq, "%3d ", x); k++; } if (k > valores_por_linha) { fprintf (arq, "\n"); k = 0; } } } fclose (arq); } /*+-------------------------------------------------------------------------+ | Rotina que faz a leitura de uma imagem em formato .TXT(Texto)e armazena | | num vetor monodimensional. Um exemplo de imagem .TXT gravada neste for- | | to: | | | | TXT | | 10 6 5 | | 1 1 1 1 1 1 1 1 1 1 | | 1 2 2 2 2 1 4 4 4 1 | | 1 2 3 3 2 1 4 5 4 1 | | 1 2 3 3 2 1 4 4 4 1 | | 1 2 2 2 2 1 1 1 1 1 | | 1 1 1 1 1 1 1 1 1 1 | | | | Lin 1: contem TXT, o que identifica este arquivo como TEXTO. | | Lin 2: numero de colunas e numero de linhas da imagem e maximo nivel. | | Lin 4 em diante: valores da imagem. | | | | PARAMETROS: | | nome = nome do arquivo (entra). | | I = ponteiro para o vetor imagem (retorna). | | nl = numero de linhas da imagem (retorna). | | nc = numero de colunas da imagem (retorna). | | mn = maximo nivel de cinza (retorna). | +-------------------------------------------------------------------------+*/ int le_imagem_txt (char *nome, int **I, int *nl, int *nc, int *mn) { int i, j, k, LIMX, LIMY, MAX_NIVEL; char c, LINHA[100]; FILE *arq; if ((arq = fopen (nome, "r")) == NULL) { printf ("Erro na ABERTURA do arquivo <%s>\n\n", nome); return FALSE; } /*-- TXT = "TXT" -----------*/ fgets(LINHA, 80, arq); if (!strstr (LINHA, "TXT")) { printf ("Erro no FORMATO do arquivo <%s>\n\n", nome); return FALSE; } /*-- Dimensoes da imagem --*/ fgets (LINHA, 80, arq); sscanf(LINHA, "%d %d %d", &LIMX, &LIMY, &MAX_NIVEL); if (LIMX == 0 || LIMY == 0 || MAX_NIVEL == 0) { printf ("Erro nas DIMENSOES do arquivo <%s>\n\n", nome); return FALSE; } if (aloca_memo (I, LIMY, LIMX)) { for (i = 0; i < LIMY; i++) { for (j = 0; j < LIMX; j++) { fscanf (arq, "%d", &k); *(*(I) + i * LIMX + j) = k; } } fclose (arq); } else { printf ("Erro na ALOCACAO DE MEMORIA para o arquivo <%s>\n\n"); printf ("Rotina: le_imagem_txt\n\n"); fclose (arq); return FALSE; } *nc = LIMX; *nl = LIMY; *mn = MAX_NIVEL; return TRUE; } /*+-------------------------------------------------------------------------+ | Rotina que grava o arquivo da imagem em formato TEXTO. | | PARAMETROS: | | I = ponteiro para o vetor imagem (entra). | | nome = nome do arquivo (entra). | | nl = numero de linhas (entra). | | nc = numero de colunas (entra). | | mn = maximo nivel de cinza (entra). | +-------------------------------------------------------------------------+*/ void grava_imagem_txt (int *I, char *nome, int nl, int nc, int mn){ int i, j, x ,k, valores_por_linha; FILE *arq; if ((arq = fopen (nome, "wt")) == NULL) { printf ("Erro na criacao do arquivo <%s>\n\n", nome); } else { fputs ("TXT\n", arq); fprintf (arq, "%d %d %d\n", nc, nl, mn); for (i =0; i < nl; i++){ for (j = 0; j < nc; j++) { x = *(I + i * nc + j); fprintf (arq, "%4d ", x); } fprintf (arq, "\n"); } } fclose (arq); } /*+-------------------------------------------------------------------------+ | Apresenta informacoes sobre um arquivo de imagem. | | Parametros: | | nome = nome fisico do arquivo de imagem. | | nl = numero de linhas da imagem. | | nc = numero de colunas da imagem. | | mn = maximo nivel de cinza da imagem. | +-------------------------------------------------------------------------+*/ void info_imagem (char *nome, int nl, int nc, int mn) { printf ("\nINFORMACOES SOBRE A IMAGEM:"); printf ("\n--------------------------\n"); printf ("Nome do arquivo.............: %s \n", nome); printf ("Numero de linhas............: %d \n", nl); printf ("Numero de colunas...........: %d \n", nc); printf ("Maximo nivel-de-cinza/cores.: %d \n\n", mn); }