• Nenhum resultado encontrado

Capítulo 7

CONCLUSÕES E SUGESTÕES

7.1 Conclusões

• O padrão JBIG é uma técnica de compressão de dados, com enfoque especial direcionado à codificação aritmética binária adaptativa. O JBIG foi estabelecido principalmente para codificação sem perdas de imagem em 2 níveis. Neste trabalho analisa-se o padrão, sendo que ele apresenta como vantagem a possibilidade de escolha da qualidade da imagem que está sendo codificada através do número das camadas de resolução D.

• O método de codificação aritmética binária adaptativa é uma codificação entrópica que utiliza a estatística dos pixels. A codificação aritmética é uma das famílias de códigos que compartilha da propriedade de tratar uma cadeia de bits como uma magnitude.

• Devido à flexibilidade da codificação aritmética, os códigos podem ser obtidos durante o processo de codificação, enquanto em outras técnicas, tais como Huffman, os códigos são obtidos antes do processo de codificação. A codificação aritmética tem capacidade de receber pixels com distribuição estatísticas diferentes e gerar os códigos que afetam diretamente as probabilidades, podendo assim

adaptar os códigos de acordo com a mudança da estatística. Ela representa a seqüência de pixels codificada com uma única palavra código.

• As equações (4.2) e (4.3) apresentam o problema de precisão que provoca a propagação do “carry-over” dentro dos códigos. O algoritmo da codificação aritmética binária adaptativa tem capacidade de usar uma precisão fixa para controle do tamanho do código, limitando o crescimento dos dígitos nos códigos através do processo de renormalização.

• O mecanismo de adaptação de codificação aritmética binária dedica-se à determinação do novo estado de estimação de probabilidade Pe do contexto atual

para se codificar o próximo pixel.

• O estudo mostra que o padrão JBIG permite codificar primeiro a imagem de baixa resolução e depois enriquecê-la com imagens de mais altas resoluções. Também se permite ao usuário interromper o processo de codificação se desejado.

• O JBIG usa um método recursivo para implementação de códigos aritméticos para compactação de dados, sem nenhuma multiplicação ou divisão, de forma a se obter uma implementação de “hardware” fácil e rápida, o que é explicado no trabalho de Kuang, Jou e Chen [25].

• A implementação do algoritmo de codificação aritmética binária adaptativa evita a operação de multiplicação através do uso de deslocamento de bits. Tal fato faz com que os valores dos registradores A e C (o tamanho e a base do intervalo) sejam frações binárias. Isso permite o deslocamento para a esquerda dos bits contidos nos registradores A e C.

Capítulo 7 - Conclusões e Sugestões 117

• A eficiência do método de compressão de dados usado refere-se à redução de tamanho de dados transmitidos ou armazenados, à redução de custo e à diminuição de tempo de transmissão.

• A estrutura do modelo e a estatística dos pixels (probabilidades relativas) compartilham a eficiência da técnica de compressão. As simulações mostram que a estrutura de 3 linhas oferecida pelo padrão JBIG dá melhor resultado do que aquela de 2 linhas.

• A escolha do método de compressão é dependente das características e das aplicações dos dados. A imagem que contem dados de características semelhantes é boa candidata para compressão de dados, em outras palavras, nesse caso, a taxa de compressão ou o fator de compressão é alto.

7.2 Contribuições

• Com a idéia de se dividir a imagem de entrada em vários planos de bits, e tratar cada plano como se fosse uma imagem de 2 níveis, consegue-se implementar um caso especial de codificação para a imagem de escala de cinzas, aplicando-se o modo seqüencial progressivo-único com o objetivo de melhorar o desempenho do sistema. Esse procedimento serve para algumas aplicações que não exigem a reprodução de muitos detalhes na imagem de saída. A menor camada de resolução em cada plano de bits é codificada e transmitida ou armazenada. Quando o número de camadas de resolução (D) aumenta, isso resulta numa melhora da taxa de compressão, pois a imagem terá menos detalhes, conforme a plataforma de “software” apresentado no apêndice B.

• Também, através do uso do método progressivo que faz parte do padrão JBIG, implementou-se uma plataforma de “software” para imagem com escala de cinzas usando-se o modo seqüencial compatível-progressivo como procedimento usual do padrão JBIG. O número de camadas de resolução D e a habilitação do processo de predição típica TP correspondem aos parâmetros que podem ser escolhidos como opções de entrada pelo usuário.

• Neste trabalho, consegue-se alcançar uma melhoria na taxa de compressão usando-se uma nova proposta que é comparada ao algoritmo de procedimento usual do padrão JBIG. A proposta é transferir o sub-bloco Redutor de Resolução (Hierarquia) do codificador para o decodificador, ou seja, o processo de redução de resolução (modo progressivo) foi aplicado na decodificação ao invés de aplicá-lo na codificação [Apêndice B]. Nesse caso, a divisão da imagem em camadas de resolução é feita no decodificador. A imagem de entrada é dividida em 8 planos de bits, pois tem-se 8 bits por pixel, portanto, cada bit representa um plano de bits. • Testa-se também imagens coloridas. Cada amostra têm 3 bytes de 8 bits. O primeiro

byte corresponde ao componente vermelho R (“Red”), o segundo byte ao componente verde G (“Green”) e o terceiro byte ao componente azul B (“Blue”). Vários métodos podem ser usados para se trabalhar com as amostras desse tipo de imagem. Nesta pesquisa, trabalha-se com bytes independentes das amostras, ou seja, os componentes não são separados em matrizes distintas, mas são tratados seqüencialmente nessa ordem: R, G e B. A largura da imagem colorida é multiplicada por 3 e cada byte é dividido em 8 planos de bits independente da sua

Capítulo 7 - Conclusões e Sugestões 119

cor. A simulação em “software” foi implementada para o algoritmo de codificação do procedimento usual do padrão JBIG.

• A presente proposta, também, foi aplicada em imagens coloridas e a plataforma de “software” foi implementada [Apêndice B]. Consegue-se alcançar uma melhoria no desempenho do sistema de codificação quando os resultados obtidos são comparados com aqueles correspondentes ao algoritmo de procedimento usual do padrão JBIG.

• A função do sub-bloco Predição Típica é a agilização do processo de codificação mais do que a busca de alguma melhoria no desempenho. Durante a simulação, executa-se os programas de codificação e avalia-se o efeito do processo de predição típica. Tanto para as imagens com escala de cinzas quanto para as imagens coloridas, o algoritmo de codificação não mostra nenhuma melhoria na taxa de compressão, ou seja, a predição típica é usada somente para se agilizar o processo de codificação.

• Implementou-se a plataforma de “software” usando-se a Linguagem C de programação a fim de se realizar as simulações do algoritmo de codificação do padrão JBIG. O objetivo foi o de testar e avaliar o desempenho da presente proposta comparando-se os resultados com aqueles obtidos através do procedimento usual do JBIG. Três plataformas estão no apêndice B, sendo elas:

1- A primeira para se realizar a codificação da menor camada de resolução de imagem com escala de cinzas.

2- A segunda para se realizar a codificação com o método progressivo de imagem com escala de cinzas com a nova proposta.

3- A terceira para se realizar a codificação com o método progressivo de imagem colorida com a nova proposta.

7.3 Sugestões

• Implementar os sub-blocos de Predição Determinística PD e Template Adaptativo TA.

• Desenvolver a técnica de codificação do padrão JBIG para a codificação com perdas.

• Utilizar juntamente com a codificação com perdas, uma filtragem para se alcançar uma melhoria do desempenho.

• O padrão pode ser estendido com o intuito de se construírem técnicas mais amplas, que possam ser aplicadas na transmissão digital de sinais de forma genérica. Por exemplo, pode-se utilizar a codificação com o método progressivo do padrão JBIG com e sem perdas para os sinais de Televisão Convencional e de Alta Definição. • Pode-se projetar uma aplicação com uma base de dados que pode servir

dispositivos de saídas com capacidades de resolução diferentes, isto é, somente aquela porção do arquivo da imagem compactada necessária para a reconstrução (de acordo com a capacidade de resolução do dispositivo de saída particular) tem que ser enviada e decodificada.

Apêndice A 121

Apêndice A1

Tabela para se determinar a Cor da Camada de Baixa Resolução

Índice Cor [0, 63] 00010001 01110011 11111111 11111111 00110011 11111111 11111111 11111111 [64, 127] 00000001 01110111 11111111 11111111 00110111 11111111 11111111 11111111 [128, 191] 00110111 11111111 11111111 11111111 01111101 11111111 11111111 11111111 [192, 255] 00110111 11111111 11111111 11111111 11111111 01111101 11111111 11111111 [256, 319] 00000001 00110111 11111101 11111111 00111111 11111111 11111111 11111111 [320, 383] 00110111 01111111 11111111 01111111 01111111 01111111 01111111 11111111 [384, 447] 00110101 11111111 11110111 11111111 11011111 01111111 11111111 11111111 [448, 511] 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [512, 575] 00000001 00100011 00000101 00111011 00010001 00100011 01110001 11111111 [576, 639] 00000001 01110101 00111011 01111111 00000000 01010011 11111110 11111111 [640, 703] 00000001 01000001 01111111 11111111 00001001 10110111 11111111 11111111 [704, 767] 00000000 01010011 01111111 11111011 10010011 01111001 11111111 11111111 [768, 831] 00000001 00000000 01110011 11111111 00110001 00010011 01110101 11111111 [832, 895] 00000000 01000001 10110111 11101110 00000001 00100001 11111100 11111111 [896, 959] 00000000 10010011 01110101 11111111 00010001 01101011 11110101 11111111 [960, 1023] 11101001 11110111 11111111 11111011 10110111 11111111 11111011 11111111 [1024, 1087] 00000001 00100011 00000001 00111111 00010001 00000001 01110111 11111111 [1088, 1151] 00000001 01110101 01101011 01111111 00000000 01010011 11111110 11111111 [1152, 1215] 00000001 01100001 01111111 11111111 00101001 00110111 11111111 11111111 [1216, 1279] 00000000 01110011 00111111 01111011 10010010 01111101 11111111 11111111 [1280, 1343] 00000001 00000000 01111011 11111110 00101111 00011011 01111111 11111111 [1344, 1407] 00000000 01000001 00110111 11111110 00001001 00110111 01111110 01111111 [1408, 1471] 00000000 11010010 01111111 11111111 00011011 01101111 11111111 11111111 [1472, 1535] 00000000 01110101 01111111 01110111 00100111 01111111 01111011 01111111 [1536, 1599] 00000001 00000011 00000001 00001001 00010001 00000001 01000001 10010011 [1600, 1663] 00000001 01110101 00100001 01010101 00000000 01010001 10000000 11110111 [1664, 1727] 00000001 01000001 01101011 00010011 00000001 00000000 11111011 11111111 [1728, 1791] 00000000 01010001 00000001 01110011 00000000 01000001 10110111 11111111 [1792, 1855] [1856, 1919] 00000001 00000000 00000000 01000000 01100001 00000001 10000001 01010110 00100111 00001000 00001001 00000000 00011110 00010000 10111111 01111111 [1920, 1983] 00000000 10000000 00100001 01110111 00000011 00000001 00111111 11111111 [1984, 2047] 01101000 11010000 11110011 10110011 00000000 11010011 11111011 11111111 [2048, 2111] 00000001 00000011 00110111 11111111 00110011 00110111 01111111 11111111 [2112, 2175] 00000001 01110111 01111111 11111111 00010001 01111011 11111111 11111111 [2176, 2239] 00000001 11110111 01111111 11111111 00111111 11111111 11111101 11111111 [2240, 2303] 00010010 11110111 11111111 11111111 11111111 11111101 11111111 01111111 [2304, 2367] 00000001 00010010 01111101 11111111 00111111 01111111 11111111 11111111 [2368, 2431] 00000000 01100010 11111111 01111111 00111111 00111111 01111111 11111111 [2432, 2495] 00010000 11111111 11110111 11111111 01111111 11111111 01111111 11111111 [2496, 2559] 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 [2560, 2623] 00000001 00100011 00000001 00011011 00010001 00100011 01110111 11111111 [2624, 2687] 00000001 01110101 00101011 01110111 00000000 01000001 10111110 11111111 [2688, 2751] 00000001 11000001 01011011 01111111 00001001 00110011 01111101 11111111 [2752, 2815] 00000000 01010001 00110111 11111011 10101001 10110001 11111111 11111111 [2816, 2879] 00000001 00000000 01110001 10110111 00100001 00000011 01110101 11111111 [2880, 2943] 00000000 01000000 00010111 01101111 00000000 00000001 01111101 11111111 [2944, 3007] 00000000 11000001 01110101 11111111 00000001 10101011 01010001 11111111 [3008, 3071] 11101000 11010011 11111111 11111011 10111011 11111111 11111011 11111111 [3072, 3135] 00000001 00100011 00000001 00011011 00110001 00000001 01010011 01111111 [3136, 3199] 00000001 01110101 00101001 01111111 00000000 01010001 10110110 11111111 [3200, 3263] 00000001 11100000 01111011 11111111 00001010 00111011 01111111 11111111 [3264, 3327] 00000000 01110001 01111111 11111011 10001000 01110101 11111111 01111111 [3328, 3391] 00000001 00000000 01100001 11110110 00111111 00001001 01111111 11111111 [3392, 3455] 00000000 01000000 00010111 01111111 00001000 00010011 01111110 01111111 [3456, 3519] 00000000 10000000 01110111 11111111 00101011 00101111 01111111 01111111 [3520, 3583] 00000000 01110001 01111111 01110111 00101011 01111111 00111011 01111111 [3584, 3647] 00000001 00000011 00000001 00001001 00010001 00000001 01000001 00000001 [3648, 3711] 00000001 01110101 00100001 01010101 00000000 01010001 10000000 01010011 [3712, 3775] 00000001 01000001 01001001 00000001 00001001 00000000 00000001 00010011 [3776, 3839] 00000000 01010001 00000000 01010011 10000000 01000001 00010011 01111111 [3840, 3903] 00000001 00000000 01100001 10000000 00100001 00000001 00000001 00010011 [3904, 3967] 00000000 01000000 00000000 01000000 00000000 00000000 00000000 00010011 [3968, 4031] 00000000 10000000 00000000 00010011 00000001 00000001 01010001 01111111 [4032, 4095] 00000000 01010000 00000000 01110011 00000001 01010100 00110001 01110111

Tabela de Estimação de Probabilidade

ST LSZ NMPS NLPS SWTCH ST LSZ NMPS NLPS SWTCH 0 0x5a1d 1 1 1 56 0x01f8 57 54 0 1 0x2586 2 14 0 57 0x01a4 58 55 0 2 0x1114 3 16 0 58 0x0160 59 56 0 3 0x080b 4 18 0 59 0x0125 60 57 0 4 0x03d8 5 20 0 60 0x00f6 61 58 0 5 0x01da 6 23 0 61 0x00cb 62 59 0 6 0x00e5 7 25 0 62 0x00ab 63 61 0 7 0x006f 8 28 0 63 0x008f 32 61 0 8 0x0036 9 30 0 64 0x5b12 65 65 1 9 0x001a 10 33 0 65 0x4d04 66 80 0 10 0x000d 11 35 0 66 0x412c 67 81 0 11 0x0006 12 9 0 67 0x37d8 68 82 0 12 0x0003 13 10 0 68 0x2fe8 69 83 0 13 0x0001 13 12 0 69 0x293c 70 84 0 14 0x5a7f 15 15 1 70 0x2379 71 86 0 15 0x3f25 16 36 0 71 0x1edf 72 87 0 16 0x2cf2 17 38 0 72 0x1aa9 73 87 0 17 0x207c 18 39 0 73 0x174e 74 72 0 18 0x17b9 19 40 0 74 0x1424 75 72 0 19 0x1182 20 42 0 75 0x119c 76 74 0 20 0x0cef 21 43 0 76 0x0f6b 77 74 0 21 0x09a1 22 45 0 77 0x0d51 78 75 0 22 0x072f 23 46 0 78 0x0bb6 79 77 0 23 0x055c 24 48 0 79 0x0a40 48 77 0 24 0x0406 25 49 0 80 0x5832 81 80 1 25 0x0303 26 51 0 81 0x4d1c 82 88 0 26 0x0240 27 52 0 82 0x438e 83 89 0 27 0x01b1 28 54 0 83 0x3bdd 84 90 0 28 0x0144 29 56 0 84 0x34ee 85 91 0 29 0x00f5 30 57 0 85 0x2eae 86 92 0 30 0x00b7 31 59 0 86 0x299a 87 93 0 31 0x008a 32 60 0 87 0x2516 71 86 0 32 0x0068 33 62 0 88 0x5570 89 88 1 33 0x004e 34 63 0 89 0x4ca9 90 95 0 34 0x003b 35 32 0 90 0x44d9 91 96 0 35 0x002c 9 33 0 91 0x3e22 92 97 0 36 0x5ae1 37 37 1 92 0x3824 93 99 0 37 0x484c 38 64 0 93 0x32b4 94 99 0 38 0x3a0d 39 65 0 94 0x2e17 86 93 0 39 0x2ef1 40 67 0 95 0x56a8 96 95 1 40 0x261f 41 68 0 96 0x4f46 97 101 0 41 0x1f33 42 69 0 97 0x47e5 98 102 0 42 0x19a8 43 70 0 98 0x41cf 99 103 0 43 0x1518 44 72 0 99 0x3c3d 100 104 0 44 0x1177 45 73 0 100 0x375e 93 99 0 45 0x0e74 46 74 0 101 0x5231 102 105 0 46 0x0bfb 47 75 0 102 0x4c0f 103 106 0 47 0x09f8 48 77 0 103 0x4639 104 107 0 48 0x0861 49 78 0 104 0x415e 99 103 0 49 0x0706 50 79 0 105 0x5627 106 105 1 50 0x05cd 51 48 0 106 0x50e7 107 108 0 51 0x04dc 52 50 0 107 0x4b85 103 109 0 52 0x040f 53 50 0 108 0x5597 109 110 0 53 0x0363 54 51 0 109 0x504f 107 111 0 54 0x02d4 55 52 0 110 0x5a10 111 110 1 55 0x025c 56 53 0 111 0x5522 109 112 0 112 0x59eb 111 112 1

Apêndice B 123

Apêndice B

1- Programas de codificação e decodificação da menor camada de resolução.

/* --- Utilizando imagem (escala de cinzas) de formato ROW tipo PGM codificando --- */ /* --- somente a menor camada de resolução para qualquer D de cada plano de bits --- */ /* --- com a opção de usar o processo de Predição Típica --- */

#include <ctype.h> #include <stdio.h> #include <assert.h> #include <stdlib.h> #include "tabela.h" #define ESC 0XFF #define STUFF 0X00 #define DTRST 0X03 #define DTNORM 0X02 #define PTB2CX 0X195 #define PTB3CX 0X0E5

/* --- Descricao "status" de codificador aritmetico --- */ struct code_estado

{

unsigned char ST[4096]; /* "status" de prob. dos contextos, e MSB = MPS */ unsigned int C; /* registrador C, base de intervalo codificado */ int A; /* registrador A tamanho normalizado de intervalo */ int SC; /* contador de pilha */

int CT; /* contador dislocamento de bits, determina quando * proximo byte vai ser armazenado ou transmitido */ int BUF; /* buffer para armazenar recente byte da saida != 0xff */ };

void BYTEOUT (int BUF, FILE *PCT) {

putc (BUF, PCT); return;

};

void FIMC (struct code_estado *s, FILE *PCT) {

int TEMP;

/** procura no intervalo codificado s->c com maior numeros de bits zero **/ if ((TEMP = (s->A - 1 + s->C) & 0xffff0000) < s->C)

s->C = TEMP;

/* --- envia o resto de bytes para o arquivo de sai'da --- */ s->C <<= s->CT;

if (s->C > 0x7ffffff)

{ /* um overflow final vai acontecer */ if (s->BUF >= 0) { BYTEOUT (s->BUF + 1, PCT); if (s->BUF + 1 == ESC) BYTEOUT (STUFF, PCT); } if (s->C & 0x7fff800) for (; s->SC; --s->SC) BYTEOUT (0x00, PCT); } else { if (s->BUF >= 0) BYTEOUT (s->BUF, PCT); for (; s->SC; --s->SC) { BYTEOUT (0xff, PCT); BYTEOUT (STUFF, PCT); } }

/* --- envia os bytes finais somente se nao sao 0x00 --- */ if (s->C & 0x7fff800) { BYTEOUT ((s->C >> 19) & 0xff, PCT); if (((s->C >> 19) & 0xff) == ESC) BYTEOUT (STUFF, PCT); if (s->C & 0x7f800) { BYTEOUT ((s->C >> 11) & 0xff, PCT); if (((s->C >> 11) & 0xff) == ESC) BYTEOUT (STUFF, PCT); } } return; }

void CODIF (struct code_estado *s, unsigned int CX, unsigned int PIX, FILE *PCT) {

int TEMP; register int lsz, ss; extern short LSZ[];

extern char NLPS[], NMPS[], SWTCH[];

Apêndice B 125 ss = s->ST[CX] & 0x7f; /* para capturar somente primeiros 7 bits */

assert (ss >= 0 && ss < 113); /* determine LSZ[ST[CX]] */ lsz = LSZ[ss];

if (((PIX << 7) ^ s->ST[CX]) & 0x80) /* PIX != MPS[CX] */ {

/* --- codifica o simbolo de menor ocorrencia LPS --- */ if ((s->A -= lsz) >= lsz) /* se intervalo de MPS >= LPS */ { s->C += s->A; s->A = lsz; } if (SWTCH[ss]) s->ST[CX] ^= 0x80; /* MSB ===> MPS[CX]=1-MPS[CX] * * XOR se A = B, entao A XOR @ B = 0 */

s->ST[CX] &= 0x80; /* mantem somente o valor de MPS=MSB */ s->ST[CX] |= NLPS[ss];

} else

{ /* --- Codificar o simbolo de maior ocorrencia MPS --- */ if ((s->A -= lsz) >= 0x8000)

return; /*--- se A >= 0x8000, nao precisa renormalizacao ---*/ if (s->A < lsz) { s->C += s->A; s->A = lsz; } s->ST[CX] &= 0x80; s->ST[CX] |= NMPS[ss]; }

do /* --- renormalizacao de intervalo codificado --- */ {

s->A <<= 1; s->C <<= 1; --s->CT;

if (s->CT == 0) /* outro byte pronto p/ envia-lo p/ arquivo da saida */ {

TEMP = s->C >> 19; /* TEMP = um byte (com o carry) de reg. C */ if (TEMP > 0xff) /* --- contiudo de BUF --- */

{ /* --- ocorre overflow --- */ if (s->BUF >= 0) { ++s->BUF; BYTEOUT (s->BUF, PCT); if (s->BUF == ESC) BYTEOUT (STUFF, PCT); } for (; s->SC; --s->SC) /* no final SC = 0 */ BYTEOUT (0x00, PCT);

s->BUF = TEMP & 0xff;/*novo byte p/ enviar,talvez ocorrera overflow*/ assert (s->BUF != 0xff);

if (TEMP == 0xff) /* talvez ocorrera overflow */ ++s->SC;

else

{ /* nao ocorrera overflow */ if (s->BUF >= 0) BYTEOUT (s->BUF, PCT); for (; s->SC; --s->SC) /* no final SC = 0 */ { BYTEOUT (0xff, PCT); BYTEOUT (STUFF, PCT); }

s->BUF = TEMP; /* buffer p/ novo byte enviado */ } s->C &= 0x7ffff; s->CT = 8; } } while (s->A < 0x8000); return; }

void COD5 (struct code_estado *s, unsigned char *Res_bit, unsigned int largura, unsigned int altura, unsigned int alta_byte, unsigned int baixa_byte, unsigned int liga, unsigned int PT, FILE *PCT) {

unsigned char *lp1, *lp2, *p1, *q1;

unsigned int lpt, lpt_antiga, CX_CBR, SLNPT, PTDON, PTBON; unsigned int cx, PIX, i, j, fase1, fase2, baixa_altura, baixa_largura; unsigned int linha_h1,linha_h2,linha_h3,linha_l1,linha_l2,linha_l3; cx = 0; PIX = 0; lpt_antiga = 0; PTBON = PTDON = PT; baixa_altura = (altura +1)/2; baixa_largura = (largura +1)/2; lp2 = Res_bit; lp1 = lp2 + baixa_byte; for (i = 0; i < altura; i++) {

/* ============ Predição Tipical Para Menor Camada ============ */ if (PTBON == 1) { p1 = lp2; if (i > 0) { q1 = lp2 - baixa_byte; while (q1 < lp2 && (lpt = (*p1++ == *q1++)) != 0); }

else /* a primeira linha */

while (p1 < lp2 + baixa_byte && (lpt = (*p1++ == 0)) != 0); if (liga == 2)

Apêndice B 127 else CX_CBR = 0; SLNPT = !(lpt ^ lpt_antiga); CODIF (s, CX_CBR ? PTB2CX : PTB3CX, SLNPT, PCT); lpt_antiga = lpt; /** CX_CBR = PTB3CX caso CX_CBR = 0 **/ if (lpt)

{ /** Pular para próxima linha pois as duas linhas sao iquais **/ lp2 += baixa_byte; /** area solida **/

continue; /** vai ate o final do loop for (i= ....) **/ }

} /* if PTBON */

linha_h1 = linha_h2 = linha_h3 = 0; if (i > 0)

{

linha_h2 = (unsigned int) *(lp2 - baixa_byte) << 8; if (i > 1 && liga == 3)

linha_h3 = (unsigned int) *(lp2 - baixa_byte - baixa_byte) << 8; } for (j = 0; j < largura; lp2++) { linha_h1 |= *lp2; if ((j < (baixa_byte * 8 - 8)) && (i > 0)) { linha_h2 |= *(lp2 - baixa_byte + 1); if (i > 1 && liga == 3)

linha_h3 |= *(lp2 - baixa_byte - baixa_byte + 1); }

do {

linha_h1 <<= 1; linha_h2 <<= 1; linha_h3 <<= 1; switch (liga)

{ case 2:

cx = (((linha_h1 >> 9) & 0x00f) + ((linha_h2 >> 10) & 0x3f0)); break;

case 3:

cx = (((linha_h1 >> 9) & 0x003) + ((linha_h2 >> 12) & 0x07c) + ((linha_h3 >> 8) & 0x380));

break; default:

fprintf (stderr,"Tipo de Template -%d- errado!\n" ,liga); exit(1);

}

PIX = ((linha_h1 >> 8) & 1); CODIF (s, cx, PIX, PCT); cx = 0;

} while (++j & 7 && j < largura); }

} /* i */ return; }

/* --- Reservando uma area com valores zeros nela --- */ {

unsigned int tamanho; unsigned char *ptr_p; tamanho = byte * altura;

ptr_p = (unsigned char *) calloc(tamanho, sizeof(unsigned char)); if (!ptr_p)

{

fprintf (stderr, "Nao tem memoria suficiente para os pixels!\n"); exit(1);

}

return (ptr_p); }

unsigned int TAMANHO (unsigned int largura) {

unsigned int tamanho, MOD;

/* --- No. de pixels por linha --- */ MOD = largura % 8;

if (MOD)

tamanho = largura + (8 - MOD); else

tamanho = largura; return (tamanho);

}

unsigned int TAM_IN_BYTE (unsigned int largura) {

unsigned int byte, tamanho_largura; /* --- No. de bytes por linha --- */ tamanho_largura = TAMANHO (largura); byte = tamanho_largura / 8;

return (byte); }

unsigned int x[20];

void REDUZIR (unsigned char **bit, unsigned char *b, unsigned int D, unsigned int nova_lar, unsigned int altura)

{

extern char Map[];

unsigned char *Meio, *F, *Pr, *P_baixa;

unsigned int cnt, chave, ca, i, j, Resultado, cont_a, cont_b;

unsigned short linha_F, linha_Meio, linha_Pr, linha_baixa2, baixa_pix;

Apêndice B 129 cnt = 0;

chave = 1;

for (ca = 1; ca < D; ca++) { if (chave != 0) { x[cnt] = nova_lar; cnt += 1; x[cnt] = altura;

alta_byte = TAM_IN_BYTE (nova_lar); bit[ca-1] = b; chave = 0; } Meio = bit[ca-1]; F = Meio - alta_byte; Pr = Meio + alta_byte; baixa_nova_lar = (nova_lar + 1)/2; baixa_altura = (altura + 1)/2; cnt += 1; x[cnt] = baixa_nova_lar; cnt += 1; x[cnt] = baixa_altura;

baixa_L_tamanho = TAMANHO (baixa_nova_lar); baixa_byte = baixa_L_tamanho / 8;

bit[ca] = reserva_char (baixa_byte, baixa_altura); P_baixa = bit[ca];

/* ---- Ponha-se os pixels da camada de baixa Resolucao a partir ---- */ /* ---- de mesma e de camada de alta Resolucao --- */ for (i = 0; i < baixa_altura; i++)

{

if (2 * i + 1 >= altura)

Pr = Meio; /* -- para repetir ultima linha da imagem no final -- */ baixa_pix = 0;

linha_F = linha_Meio = linha_Pr = linha_baixa2 = 0; for (j = 0; j < baixa_L_tamanho; j += 8)

{

*P_baixa = 0;

linha_baixa2 |= i ? *(P_baixa - baixa_byte) : 0;

/* --- linha_baixa2 = 0 caso i=0, e caso contrario pega --- */ /* --- o byte que esta a cima do byte atual do P_baixa --- */

for (cont_b=0; cont_b < 8 && j+cont_b < baixa_nova_lar; cont_b += 4) {

if (((j + cont_b) >> 2) < alta_byte) {

/* --- p/ evitar passar o limite de bytes na alta Res. --- */ linha_F |= i ? *F : 0; ++F;

linha_Meio |= *Meio; ++Meio; linha_Pr |= *Pr; ++Pr; }

linha_Pr <<= 2; linha_Meio <<= 2; linha_F <<= 2; linha_baixa2 <<= 1; Resultado = 0;

Resultado = (((linha_Pr>>8) & 0x0007)+((linha_Meio>>5)& 0x0038) + ((linha_F >> 2) & 0x01c0) + (baixa_pix << 9)

+ ((linha_baixa2 << 2) & 0x0c00)); assert (Resultado >= 0 && Resultado < 4096); baixa_pix = 0;

baixa_pix = Map[Resultado]; *P_baixa <<= 1;

*P_baixa |= (unsigned char) baixa_pix; /** P_baixa e linha atual na baixa Res. **/

} /* --- baixa_pix e linha a cima do pixel ? estimado --- */ }

++P_baixa; } /* j */

/* --- inserir bits de valores zeros no final de cada linha --- */ /* --- ate atengir ao tamanho de baixa_L_tamanho --- */

*(P_baixa - 1) <<= baixa_L_tamanho - baixa_nova_lar;/** recua P_baixa */ F += alta_byte; /* para um byte ai colocand 0's nas digitos de byte */ Meio += alta_byte;

Pr += alta_byte; /* pula 1 line p/ repetir o processo na 3 e 4 linha */ } /* i */ nova_lar = baixa_nova_lar; altura = baixa_altura; alta_byte = baixa_byte; } /* ca */ return; }

void DIVIDE (struct code_estado *s, unsigned int nova_lar, unsigned int altura, unsigned int D, unsigned int liga, unsigned int PT, FILE *PCT, unsigned char *b)

{

unsigned int cnt; unsigned char **bit;

unsigned int alta_byte, baixa_byte;

bit = (unsigned char **) calloc(D, sizeof(unsigned char)); if (!bit)

{

fprintf (stderr, "Nao tem memoria suficiente para a reserva!\n"); exit(1);

}

if (D == 1) {

alta_byte = TAM_IN_BYTE (nova_lar);

COD5(s, b, nova_lar, altura, alta_byte, alta_byte, liga, PT, PCT); goto F;

Apêndice B 131 REDUZIR (bit, b, D, nova_lar, altura);

cnt = (D*2)-1; altura = x[cnt]; cnt -= 1;

nova_lar = x[cnt];

baixa_byte = TAM_IN_BYTE (x[D*2-2]);

/* ---- Codificando somente a menor camada de Resolução ---- */ COD5 (s, bit[D-1], nova_lar, altura, baixa_byte, baixa_byte, liga, PT, PCT); F: BYTEOUT (ESC, PCT);

BYTEOUT (DTNORM, PCT); free(bit);

return; }

void **PLANO_P (unsigned int largura, unsigned int altura, unsigned char *bit, unsigned char **g) {

unsigned char *k; unsigned int i, j;

unsigned char *b0, *b1, *b2, *b3, *b4, *b5, *b6, *b7; /* --- Colocar os dados de cada bit de 8 bits --- */ /* --- numa area de memoria separada --- */ b0 = g[0]; b1 = g[1]; b2 = g[2]; b3 = g[3];

b4 = g[4]; b5 = g[5]; b6 = g[6]; b7 = g[7]; k = bit;

for (i = 0; i < altura; i++) { for (j = 0; j < largura; j++) { *b0 <<= 1; *b0 |= (*k & 0x01); *k >>= 1; *b1 <<= 1; *b1 |= (*k & 0x01); *k >>= 1; *b2 <<= 1; *b2 |= (*k & 0x01); *k >>= 1; *b3 <<= 1; *b3 |= (*k & 0x01); *k >>= 1; *b4 <<= 1; *b4 |= (*k & 0x01); *k >>= 1; *b5 <<= 1; *b5 |= (*k & 0x01); *k >>= 1; *b6 <<= 1; *b6 |= (*k & 0x01); *k >>= 1; *b7 <<= 1; *b7 |= (*k & 0x01); if ((j & 7) == 7) { b0++; b1++; b2++; b3++; b4++; b5++; b6++; b7++; } k++; } } /* i */ return; }

void MEM_R (unsigned char *ptr, unsigned int altura, unsigned int largura, FILE *fpix, char *fe) {

fread (ptr, largura * altura, sizeof(unsigned char), fpix); if (feof(fpix))

fprintf (stderr, "Fim do arquivo de pixels '%s' inesperado !\n",fe); exit(1);

}

if (ferror(fpix) || fclose(fpix)) {

fprintf (stderr,"Problema durante a leitura do arquivo '%s'\n",fe); exit(1);

} return; }

unsigned int lerint (FILE *fpix) { unsigned int i, c; if ((c = getc(fpix)) != EOF) { ungetc(c, fpix); fscanf(fpix,"%d",&i); } return i; }

FILE *ABRIR (char *f, FILE *PCT) {

FILE *fpix; unsigned int k; unsigned char L, tipo; fpix = fopen(f,"rb"); if (!fpix)

{

fprintf (stderr,"Nao pode abrir o arquivo de pixels '%s'\n",f); exit(1);

}

if ((L = getc(fpix)) != 'P') {

fprintf (stderr,"O arquivo '%s' nao e tipo PGM !\n",f); exit(1);

}

fwrite (&L, 1, sizeof(unsigned char), PCT); if ((tipo = getc(fpix)) != '5')

{

fprintf (stderr,"O arquivo '%s' nao e com formato RAW de tipo PGM !\n",f); exit(1);

}

fwrite (&tipo, 1, sizeof(unsigned char), PCT); fprintf (PCT,"\n");

while ((k = getc(fpix)) != EOF && !isdigit(k)) if (k =='#')

{

Apêndice B 133 while ((k = getc(fpix)) != EOF && !(k == 13 || k == 10))

fprintf (PCT,"%c",k); fprintf (PCT,"\n"); } ungetc(k, fpix); return (fpix); }

void CAMADAS (struct code_estado *s, char *fs, char *fe) {

FILE *fpix, *PCT;

unsigned char *area, **PLANO, h;

unsigned int espaco, DL, D, NO_PLANO, liga, PT, m; unsigned int largura, altura, nivel, nova_lar, lar; unsigned char *t0, *t1, *t2, *t3, *t4, *t5, *t6, *t7; PCT = fopen(fs,"wb");

if (!PCT) {

fprintf (stderr,"Nao pode abrir o arquivo '%s' de saida \n",fs); exit(1);

}

fpix = ABRIR (fe, PCT);

printf ("\n\n =========>> ATENCAO! ... O numero de PLANOS = 8 \n\n"); NO_PLANO = 8;

DL = 0;

printf ("\n\n =====>> Digite 1 para ativar processo da Predição Tipical = "); scanf ("%d",&PT);

C: printf ("\n\n ========>> Entre com numeros de Camadas de Resolucao = "); scanf ("%d",&D);

if (D > 7 || D == 0) {

printf ("\n O padrao JBIG ADEVERTE! o valor de camadas deveria ser \ de (1) a (7). ===> Por favor, repeta-se o processo ... \n\n");

goto C; }

if (D == 1)

printf("\n\n ATENCAO! .... A codificacao feita em cada PLANO somente\ para a camada com a resolucao total \n\n");

else

printf("\n\n ATENCAO! .... A codificacao feita em cada PLANO somente\ para a menor camada de resolucao (D0) \n\n");

espaco = 0;

largura = lerint (fpix); altura = lerint (fpix); h = getc(fpix); nivel = lerint (fpix); h = getc(fpix);

/* --- Colocar os dados da imagem original numa area --- */ area = reserva_char (largura, altura);

/* --- da imagem original --- */

PLANO = (unsigned char **) calloc(NO_PLANO, sizeof(unsigned char)); if (!PLANO)

{

fprintf (stderr, "Nao tem memoria suficiente para a reserva!\n"); exit(1);

}

lar = largura / 8; /*-- largura nova para nova area de cada bit (PLANO) --*/ for (m = 0; m < NO_PLANO; m++)

PLANO[m] = reserva_char (lar, altura);

/* --- Colocar os dados de cada bit de 8 bits --- */ /* --- numa area de memoria separada --- */

t0 = PLANO[0]; t1 = PLANO[1]; t2 = PLANO[2]; t3 = PLANO[3]; t4 = PLANO[4]; t5 = PLANO[5]; t6 = PLANO[6]; t7 = PLANO[7]; PLANO_P (largura, altura, area, PLANO);

free (area);

fprintf (PCT,"%d", DL); fprintf (PCT,"%d", D);

fprintf (PCT,"%d", NO_PLANO); fprintf (PCT,"%d", espaco);

fprintf (PCT," %d %d ", largura, altura); fprintf (PCT,"%d ", nivel);

printf ("\n Modelo Template de Baixa Res. : - Duas linhas => digite 2:"); printf ("\n - Tres linhas => digite 3:");

scanf ("%d",&liga); fprintf(PCT,"%d",liga); fprintf (PCT,"%d", PT);

nova_lar = lar * 8; /* -- # de bits por linha em cada PLANO = largura -- */ DIVIDE (s, nova_lar, altura, D, liga, PT, PCT, t0);

DIVIDE (s, nova_lar, altura, D, liga, PT, PCT, t1); DIVIDE (s, nova_lar, altura, D, liga, PT, PCT, t2); DIVIDE (s, nova_lar, altura, D, liga, PT, PCT, t3); DIVIDE (s, nova_lar, altura, D, liga, PT, PCT, t4); DIVIDE (s, nova_lar, altura, D, liga, PT, PCT, t5); DIVIDE (s, nova_lar, altura, D, liga, PT, PCT, t6); DIVIDE (s, nova_lar, altura, D, liga, PT, PCT, t7); FIMC (s, PCT);

free(PLANO);

if (ferror(PCT) || fclose(PCT)) {

fprintf (stderr,"Problema durante escrever no arquivo '%s'\n",fs); exit(1);

} return; }

void INITC (struct code_estado *s) {

Apêndice B 135 for (i = 0; i < 4096; s->ST[i++] = 0); s->C = 0; s->A = 0x10000; s->SC = 0; s->CT = 11;

s->BUF = -1; /* buffer vazio */ return;

}

main (argc, argv)

char *argv[]; {

struct code_estado s;

char *fe = argv[1], *fs = argv[2]; if ((fe != NULL) && (fs != NULL)) {

INITC (&s);

CAMADAS (&s, fs, fe);

printf (" \n\n ... FIM DO PROCESSO DE CODIFICACAO ...\n\n"); }

else

printf ("'erro'! \n\n Por favor, entre com: nome do arquivo tipo PGM \ e da saida para armazenar os dados compactados, sequencialmente.\n"); } /* main */

/* --- somente a menor camada de resolução de cada plano de bits --- */ /* --- com a opção de usar o processo de Predição Típica --- */

#include <stdio.h> #include <ctype.h> #include <assert.h> #include <stdlib.h> #include "tabela.h" #define ESC 0XFF #define STUFF 0X00 #define DTRST 0X03 #define DTNORM 0X02 #define PTB2CX 0X195 #define PTB3CX 0X0E5 unsigned int passa = 9;

/* --- Descricao "status" de decodificador aritmetico --- */ struct decode_estado

{

unsigned char ST[4096]; /* "status" prob. dos contextos, e MSB = MPS */ unsigned int C; /* registrador C, base de intervalo a ser codificado*/ int A; /* registrador A, tamanho normalizado de intervalo */ int CT; /* contador de dislocamento de bits, determina * * quando pro'ximo byte vai ser lido */ int lnpt; /* flag de PT: linha nao e' Predicao Tipical */

int pseudo; /* flag de PTBON/PTDON: proximo pixel e' pseudo */ };

void LERBYTE (struct decode_estado *s, FILE *PCT) { unsigned int k; L: if ((k = getc(PCT)) != EOF) { if (k == ESC) { if ((k = getc(PCT)) == EOF) {

printf ("\n Erro! No codigo do Encerramento surgeu 0xff extra!\n"); exit(1); } else if (k == DTNORM) goto L; else if (k == DTRST)

Apêndice B 137 {

printf ("\n O encerramento reforcado \n");

passa = getc(PCT); /*Em qual camada foi encerrado o chave,(D-ca)*/

goto L; /* --- passa = No. da camada onde foi o encerramento --- */ } else if (k == STUFF) k = 0xff; else {

printf ("\n Erro! Nao ha codigo de STUFF \n\n"); exit(1); } } } else k = 0; s->C |= k << 8; s->CT = 8; return; }

void RENORMDEC (struct decode_estado *s, FILE *PCT) { do { if (s->CT == 0) LERBYTE (s, PCT); s->C <<= 1; s->A <<= 1; --s->CT; } while (s->A < 0x8000); if (s->CT == 0) LERBYTE (s, PCT); return; }

unsigned int DECODIF (struct decode_estado *s, FILE *PCT, unsigned short CX) {

unsigned int PIX; extern short LSZ[]; register int lsz, ss;

extern char NMPS[], NLPS[], SWTCH[];

ss = s->ST[CX] & 0x7f; /* determina o estado do contexto CX */ assert (ss < 113);

lsz = LSZ[ss]; /* consulta a estimativa de probabilidade */ /* relativa ao estado do CX */ if ((s->C >> 16) < (s->A -= lsz)) if (s->A >= 0x8000) { PIX = s->ST[CX] >> 7; return PIX;

else /* --- MPSDECODIF --- */ if (s->A < lsz)

{

PIX = 1 - (s->ST[CX] >> 7);

/* --- teste se a troca condicional (MPS/LPS) e' necessa ria --- */ if (SWTCH[ss])

s->ST[CX] ^= 0x80; /* XOR para invertir o valor de MVAL[CX] */ /* - escolha o proximo estado de estimativa de probabilidade - */ s->ST[CX] &= 0x80; s->ST[CX] |= NLPS[ss]; } else { PIX = s->ST[CX] >> 7; s->ST[CX] &= 0x80; s->ST[CX] |= NMPS[ss]; } else /* --- LPSDECODIF --- */ if (s->A < lsz) { s->C -= s->A << 16; s->A = lsz; PIX = s->ST[CX] >> 7; s->ST[CX] &= 0x80; s->ST[CX] |= NMPS[ss]; } else { s->C -= s->A << 16; s->A = lsz; PIX = 1 - (s->ST[CX] >> 7);

/* --- teste se a troca condicional (MPS/LPS) e necessaria --- */ if (SWTCH[ss])

s->ST[CX] ^= 0x80; /* XOR para invertir o valor de MVAL[CX] * * se A = B; entao A XOR B = 0 */ /* - escolha o proximo estado de estimativa de probabilidade - */ s->ST[CX] &= 0x80; s->ST[CX] |= NLPS[ss]; } RENORMDEC (s, PCT); return PIX; }

void DCOD5 (struct decode_estado *s, unsigned char *Res_bit, unsigned int largura, unsigned int altura, unsigned int alta_byte, unsigned int baixa_byte, unsigned int liga, unsigned int PT, FILE *PCT)

Apêndice B 139 {

unsigned char *lp1, *lp2, *p1, *q1;

unsigned int i, j, CX_CBR, SLNPT, PTBON, PTDON; unsigned int cx, PIX, fase1, fase2, baixa_altura;

register unsigned int linha_h1,linha_h2,linha_h3,linha_l1,linha_l2,linha_l3; cx = 0; PIX = 0; s->lnpt = 1; PTBON = PTDON = PT; baixa_altura = (altura +1)/2; lp2 = Res_bit; lp1 = lp2 + baixa_byte; for (i = 0; i < altura; i++) { /* =============== Predição Tipical =============== */ if (PTBON == 1) { if (liga == 2) CX_CBR = 1; else CX_CBR = 0; SLNPT = DECODIF (s, PCT, CX_CBR ? PTB2CX : PTB3CX); s->lnpt = !(SLNPT ^ s->lnpt); /** se A=B entao A.XOR.B=0 **/ if (!s->lnpt)

{ /* linha tipical (iqual a linha em cima dela) */ p1 = lp2; if (i == 0) while (p1 < lp2 + baixa_byte) *p1++ = 0; else { q1 = lp2 - baixa_byte; while (q1 < lp2) *p1++ = *q1++; } /* else */ lp2 += baixa_byte; continue; } /* if */ } /* if PTBON */

linha_h1 = linha_h2 = linha_h3 = 0; if (i > 0)

{

linha_h2 = (unsigned int) *(lp2 - baixa_byte) << 8; if (i > 1 && liga == 3)

linha_h3 = (unsigned int) *(lp2 - baixa_byte - baixa_byte) << 8; } for (j = 0; j < largura;) { if ((j & 7) == 0) if ((j < (baixa_byte * 8 - 8)) && (i > 0)) { linha_h2 |= *(lp2 - baixa_byte + 1);

linha_h3 |= *(lp2 - baixa_byte - baixa_byte + 1); } do { switch (liga) { case 2:

cx = (linha_h1 & 0x00f) + ((linha_h2 >> 9) & 0x3f0); break;

case 3:

cx = (linha_h1 & 0x003) + ((linha_h2 >> 11) & 0x07c) + ((linha_h3 >> 7) & 0x380);

linha_h3 <<= 1; break;

default:

fprintf (stderr,"Tipo de Template -%d- errado!\n" ,liga); exit(1);

}

PIX = DECODIF (s, PCT, cx);

Documentos relacionados