APLICAÇÃO DE ESTEGANOGRAFIA EM ARQUIVOS JPG
LÍVIA DELGADO VOLPE
Presidente Prudente – SP
2007
APLICAÇÃO DE ESTEGANOGRAFIA EM ARQUIVOS JPG
LÍVIA DELGADO VOLPE
Trabalho de Conclusão de Curso, apresentado
a Faculdade de Informática de Presidente
Prudente, Curso de Bacharelado em Ciência
da Computação, Universidade do Oeste
Paulista, como parte dos requisitos para a sua
conclusão.
Área: Processamento Gráfico
Orientadores:
MSc. Ana Paula D. Parizoto Fabrin
MSc. Almir Olivette Artero
MSc. Francisco Assis da Silva
Presidente Prudente – SP
2007
Aplicação de Esteganografia em arquivos JPG /
Lívia Delgado Volpe. – Presidente Prudente:
UNOESTE, 2007.
85p. : il.
Trabalho de Conclusão de Curso (Graduação
em Ciência da Computação) – Universidade do
Oeste Paulista – UNOESTE: Presidente Prudente
– SP, 2007.
Bibliografia
1. Esteganografia, 2. Processamento de
imagens. I. Autor. II. Título.
Dedico este trabalho ao meu pai Carlos, que nunca mediu esforços e
esteve sempre apoiando e aconselhando nos momentos mais difíceis sem que a
distância atrapalhasse.
A minha mãe Ana Lúcia, pelo amor, confiança e apoio, e a minha irmã
Thaís pelo carinho e amizade.
A minha família que, em todos os momentos de realização desta
pesquisa, esteve presente.
A Deus pela minha vida.
A professora orientadora, Ana Paula D. Parizoto Fabrin que, na rigidez de
seus ensinamentos, fez aprimorar meus conhecimentos.
Aos professores, Francisco Assis da Silva e Leandro Luiz de Almeida, pela
amizade e carisma.
Aos professores da Faculdade de Informática de Presidente Prudente
pelos conhecimentos compartilhados.
Ao meu pai, Carlos Volpe, pelos sacrifícios que fez e ainda faz para
proporcionar uma vida maravilhosa para sua família, acima de tudo com muito amor e
carinho.
A minha mãe Ana Lúcia pela confiança e pelo apoio que nunca faltou,
sempre me dando forças para concluir o curso e não desistir nunca.
Ao meu namorado Lucas, que me incentivou, aconselhou e deu forças
para nunca desistir e sempre acreditar que sou capaz.
Aos meus amigos e amigas, pelo companheirismo e os momentos de
alegria compartilhados.
"Procure ser uma pessoa de valor, em vez de procurar ser uma pessoa de
sucesso. O sucesso é conseqüência."
Aplicação de Esteganografia em arquivos JPG
O uso de imagens digitais aumentou consideravelmente nos últimos anos, com isso
aumentaram os problemas de segurança tais como integridade de imagens digitais,
direitos autorais e proteção de propriedade. Uma solução para esse problema é utilizar
a técnica de Esteganografia que consiste em esconder mensagens ficando
imperceptível sua existência. A presente pesquisa, intitulada – “Aplicação de
Esteganografia em arquivos JPG” – teve como objetivo central estudar a possibilidade e
criar mecanismos de Esteganografia em arquivos de imagem JPG sem danificar ou
perder a mensagem inserida na imagem. Com este estudo será possível viabilizar a
inserção de novas mensagens ou imagens em vários formatos de imagem JPG. A
realização deste trabalho justificou-se, diante da necessidade de concluir as vantagens
ou desvantagens de se utilizar Esteganografia em imagens JPG, uma vez que este
modelo de imagem é o mais utilizado nos mais diversos ambientes da informática.
Metodologicamente, o assunto pesquisado envolveu o levantamento de material
bibliográfico sobre imagem JPG e Esteganografia, foram estudados componentes Java
para o processamento de imagem JPG e os mecanismos de Esteganografia aprendidos
após a pesquisa bibliográfica foram colocados em prática em algumas das etapas de
compressão das imagens do padrão JPG.
Application of Steganography in JPG files
The use of digital images has increased considerably in recent years; because of it the
security problems such as integrity of digital images, copyright and protection of property
have increased. One solution to this problem is to use the technique of Steganography,
which is used to hide messages getting imperceptible its existence. The present work,
entitled, "Application of Steganography in JPG files" - aimed to study the possibility and
create mechanisms for Steganography in JPG image files without damaging or losing
the message embedded in the image. With this study it will be possible to facilitate the
insertion of new messages or images in various formats of JPG image. The completion
of this work was justified, concluding the advantages or disadvantages of using
Steganography in JPG images, since this type of image is the most used in a variety of
computing environments. Methodologically, the subject researched involved the removal
of bibliographic material on JPG image and Steganography; it was studied Java
components for the processing of JPG image and mechanisms of Steganography
learned after bibliographic research were put into practice in some of the stages of
compression of images from the standard JPG.
Figura 1 – Exemplo de pixels de uma imagem...25
Figura 2 – Exemplo de uso do método LSB ...26
Figura 3 – Processo de Compressão JPEG...29
Figura 4 – Processo de Descompressão JPEG ...30
Figura 5 – Resultados de Compressão com diferentes tamanhos de blocos...32
Figura 6 – Resultados de Compressão variando os fatores de qualidade aplicados a
uma imagem de 384 X 288 pixels com 1 byte por pixel, tamanho de 100.592 bytes. ....34
Figura 7 – Ziz-zag num bloco de 8 x 8 ...36
Figura 8 – A operação Run-Length Coding ...38
Figura 9 – Imagem com 640 X 480 pixels ...40
Figura 10 – Histograma da imagem original com o número de pixels de cada nível de
cinza ...41
Figura 11 – Árvore de Huffman ...42
Figura 12 – Codificação de Huffman ...42
Figura 13 – Código de Inserção de mensagem na imagem ...45
Figura 14 – Código de leitura da mensagem na imagem ...46
Figura 15 – Técnica 1: Criar funções ...48
Figura 16 – Código da TDC e Quantização...49
Figura 17 – Código da inversa da Quantização e a Transformada Inversa do Cosseno50
Figura 18 – Técnica 2: Replicação da informação ...52
Figura 19 – Código de inserção de uma mensagem replicada na imagem...53
Figura 20 – Código de leitura de uma mensagem replicada na imagem ...55
CCITT
Consultive Committee International of Telegraph e Telephones
IEC
International Electrotechnical Commission
ISO
International Standard Organization
ITDC
Transformada Inversa do Cosseno
JPEG
Joint Photographic Experts Group
LSB
Last Significant Bit
RLC
Run-Length Coding
SAH
Sistema Auditivo Humano
SVH
Sistema Visual Humano
TDC
Transformada Discreta do Cosseno
TDK
Transformada de Karhunen-Loève
1
INTRODUÇÃO...12
1.1
Formulação do Problema...12
1.2
Objetivos do Projeto...12
1.3
Justificativas do Projeto ...13
1.4
Metodologia e Plano de Trabalho ...13
2
ESTEGANOGRAFIA ...15
2.1
Definição ...15
2.2
Histórico ...15
2.3
Esteganografia X Criptografia ...16
2.4
Aplicações...17
2.4.1
Proteção de direitos autorais ...17
2.4.2
Comunicação encoberta ...17
2.4.3
Seriação (Fingerprinting) ...18
2.4.4
Certificação e controle de acesso ...18
2.4.5
Legenda em imagens e vídeos ...18
2.4.6
Autenticação e verificação da integridade ...19
2.4.7
Controle de cópias ...19
2.5
Técnicas de Esteganografia...19
2.5.1
Esteganografia em textos ...19
2.5.2
Codificação por deslocamento de linhas verticalmente ...20
2.5.3
Codificação por deslocamento de palavra em textos justificados ...20
2.5.4
Codificação por deslocamento do caracter de fim de linha...21
2.5.5
Esteganografia em áudio ...21
2.5.5.1 Inserção no bit menos significativo ...22
2.5.5.2 Esconder dados no eco do áudio...22
2.5.6
Esteganografia sobre TCP/IP ...23
2.5.7
Esteganografia em imagens ...23
2.6
Técnicas de Esteganografia em Imagens ...24
2.6.1
Inserção no bit menos significativo ...24
2.6.2
Técnicas de filtragem e mascaramento ...26
2.6.3
Algoritmos e transformações ...27
3
ARQUIVOS DE IMAGEM JPG ...28
3.1
Transformada Discreta do Cosseno (TDC)...31
3.2
Quantização...33
3.3
Zig-zag ...35
3.4
Codificação RLC ...36
3.5
Codificação por Huffman...39
4
PROJETO...44
4.1
Descrição das Atividades Realizadas ...44
4.1.1
Inserção de mensagem na imagem...44
4.1.2
Leitura da mensagem embutida na imagem ...45
4.1.3
Aplicação de esteganografia em arquivos de imagem BMP ...46
4.1.7
Inserção da mensagem após realizar etapas de compressão usando
componentes existentes...55
5
CONCLUSÕES E TRABALHOS FUTUROS...58
REFERÊNCIAS BIBLIOGRÁFICAS ...59
1
INTRODUÇÃO
1.1 Formulação do Problema
O uso de imagens digitais aumentou consideravelmente nos últimos anos,
com o surgimento da Internet a comunicação e a troca de informações passaram a ser
possível entre as pessoas do mundo inteiro. Com isso, aumentaram os problemas de
segurança, tais como: integridade de imagens digitais, direitos autorais e proteção de
propriedade.
Uma solução para esse problema é utilizar a técnica de Esteganografia,
que consiste em esconder mensagens ficando imperceptível sua existência. Este
trabalho monográfico foi realizado para saber se é possível inserir mensagens pelo
método de Esteganografia em arquivos de imagem JPG sem perdas ou danos na
mensagem inserida.
1.2 Objetivos do Projeto
Um dos grandes objetivos deste trabalho foi estudar a possibilidade e
criar mecanismos de Esteganografia em arquivos de imagem JPG sem danificar ou
perder a mensagem inserida na imagem.
Primeiramente foi implementada a inserção de uma mensagem em uma
imagem BMP, para conhecer melhor a técnica de Esteganografia. Já que esse tipo de
imagem não usa compressão, sabe-se que não há perda da informação inserida.
Posteriormente foi implementada a inserção de uma mensagem em uma
imagem JPG, pelo qual foi possível descobrir as possibilidades de inserção por meio de
algumas técnicas estudadas.
1.3 Justificativas do Projeto
A segurança na transferência de dados via Internet é de suma importância
para o meio digital. A ocultação de mensagens no corpo de imagens digitais pode
garantir uma maior viabilidade na transmissão segura de dados. Por meio do estudo da
técnica da Esteganografia, foi possível verificar a confiabilidade da ocultação de tais
mensagens, baseando-se no padrão JPG, sendo esse o mais utilizado entre os
diversos ambientes da informática.
1.4 Metodologia e Plano de Trabalho
O trabalho foi realizado mediante pesquisas e levantamento de material
bibliográfico sobre o padrão de imagens JPG e esteganografia. Além disso, foram
estudados componentes Java para processamento de imagem JPG.
Os mecanismos de esteganografia estudados foram implementados e
colocados em prática em algumas das etapas de compressão das imagens do padrão
JPG. Também foram implementadas algumas etapas da compressão, tais como:
Transformada Discreta do Cosseno, a quantização e suas respectivas inversas.
Além desse primeiro capítulo introdutório, esta monografia apresenta no
capítulo 2 os conceitos básicos, como definições, histórico, aplicações e técnicas de
esteganografia. No capítulo 3 são descritos os conceitos de arquivos de imagens JPG e
seu processo de compressão e descompressão. O documento mostra também a
descrição das atividades realizadas no projeto (capítulo 4), tais como, a inserção da
mensagem em uma imagem, a leitura da mensagem na imagem, sua aplicação em
imagens BMP e também as técnicas desenvolvidas e estudadas para inserção e leitura
em imagens JPG. Por fim, o capítulo 5 mostra as conclusões obtidas no
desenvolvimento do trabalho e também apresenta possíveis trabalhos futuros.
2
ESTEGANOGRAFIA
2.1 Definição
Segundo Popa (apud PETRI, 2004, p. 7), esteganografia deriva de ambas
as palavras gregas estegano e grafia, em que, estegano significa esconder ou mascarar
e grafia significa escrita. Logo, esteganografia é a arte da escrita para comunicações
ocultadas. Dentro da esteganografia existe um conjunto de métodos para
comunicações secretas desenvolvidas ao longo da história. Entre os métodos de
Esteganografia é possível destacar: tintas “invisíveis”, micropontos, arranjo de
caracteres, assinaturas digitais, canais escondidos, comunicações por espalhamento de
espectro, entre outras.
De acordo com Jascone (apud PETRI, 2004, p. 8), esteganografia é a arte
da comunicação secreta, onde oculta-se uma mensagem sigilosa dentro de outra
informação sem importância, de maneira que não seja possível identificar que há uma
mensagem escondida. Na área da computação essa outra informação sem importância
pode ser um arquivo de som, imagem ou texto.
2.2 Histórico
Ao longo da história, foram criados e utilizados muitos métodos para
ocultar informações, com o objetivo de obter privacidade e segurança dentro dos meios
de comunicação.
Um método utilizado na Grécia antiga para troca de mensagens seguras
era raspando a cabeça dos escravos de confiança e tatuando a mensagem sigilosa a
ser transmitida, e após o crescimento do cabelo o escravo era enviado até o seu
destino, onde sua cabeça seria raspada novamente para ser revelada a mensagem à
pessoa desejada (PETITCOLAS ET AL,1999, apud ROCHA, 2003, p.3).
Outro método foi o de micropontos que começou a ser utilizado na
Segunda Guerra Mundial. Uma mensagem secreta poderia ser fotografada e reduzida
ao tamanho de um ponto e podendo este ponto fazer parte de uma mensagem qualquer
sondo o ponto de uma letra “i” ou até mesmo de um ponto final “.” de frase de uma
mensagem qualquer (JASCONE, 2003, p.33).
Outra técnica seria ocultar uma mensagem dentro de outra, um exemplo
seria escrever uma mensagem oculta utilizando a primeira letra de cada palavra de
outra mensagem que não tenha importância (JASCONE, 2003, p.33).
2.3 Esteganografia X Criptografia
A esteganografia é um ramo da Criptologia que consiste em ocultar uma
informação dentro de outra informação sem importância. Ao invés de cifrá-la, técnica
utilizada na criptografia de mensagens, o que se busca é tornar imperceptível a sua
presença.
Uma diferença entre essas duas técnicas é que na esteganografia a
mensagem não está codificada, mas não é possível notar a sua presença, enquanto
que na criptografia a mensagem está codificada, porém a sua presença pode ser
identificada.
Essas duas técnicas podem ser combinadas para aumento da privacidade
e segurança.
2.4 Aplicações
A seguir serão apresentadas algumas aplicações de Esteganografia
descritas por GOIS (apud PETRI, 2004, p. 19).
2.4.1 Proteção de direitos autorais
É quando um autor de uma imagem, vídeo, som ou texto deseja assinar
sua obra para que nenhuma pessoa possa atribuir-se ou aproveitar-se das obras de
sua autoria.
2.4.2 Comunicação encoberta
O simples fato de uma pessoa usuária de computador desejar enviar uma
mensagem eletrônica de forma sigilosa para outra pessoa pode despertar o interesse
de um atacante interceptar e bloquear a mensagem. Com o uso da criptografia alertaria
o atacante, entretanto aplicando-se a esteganografia a comunicação tornaria possível
sem que o atacante soubesse da existência de uma comunicação.
2.4.3 Seriação (Fingerprinting)
Consiste em colocar, escondido ou não, identificador único do usuário em
objetos, da mesma forma em que cada cópia de uma xilogravura
1é idêntica às outras a
menos do número que a identifica dentro da série produzida (1/20, 2/20, etc.). Tudo isso
para ser possível detectar e identificar a cópia ilegal de produtos.
2.4.4 Certificação e controle de acesso
Muito utilizado em documentos oficiais, por exemplo, carteiras de
identidade e passaportes. Ela permite validar as informações presentes em um
documento por meio da sua vinculação. Um exemplo seria a utilização de um cartão de
identificação, onde o identificador do cartão é mostrado em forma textual e também
escondido como uma marca na própria fotografia impressa no cartão.
2.4.5 Legenda em imagens e vídeos
Nesse caso as legendas seriam ocultadas em imagens ou vídeos de
modo que as mesmas possam ser extraídas e apresentadas quando necessário. Esse
método também pode ser aplicado em som ou informações adicionais de um filme de
DVD, por exemplo.
2.4.6 Autenticação e verificação da integridade
As imagens não podem ser aceitas como provas de julgamento, pois
podem ser facilmente alteradas ou manipuladas. Com o uso de marcas digitais essa
situação pode ser alterada em favor do uso deste tipo de mídia, como o uso de
câmeras digitais, por exemplo.
2.4.7 Controle de cópias
Muitas companhias estão trabalhando em restringir e controlar a
possibilidade de cópia de seus produtos. Um exemplo seria a fabricação de DVDs,
onde um filme comercial poderia conter uma marca digital que especificasse se e
quando o filme poderia ser copiado.
2.5 Técnicas de Esteganografia
2.5.1 Esteganografia em textos
Segundo Petri (2004), esse método é um dos mais simples, pois não é
preciso a utilização de nenhuma ferramenta específica para aplicar tal método. Um
exemplo dessa técnica seria ler apenas a ultima letra de cada palavra, formando assim
uma palavra escondida, ou ainda, um texto.
2.5.2 Codificação por deslocamento de linhas verticalmente
De acordo com Petri (2004), por meio dessa técnica, as linhas descritas
no texto são deslocadas verticalmente para codificar unicamente o documento.
Codificar e decodificar podem ser aplicados ao formato de arquivo de um documento ou
a um bitmap
2de página de imagem. Nesse caso, se o documento está em formato de
papel é mais difícil remover a codificação. Cada página passará pelo processo de
reescaneamento, alteração e reimpressão. Isto se torna ainda mais complicado se o
documento impresso é uma fotocópia, pois podem sofrer algumas alterações.
2.5.3 Codificação por deslocamento de palavra em textos justificados
Na codificação por deslocamento de palavra em textos justificados, as
codewords
3são codificadas em um documento deslocando as posições horizontais das
palavras dentro das linhas do documento, mantendo o aspecto de espaçamento
natural. Essa codificação pode também ser aplicada a um formato de arquivo ou a um
bitmap de página de imagem. A técnica é somente aplicável a documentos com
espaçamento variável entre palavras vizinhas, como em documentos que tiveram o
texto justificado. Como efeito dessa variação no espaçamento, é necessário ter a
imagem original, ou saber o espaçamento entre as palavras em um documento não
codificado (PETRI, 2004).
Nessa técnica, o deslocamento de palavras pode também ser detectado e
destruído. Em caso de alguém conhecer o algoritmo usado pelo formatador para a
justificação do texto, o espaço real entre as palavras pode ser então medido e
comparado com o espaçamento esperado pelo formatador. As diferenças de
2
Formato de um arquivo do tipo imagem. Estes arquivos possuem extensões “.bmp” (PETRI, 2004, p.17).
espaçamento revelariam os dados codificados. Outra maneira é pegar dois ou mais
documentos não corrompidos e distintamente codificados e executar operações de
diferenciamento de pixels, página por página nas imagens. Assim poderia se perceber o
deslocamento das palavras e o tamanho do espaçamento entre elas. Reespaçando as
palavras deslocadas de volta ao espaçamento original produzido sob o formatador, ou
aplicando deslocamentos horizontais aleatórios a todas as palavras não encontradas
nas bordas das colunas do documento, poderia se eliminar a codificação. Entretanto,
essas técnicas poderiam consumir muito tempo (PETRI, 2004).
2.5.4 Codificação por deslocamento do caracter de fim de linha
Outra técnica de codificar informações em texto é conhecida como
codificação característica. Isto se aplica a um arquivo de imagem bitmap de um
documento, ou a um arquivo de formato. Nessa codificação, algumas características do
texto são modificadas ou não, dependendo da palavra código. A codificação
característica suporta uma quantidade elevada de codificação dos dados, devido ao
número freqüentemente elevado das características nos originais que podem ser
modificados. A codificação característica pode ser detectada ajustando cada
comprimento de fim de linha a um valor fixo, podendo ser feito de forma manual ou
automática (PETRI, 2004).
2.5.5 Esteganografia em áudio
O Sistema Auditivo Humano (SAH) apresenta uma faixa de freqüência
muito grande e muito sensível ao ruído. Qualquer modificação em um arquivo de áudio
pode ser detectada. Entretanto, enquanto o SAH possui uma larga faixa dinâmica, ele
tem uma pequena faixa de diferenciação para distância - sons fortes tendem a abafar
sons fracos. Para esconder mensagens em áudio, é necessário explorar as fraquezas
do SAH, tomando cuidado com a sensibilidade humana (BENDER, 1996 apud PETRI,
2004, p. 19).
2.5.5.1 Inserção no bit menos significativo
Valores binários podem ser armazenados nos bits menos significativos
dos arquivos de áudio. A capacidade do sinal é de 1 Kb por segundo por kilohertz,
então, por exemplo, em uma seqüência de reprodução de 44 kHz a capacidade do sinal
seria de 44 kbps. Porém, essa técnica introduz um ruído audível. Uma das
desvantagens desta técnica é a pequena imunidade a manipulações. Fatores, como,
ruído de canal e regravação podem destruir facilmente o sinal oculto (BENDER, 1996
apud PETRI, 2004, p. 19).
2.5.5.2 Esconder dados no eco do áudio
Nesse método são inseridos os dados em sinal próprio gerando um eco.
Os dados são escondidos pela variação de três parâmetros de eco: amplitude inicial,
taxa de deterioração e o atraso. Em algum ponto, a audição humana não pode
distinguir entre o som original e o eco, onde o sinal do eco é ouvido simplesmente como
ressonância. As qualidades da gravação original, do tipo de som, e do ouvinte, também
influenciam na transmissão (BENDER, 1996 apud PETRI, 2004, p. 19).
2.5.6 Esteganografia sobre TCP/IP
Existem técnicas para ocultar informações dentro do cabeçalho de um
pacote TCP/IP
4. A arquitetura básica do pacote TCP/IP permite um número de opções
secretas, ou seja, a utilização dos campos não usuais ou opcionais que ficam dentro
dos pacotes (PETRI, 2004).
2.5.7 Esteganografia em imagens
No próximo item, serão mostradas técnicas de codificação dos dados em
imagens digitais. Necessariamente, na esteganografia da imagem é preciso saber
explorar os poderes limitados do sistema visual humano (SVH). A esteganografia da
imagem evoluiu muito com o desenvolvimento de computadores gráficos rápidos e
poderosos, além de que os softwares esteganográficos estão disponíveis para usuários
diários da Internet (PETRI, 2004).
4
O TCP/IP ( nome derivado de seus protocolos principais Transmission Control Protocol/Internet Protocol ) é um padrão utilizado para conectar as redes de computadores que fazem parte da Internet, permitindo a comunicação entre aplicativos em computadores de redes distintas sem que haja necessidade de se conhecer a topologia empregada em cada uma delas (PETRI, 2004. p.10).
2.6 Técnicas de Esteganografia em Imagens
2.6.1 Inserção no bit menos significativo
De acordo com Jascone (2003, p.38), pondera que:
O método Last Significant Bit (LSB)5 é o mais comum utilizado para armazenar informação em imagens digitais. Consiste em utilizar o bit menos significativo de cada pixel (ou de cada cor) da imagem, para ocultar a mensagem.
De acordo com Rocha (2003, apud Jascone, 2003, p.38), as técnicas de
LSB conseguem esconder os dados aos olhos humanos, mas podem ser facilmente
perdidas computacionalmente utilizando algoritmos de compressão com perdas de
dados. Por exemplo, se a mensagem for ocultada em uma imagem no formato bitmap,
a mensagem é perdida se esta for convertida para um formato JPEG, devido ao
processo de compressão que o padrão utiliza.
Para esconder uma mensagem em uma imagem de 24 bits, sendo que em
cada pixel possui três bytes (RGB), utilizando a técnica de inserção no bit menos
significativo, pode-se armazenar três bits em cada pixel, utilizando um bit de cada byte
desse pixel, sendo assim, cada byte da mensagem a ser ocultada irá ocupar oito bytes
da imagem (JASCONE, 2003).
A Figura 1 mostra os valores dos pixels de uma determinada imagem.
Figura 1 – Exemplo de pixels de uma imagem
Fonte: JASCONE, 2003.Supondo que o desejável seja armazenar a letra “A” nesta imagem. A letra
“A” é o código 65 da tabela ASCII e seu valor binário é equivalente ao número: 0 1 0 0 0
0 0 1. Armazenando esse valor binário, bit a bit, no corpo da imagem, utilizando o bit
menos significativo de cada byte do pixel, a imagem resultante seria equivalente a
Figura 2 (JASCONE, 2003).
Figura 2 – Exemplo de uso do método LSB
Fonte: JASCONE, 2003.Os bits sublinhados são aqueles que foram alterados, causando uma
alteração imperceptível para o olho humano na cor do pixel. Esses valores agrupados
formam o byte que representa a letra “A” (JASCONE, 2003).
2.6.2 Técnicas de filtragem e mascaramento
Técnicas de filtragem e mascaramento são restritas a imagens em tons de
cinza. Essas técnicas escondem a informação pela marcação de uma imagem,
semelhante ao funcionamento das marcas d’água em papel. Uma das vantagens dessa
técnica é que devido ao fato da marca d’água ser integrada na imagem ela pode ser
aplicada em imagem que passam por métodos de compressão. Outra vantagem é que
o olho humano não consegue distinguir as mudanças na imagem, sendo assim, as
técnicas de máscara e filtragem também passam despercebidas pelo sistema visual
humano (JASCONE, 2003, p.40).
2.6.3 Algoritmos e transformações
Os algoritmos de transformação trabalham com formas mais refinadas de
manipulação de imagens, entre elas estão: o brilho, a saturação e a compressão das
imagens. As técnicas de transformação tomam como aliado a compressão, que é o
principal inimigo da inserção LSB. Por isso tornam-se como as mais refinadas técnicas
de mascaramento de informações em imagens conhecidas (ROCHA, 2003, apud
PETRI, 2004, p.23).
3
ARQUIVOS
DE
IMAGEM
JPG
O padrão JPEG (Joint Photographic Experts Group), estabelecido
juntamente pelo ISO/IEC e organizações de CCITT, é um dos mais importantes padrões
de compressão de dados dos anos 90. O padrão de compressão de imagens JPEG
trabalha com imagens em tons de cinza e imagens coloridas de resolução e tamanho
variado. O padrão JPEG é usado em artes gráficas, editoração eletrônica, imagens
médicas, e várias outras aplicações. Esse padrão é usado comumente em compressão
com perda. Porém, também há um modo de compressão sem perda com desempenho
de compressão reduzido (BAXES, 1994).
O formato de imagem que faz uso desse algoritmo é o JPG. O tamanho
de cada bloco adotado para o padrão JPG é 8x8 pixels, pois possui melhor razão entre
tempo de cálculo e capacidade de compressão (SILVA, 1998).
O procedimento integral para a compressão de uma imagem tem a
Transformada Discreta do Cosseno (TDC) como uma de suas etapas. Primeiramente, a
imagem é subdividida em blocos 8 x 8, os quais são então transformados pela TDC
gerando um conjunto conhecido como coeficiente TDC. Esses coeficientes são então
quantizados, ou seja, sofrem uma redução em valor, sendo mantidos apenas os mais
importantes. O padrão JPEG faz essa redução por zona. É nessa etapa que há uma
significativa diminuição do espaço exigido para o armazenamento, com conseqüente
perda de informação. Os coeficientes são reordenados obedecendo a seqüência
zig-zag para a codificação por entropia, após a reordenação, são transformados pela
codificação de Huffman (SILVA, 1998).
Esse processo se repete até que se acabem todos os blocos da imagem,
quando se tem a imagem comprimida com extensão JPG. O processo de recuperação
da imagem “original” segue os passos na direção contrária, aplicando no final a
transformada inversa do cosseno (NELSON, 1991).
A Figura 3 apresentada a seguir mostra o processo de compressão de um
arquivo de imagem JPG. A Figura 4 mostra o processo de descompressão de um
arquivo de imagem JPG.
Figura 3 – Processo de Compressão JPEG
Fonte: SILVA, 1998.Figura 4 – Processo de Descompressão JPEG
Fonte: SILVA, 1998.3.1 Transformada Discreta do Cosseno (TDC)
A Transformada Discreta do Cosseno (TDC) é uma transformada
matemática baseada em cossenos, é muito utilizada em compressão de dados e
processamento digital de imagens.
Como é citado por Silva (1998, p. 4), a Transformada Discreta do Cosseno
é a chave do processo de compressão, onde ela transforma um conjunto de pontos do
domínio espacial em uma representação equivalente no domínio da freqüência. A
Transformada Discreta do Cosseno diminui a correlação, ou seja, eliminam-se as
redundâncias estatísticas. Outro aspecto importante é que os novos dados devem exigir
menos espaço ao mesmo tempo em que o algoritmo para obtê-los seja o mais eficiente
possível. A transformada utilizada no processo de compressão do padrão JPEG é a
TDC, que converte um bloco de pixels em uma matriz de coeficientes,
descorrelacionando a informação da imagem.
Os coeficientes (que foram transformados) iniciais do bloco contêm as
informações mais relevantes da imagem, sendo assim, deve-se garantir o
armazenamento de certo número de coeficientes com baixos índices de posição. Por
outro lado, como a transformada fornece uma série de cossenos, os coeficientes
reduzem em amplitude conforme os índices aumentam. Portanto, os coeficientes
podem ser quantizados por zona, diminuindo-os e eliminando os menos significantes,
obtendo o principal ganho na taxa de compressão (SILVA, 1998).
A Transformada Discreta do Cosseno é definida por:
onde:
C: Transformada Discreta do Cosseno
f: Valores da imagem original (nível de cinza)
N: Dimensão da imagem (ou bloco).
Para aplicar a TDC em uma imagem, é necessário, para agilizar os
cálculos e para uma melhor taxa de compressão, dividir a imagem original em blocos, 4
x 4, 8 x 8 ou 16 x 16, podendo chegar a usar até blocos de 32 x 32 ou 64 x 64.
Geralmente são usados blocos 8 x 8 (SILVA, 1998).
A Figura 5 mostra os resultados de compressão com tamanhos de blocos
variados.
Figura 5 – Resultados de Compressão com diferentes tamanhos de blocos
Fonte: SILVA, 1998.A Transformada Inversa do Cosseno (ITDC) é dada por:
O tempo necessário para computar cada elemento na TDC é dependente
do tamanho do bloco. O número de multiplicações para este caso é equivalente a N
2,
isto é, o tempo necessário para processar cada elemento na TDC aumenta
consideravelmente quando N aumenta. O total de cálculos necessários para realizar
uma transformada TDC é proibitivamente grande. A implementação da TDC, em geral,
deve dividir a imagem em blocos menores, mais rapidamente computáveis. O grupo
JPEG selecionou o bloco de tamanho 8 x 8 para ser o padrão (NELSON, 1991).
3.2 Quantização
Segundo Silva (1998, p. 14), a Transformada Discreta do Cosseno ocupa
mais espaço do que a matriz original, pois, enquanto os valores da matriz original são
do tipo inteiro, os coeficientes da transformada são reais. Para reduzir esses valores, é
realizada a quantização, que é o processo de reduzir o número de bits necessários para
armazenar um valor reduzindo a precisão de um inteiro. É na quantização que acontece
a perda da informação, ou seja, os valores dos coeficientes que eram reais passam a
ser inteiros, perdendo a parte decimal, porém reduzindo o número de bits necessários
para armazenar os valores.
O padrão JPEG, usa uma matriz Q[i][j] de quantização extremamente
testada por membros do comitê, que gera um nível estável e bom de compressão:
Q[i][j] = 1 + (1 + i + j) * fator_de _qualidade
No qual o fator_de_qualidade pode variar de 1 a 25. Valores maiores do
que 25 comprometem em muito a qualidade da imagem.
A Figura 6 mostra os resultados de compressão com diferentes fatores de
qualidade.
Figura 6 – Resultados de Compressão variando os fatores de qualidade aplicados a
uma imagem de 384 X 288 pixels com 1 byte por pixel, tamanho de 100.592 bytes.
Fonte: SILVA, 1998.
Dessa maneira os coeficientes associados as maiores freqüências são os
que sofrem as maiores reduções. Essa é uma quantização por zona, pois incide em
certas posições, ao invés de determinar quais os coeficientes são os mais importantes
para o bloco específico (SILVA, 1998).
Um algoritmo para gerar a matriz de quantização, poderia ser escrito
como o algoritmo:
for (i = 0; i < N; i ++)
for (j = 0; j < N; j++)
Q[i][j] = 1 + (1 + i + j)*fator_de_qualidade;
O próximo passo é quantizar os coeficientes da TDC:
Valor_quantizado[i][j] = Q[i][j]/DCT[i][j] arredondado para inteiro.
No processo de descompressão, opera-se de maneira inversa:
TDC[i][j] = Valor_quantizado[i][j] * Q[i][j]
3.3 Zig-zag
O algoritmo de JPEG comprime tão efetivamente devido ao fato de que
um número grande de coeficientes na imagem de TDC é truncado para zero durante o
método de quantização dos coeficientes. Tantos valores são setados para zero que o
comitê JPEG elegeu para manipular estes valores diferentemente de outros valores dos
coeficientes (SILVA, 1998).
Segundo Silva (1998, p. 31), como a quantização diminui a magnitude dos
coeficientes da TDC e aumenta o número de coeficientes com valores zero, se os
dados forem ordenados novamente agora usando a seqüência Zig-zag, mostrada na
Figura 7, os coeficientes de baixa freqüência são colocados na frente dos coeficientes
de alta freqüência.
Um esquema usado para reordenar estes elementos é conhecido como
zig-zag:
Figura 7 – Ziz-zag num bloco de 8 x 8
Fonte: NELSON, 1991.3.4 Codificação RLC
Segundo Silva (1998, p.18), a entropia de uma imagem é a medida de seu
conteúdo de informação. Se a entropia é alta, a informação de uma imagem tende a ter
pouca correlação, sendo assim, a informação de uma imagem de entropia alta
apresenta muita aleatoriedade e pouca redundância. Se a entropia é baixa, a
informação de uma imagem é mais previsível, apresenta pouca aleatoriedade e muita
redundância.
A entropia de uma imagem pode ser calculada como a probabilidade de
sua ocorrência. Isto é exibido como um número que representa o número de bits
necessários para representar aquela probabilidade. Para qualquer imagem, o calculo é
realizado como segue:
E = Nc x Nl x Nb
Onde:
E: entropia;
Nc: Número de colunas;
Nl: Número de linhas;
Nb: Número de bits por pixel.
Por exemplo: 640 x 480 x 8, teria a seguinte entropia:
E = 640 x 480 x 8 = 2.457.600.
Essa é a medida de entropia para qualquer caso 640 x 480 x 8 bit
imagem. Qualquer uma de 22.457.600 possíveis imagens diferente pode ser
representada por uma imagem desta resolução. A chance de uma imagem particular
com estas medidas ser idêntica à outra é de uma em 22.547.600 (SILVA, 1998).
Raramente as imagens são compostas de níveis totalmente variados, a
entropia atual de uma imagem normal geralmente será algo menor do que o cálculo
acima. Devido ao fato da quantidade de dados de uma imagem comum ser sempre
mais alta que a quantidade de dados de informação comum. A quantidade de
informação comum da imagem é denominada de entropia atual de uma imagem. A
técnica que codifica a entropia diminui redundâncias da imagem para ser utilizada em
códigos de tamanho variável. Isto pode ser feito codificando números variáveis de
pixels com código de tamanho fixo, ou codificando números fixos de pixels com códigos
de tamanhos variados (SILVA, 1998).
Como é citado por Silva (1998), codificação de imagem RLC tira proveito
do fato que vários pixels pertos em uma imagem tendem a ter o mesmo valor de nível.
Dessa forma podem-se agrupar os pixels de nível idênticos em códigos únicos,
reduzindo assim, a redundância da imagem.
Na codificação RLC a imagem original é analisada começando do primeiro
pixel do canto superior esquerdo, do primeiro pixel em diante é seguido o vizinho pela
linha, são determinados quantos pixels seguidos tem o mesmo valor. Se o próximo ou
mais pixels em seqüência possui o mesmo valor de nível como o primeiro então eles
são todos representados por um novo código. O novo código é formado por dois
valores, o primeiro com o valor de nível e o segundo com a quantidade de pixels que
possuem o mesmo valor. Em seguida move para o próximo pixel na linha com um novo
valor de nível e o processo se repete. Quando a linha é finalizada, o processo passa
para o começo da próxima linha. Assim, o processo continua até que a última linha da
imagem seja alcançada e finalizada.
Se, por exemplo, 10 pixels em seqüência tivessem o valor semelhante de
nível de 80, eles seriam transformados nos valores 80|10 (nível|quantidade). Os 10
bytes de dados necessários para representar 10 pixels da imagem original são
comprimidos para somente 2 bytes (BAXES, 1994).
A Figura 8 apresentada a seguir mostra um exemplo da operação
Run-Length Coding.
Figura 8 – A operação Run-Length Coding
Fonte: SILVA, 1998.Como é citado em Silva (1998), uma imagem codificada com o RLC é
decodificada ampliando cada código gerado. O nível de cada código é repetido pela
linha da imagem para o número de pixels indicado pelo valor de duração adjunto.
Segundo Silva (1998), em imagens binárias, este método possibilita
grandes taxas de compressão. Porém, se os pixels vizinhos não forem iguais, a
codificação pode resultar em um tamanho maior do que a imagem original.
Por exemplo:
78 81 90 - pixels de uma imagem
78 01 81 01 90 01 - codificação RLC
A região da imagem possui 3 bytes, já a codificação precisa de 6 bytes
para armazenamento, ou seja, o dobro da imagem original.
3.5 Codificação por Huffman
Outra técnica usada para a codificação de entropia é a de Huffman,
desenvolvida em 1952, por D. A. Huffman. A codificação de Huffman transforma o valor
do nível de pixel da imagem original em um novo código de tamanho variável, onde,
este novo código é baseado nas freqüências de ocorrência na imagem. Desta forma,
são atribuídos níveis que freqüentemente acontecem em códigos menores, e são
atribuídos níveis que acontecem sem muita freqüência em códigos maiores. O resultado
é que a imagem comprimida exigirá menos bits globais para demonstrar a imagem
original (SILVA, 1998).
O método de compressão de Huffman inicia olhando o histograma de nível
de uma imagem. A freqüência de ocorrência para todo nível na imagem é analisada
pelo histograma. Os valores de nível são ordenados pelas freqüências de ocorrência
em luma lista, onde o código de Huffman atribui novos códigos para cada valor de nível.
Os códigos atribuídos possuem tamanhos variados; os códigos menores são atribuídos
primeiros (mais freqüente) valores na lista e, eventualmente, os códigos mais longos
são atribuídos últimos (menos freqüente) valores na lista. For fim, a imagem comprimida
é criada substituindo os códigos de valor de nível de tamanho variável para o original
código de valor de nível de 1 byte (SILVA, 1998).
A Figura 9 mostra um exemplo de imagem, no qual será aplicada a
codificação de Huffman.
Figura 9 – Imagem com 640 X 480 pixels
Fonte: SILVA, 1998.A Figura 10 mostra o histograma da Figura 9 com o número de pixels de
cada nível de cinza.
Figura 10 – Histograma da imagem original com o número de pixels de cada nível de
cinza
Fonte: BAXES, 1994.
Os códigos de Huffman são atribuídos criando a árvore de Huffman que
emparelha os valores de nível baseado nas suas freqüências combinadas de
ocorrência. A árvore de Huffman assegura que os códigos maiores são atribuídos
freqüentemente os de menos níveis e vice-versa (BAXES, 1994).
A Figura 11 mostra a árvore de Huffman gerada a partir do histograma da
imagem.
Figura 11 – Árvore de Huffman
Fonte: BAXES, 1994.A Figura 12 mostra a codificação de Huffman que foi gerada para a
imagem.
Figura 12 – Codificação de Huffman
Fonte: BAXES, 1994.Segundo Silva (1998), o código de Huffman é tão pequeno quanto um bit
e podendo chegar ao valor máximo de sete bits. O maior código de Huffman nunca
pode ser superior que o número de níveis diferentes na imagem (no caso, oito) menos
um. Embora uma imagem codificada pelo Huffman possa ter alguns níveis com códigos
muito longos, as suas freqüências de ocorrências sempre são estatisticamente baixas.
A decodificação de imagem Huffman inverte o processo de compressão
substituindo o valor original pelo valor da codificação de Huffman. A codificação por
Huffman gera uma razão de redução do código de 1.5:1 a 2:1 (SILVA, 1998).
4
PROJETO
4.1 Descrição das Atividades Realizadas
4.1.1 Inserção de mensagem na imagem
Foi desenvolvida uma função para aplicar o conceito de esteganografia
em arquivos de imagem, essa função tem como objetivo inserir uma mensagem nos bits
menos significativos de cada pixel da imagem. Para guardar uma letra na imagem são
necessários oito pixels, pois uma letra é representada por oito bits, sendo assim, cada
bit da letra é inserido em um pixel. E, por fim, é inserida na imagem uma marcação de
fim de mensagem, a marcação utilizada nesse caso foi inserir no fim da mensagem três
asteriscos, para ser possível identificar o término da mensagem inserida.
A Figura 13
mostra o código da inserção de uma mensagem em uma
imagem.
1 public void escreveMsg(String msg)
2 {
3 msg=msg+"***";
4 int contBits=0, cont = 0;
5 char charAtual = msg.charAt(0);
6 char aux;
7 int l, c, pixel[] = {0, 0, 0, 0};
8 WritableRaster raster = bImage.getRaster();
9 for (l=0 ; l<bImage.getHeight() && cont<msg.length(); l++)
10 for (c=0 ; c<bImage.getWidth() && cont<msg.length(); c++) {
11 raster.getPixel(c,l,pixel); //obtem um pixel
12 if (contBits<8){
13 aux=charAtual;
14 //vai deslocando o aux utilizando o contBits, que se desloca 8
vezes, pegando assim todos os bits do caracter e salva cada bit do caracter em um bit menos significativo do pixel da imagem.
15 if ((char)(aux<<(contBits)+8)>>(7+8) == 1) //desloca pra direita e
pega o bit pelo contBits
16 pixel[0]= pixel[0]|1;
17 else pixel[0]= pixel[0]&(~1);
18 raster.setPixel(c,l,pixel);
19 contBits++;
21 else {
22 //após 8 bits significa que terminou de gravar um caracter
23 cont++;
24 contBits = 0;
25 if (cont<msg.length())
26 charAtual =msg.charAt(cont); //pega o próximo caracter a ser
gravado na imagem
27 }
28 }
29 }
Figura 13 – Código de Inserção de mensagem na imagem
4.1.2 Leitura da mensagem embutida na imagem
Outra função foi desenvolvida, esta com o objetivo de extrair uma possível
mensagem da imagem. Nessa função a leitura de 8 pixels forma uma letra, onde em
cada pixel é extraído o valor do bit menos significativo, depois de lidos 8 pixels é
possível formar um caracter. Dessa forma é feita a leitura na imagem até que se
encontre a marcação de fim de mensagem.
A Figura 14
mostra o código da leitura de uma mensagem em uma
imagem.
1 public String lerMsg()
2 {
3 String msg = "",aux = "";
4 int qtdChar=0,contBits=0,cont=0,mascara=1,tam,l,c,pixel[]={0, 0, 0, 0};
5 char buffer=0,char1,char2,char3;
6 WritableRaster raster = bImage.getRaster();
7 for (l=0 ; l<bImage.getHeight() ; l++)
8 for (c=0 ; c<bImage.getWidth() ; c++) {
9 raster.getPixel(c,l,pixel); //obtem um pixel
10 cont++;
11 if (msg.length()>3) {
12 //Quando encontrar *** significa que a mensagem acabou
13 tam=msg.length();
14 char1=msg.charAt(tam-1);
15 char2=msg.charAt(tam-2);
16 char3=msg.charAt(tam-3);
17 if ((char1=='*') && (char2=='*') && (char3=='*')) {
18 for (int i=0; i<=msg.length()-4; i++)
20 msg=aux;
21 return(msg);
22 }
23 }
24 if (contBits<8){
25 //Lê 8 bits, para poder formar um caracter
26 if (contBits==0) {
27 if ((pixel[0] & mascara)==1)
28 buffer = (char)((buffer)|1); //desloca um bit pra esquerda e coloca
o bit um
29 else buffer = (char)((buffer)&(~1)); //desloca um bit pra esquerda
e coloca o bit zero
30 }
31 else {
32 if ((pixel[0] & mascara)==1)
33 buffer = (char)((buffer<<1)|1); //desloca um bit pra esquerda e
coloca o bit um
34 else buffer = (char)((buffer<<1)&(~1)); //desloca um bit pra esquerda
e coloca o bit zero
35 }
36 contBits++;
37 }
38 else{
39 //Depois de formar um caracter ele é concatenado com a mensagem e
depois começa a ler outro caracter
40 contBits = 0; 41 msg = msg + (char)buffer; 42 buffer=0; 43 } 44 } 45 return msg; 46 }
Figura 14 – Código de leitura da mensagem na imagem
4.1.3 Aplicação de esteganografia em arquivos de imagem BMP
A técnica de esteganografia foi primeiramente aplicada em arquivos de
imagem BMP, ao qual apresentou resultados satisfatórios, pois as mensagens inseridas
nos bits menos significativos de cada pixel foram recuperados após a imagem ser salva,
isto é, devido ao fato de que o padrão de imagem BMP não sofrer nenhum tipo de
compressão.
4.1.4 Aplicação de esteganografia em arquivos de imagem JPG
Posteriormente, essa técnica foi aplicada igualmente em arquivos de
imagem JPG, onde após a leitura da imagem foi inserida uma mensagem em seus bits
menos significativos e então a imagem foi salva. Após os testes com imagens do
padrão JPG, foi possível perceber que essa não apresentou resultados satisfatórios,
pois após a imagem ser salva, os dados inseridos foram perdidos, isto é, devido ao fato
de que o padrão de imagem JPG sofrer compressão com perda, ou seja, devido às
transformações pelo qual a imagem passa a informação é perdida.
4.1.5 Inserção da mensagem após realizar etapas de compressão usando
funções desenvolvidas
A Figura 15 representa a primeira técnica que foi implementada, esta
técnica consiste em desenvolver funções para serem utilizadas no processo de inserção
e leitura da mensagem.
Figura 15 – Técnica 1: Criar funções
Após alguns testes com imagem JPG, foi iniciado um estudo das etapas
que são realizadas na compressão do padrão de imagem JPG, a partir do qual é
possível saber se existem possibilidades de inserir a mensagem em algumas dessas
etapas e, posteriormente, conseguir recuperar a mensagem inserida. Algumas dessas
etapas, tais como: a Transformada Discreta do Cosseno, a Transformada Inversa do
Cosseno, a quantização e sua inversa, foram implementadas como formas de tentativas
de inserção da mensagem, onde é possível verificar se, após a inserção da mensagem
ocorre ou não perda dos dados inseridos em algum dos passos anteriormente citados.
A Figura 16 mostra o código da Transformada Discreta do Cosseno e da
quantização.
1 public void dct()
2 {
3 int qtdBL=(int)bImage.getWidth()/8, qtdBC=(int)bImage.getHeight()/8;
5 for (int c=0;c<qtdBC;c++)
6 dct_bloco(l,c); //o cálculo da TDC é realizado em blocos
7 }
8
9 public void dct_bloco(int l, int c) {
10 int pixel[] = {0, 0, 0, 0};
11 double tmp;
12 for (int i = 0; i < tam; i++) { //percorre a imagem
13 for (int j = 0; j < tam; j++) { //percorre a imagem
14 ret[i+l*8][j+c*8] = 0;
15 for (int x = 0; x < tam; x++) {
16 for (int y = 0; y < tam; y++) {
17 raster.getPixel(y+c*8,x+l*8,pixel); //obtem um pixel da imagem
18 tmp = pixel[0]; //zera o variável
19 tmp *= Math.cos((2*y + 1) * j * Math.PI/(2*tam)); //cálculo da TDC
20 tmp *= Math.cos((2*x + 1) * i * Math.PI/(2*tam)); //cálculo da TDC
21 ret[i+l*8][j+c*8] += tmp; //cada ponto da matriz resultante é a
soma dos produtos do cosseno de todos os valores de um bloco.
22 }
23 }
24 ret[i+l*8][j+c*8] *= i==0?1.0/Math.sqrt(tam):Math.sqrt(2.0/tam);
25 //se o valor de i for 0, então o cálculo é 1 sobre a raiz quadrada do
tamanho do bloco, se o valor de i for 1, então o cálculo é raiz quadrada de 2 sobre o tamanho do bloco.
26 ret[i+l*8][j+c*8] *= j==0?1.0/Math.sqrt(tam):Math.sqrt(2.0/tam);
27 //se o valor de j for 0, então o cálculo é 1 sobre a raiz quadrada do
tamanho do bloco, se o valor de j for 1, então o cálculo é raiz quadrada de 2 sobre o tamanho do bloco.
28 }
29 }
30 //Quantização
31 for (int i = 0; i < tam; i++) {
32 for (int j = 0; j < tam; j++) {
33 Valor_Quantizado[i+l*8][j+c*8]=Math.round(ret[i+l*8][j+c*8]/Q[i][j]);
34 //valor quantizado é a TDC dividida pela matriz de quantização (Q).
35 System.out.print((int)Valor_Quantizado[i+l*8][j+c*8]+" ");
36 }
37 System.out.println("");
38 }
39 }
Figura 16 – Código da TDC e Quantização
A Figura 17 mostra o código da inversa da quantização e da Transformada
Inversa do Cosseno.
1 public void inv_dct()
2 {
3 int qtdBL=(int)bImage.getWidth()/8, qtdBC=(int)bImage.getHeight()/8;
4 for (int l=0;l<qtdBL;l++)
6 inv_dct_bloco(l,c);
7 }
8 public void inv_dct_bloco(int l, int c) {
9 int pixel[] = {0, 0, 0, 0};
10 double tmp;
11 double[][] i_ret = new double[tam][tam];
12 //Inversa da Quantização
13 //na inversa é realizada primeiro a quantização
14 for (int i = 0; i < tam; i++) {
15 for (int j = 0; j < tam; j++)
16 ret[i+l*8][j+c*8]=Valor_Quantizado[i+l*8][j+c*8]*Q[i][j];
17 //no qual a matriz resultante recebe a operação inversa da
quantização
18 }
19 for (int x = 0; x < tam; x++) { //percorre a imagem
20 for (int y = 0; y < tam; y++) { //percorre a imagem
21 i_ret[x][y] = 0; //zera
22 for (int i = 0; i < tam; i++) {
23 for (int j = 0; j < tam; j++) {
24 tmp = ret[i+l*8][j+c*8];
25 tmp *= Math.cos((2*y + 1) * j * Math.PI/(2*tam)); //cálculo da ITDC
26 tmp *= Math.cos((2*x + 1) * i * Math.PI/(2*tam)); //cálculo da ITDC
27 tmp *= i==0?1.0/Math.sqrt(tam):Math.sqrt(2.0/tam);
28 //se o valor de i for 0, então o cálculo é 1 sobre a raiz quadrada
do tamanho do bloco, se o valor de i for 1, então o cálculo é raiz quadrada de 2 sobre o tamanho do bloco.
29 tmp *= j==0?1.0/Math.sqrt(tam):Math.sqrt(2.0/tam);
30 //se o valor de j for 0, então o cálculo é 1 sobre a raiz quadrada
do tamanho do bloco, se o valor de j for 1, então o cálculo é raiz quadrada de 2 sobre o tamanho do bloco.
31 i_ret[x][y] += tmp;
32 //cada ponto da matriz resultante é a soma dos produtos do cosseno
e dos coeficientes de todos os valores de um bloco.
33 }
34 }
35 }
36 }
37 for (int i = 0; i < tam; i++) {
38 for (int j = 0; j < tam; j++) {
39 System.out.print(Math.round(i_ret[i][j])+" "); //exibe o resultado
40 //pixel[0]=pixel[1]=pixel[2]=(int)i_ret[i][j]; //somente com cinza
41 //atualiza os valores dos pixels na imagem
42 raster.getPixel(j+c*8,i+l*8,pixel); 43 if (i_ret[i][j]>255) 44 pixel[0]=255; 45 else 46 pixel[0]=(int)i_ret[i][j]; 47 raster.setPixel(j+c*8,i+l*8,pixel); 48 } 49 System.out.println(""); 50 } 51 }
Posteriormente à implementação dessas etapas, foram realizados testes
para gravar a mensagem e verificar se a mensagem gravada não foi perdida. A
mensagem foi inserida após realizar a Transformada do Cosseno e a Quantização, pois
após a realização da quantização concluiu-se que os últimos pixels do canto inferior
direito de um bloco tendem a receber o valor zero. Dessa forma, pensou-se que
armazenando um caracter nestes valores ele não seria perdido. Pela inserção de um
caracter no último pixel do bloco, foi possível perceber que quando o valor é baixo não
há alteração significativa na imagem, já quando o valor é mais alto a imagem sofre
algumas alterações perceptíveis para a visão humana. Após a gravação de um
caracter, foi realizado o cálculo da inversa da Quantização e a Transformada Inversa do
Cosseno para que assim a imagem voltasse para o domínio espacial, em seguida a
imagem foi salva. Para verificar se a mensagem não foi perdida a imagem foi lida
novamente e foi realizado o cálculo da Transformada Discreta do Cosseno e da
Quantização para que a imagem mude para o domínio da freqüência, já que foi nesse
domínio que a mensagem foi inserida, posteriormente foram verificados os últimos
pixels de cada bloco, comparando se a mensagem que foi inserida ainda estava
presente no corpo da imagem. Concluiu-se que a mensagem inserida não foi mantida
após sofrer as etapas de compressão que o JPG realiza.
4.1.6 Replicação da informação
A Figura 18 representa a segunda técnica implementada, essa técnica
consiste em replicar a mensagem no corpo de uma imagem.
Figura 18 – Técnica 2: Replicação da informação
Também foi desenvolvida a técnica de replicação dos dados, essa técnica
consiste em gravar uma mensagem replicando cada bit do caracter várias vezes, por
exemplo, replicar cada bit de um caracter oito vezes, sendo assim no momento da
gravação de uma mensagem cada caracter da mensagem seria gravado oito vezes na
imagem. E, por fim, é inserida na imagem uma marcação de fim de mensagem, a
marcação utilizada nesse caso foi inserir no fim da mensagem três asteriscos, para ser
possível identificar o término da mensagem inserida, esses três asteriscos também
serão armazenados em replicação.
A Figura 19 mostra o código da inserção de uma mensagem replicada em
uma imagem, nesse exemplo de código foi usada a replicação de 100 vezes, ou seja, o
mesmo caracter é gravado na imagem 100 vezes.
1 public void escreveMsgR(String msg){
2 String m="";
3 int contBits=0, cont = 0;
4 char charAtual;
5 char aux;
6 int i,l,c, pixel[] = {0, 0, 0, 0};
7 WritableRaster raster = bImage.getRaster();
8 msg=msg+"***"; 9 for (i=0;i<msg.length();i++) { 10 for (c=0;c<100;c++){ 11 m=m+msg.charAt(i); 12 } 13 } 14 System.out.println(m); 15 charAtual = m.charAt(0);
16 for (l=0 ; l<bImage.getHeight() && cont<m.length(); l++)
17 for (c=0 ; c<bImage.getWidth() && cont<m.length(); c++) {
18 raster.getPixel(c,l,pixel); //obtem um pixel
19 if (contBits<8){
20 aux=charAtual;
21 if ((char)(aux<<(contBits)+8)>>(7+8) == 1) //desloca pra
direita e pega o bit pelo contBits
22 pixel[0]= pixel[0]|1;
23 else pixel[0]= pixel[0]&(~1);
24 raster.setPixel(c,l,pixel); 25 contBits++; 26 } 27 else{ 28 cont++; 29 contBits = 0; 30 if (cont<m.length()) 31 charAtual =m.charAt(cont); 32 } 33 } 34 }
Figura 19 – Código de inserção de uma mensagem replicada na imagem
A Figura 20 mostra o código da leitura de uma mensagem replicada em
uma imagem, nesse exemplo de código foi usada a replicação de 100 vezes, ou seja,
devem ser lidos 100 caracteres e aquele que aparecer mais vezes é o escolhido para
formar a mensagem.
1 public String lerMsgR(){
2 String msg = "";
3 String aux = "";
4 char vet[] = new char[100];
5 int qtdChar=0,contBits=0, cont = 0, mascara = 1,tam,contAux=0;
7 int i, j, l, c, pixel[] = {0, 0, 0, 0};
8 WritableRaster raster = bImage.getRaster();
9 char maior = '\0';
10 int qtdemaior, qtde;
11 for (l=0 ; l<bImage.getHeight() ; l++)
12 for (c=0 ; c<bImage.getWidth() ; c++) {
13 raster.getPixel(c,l,pixel); //obtem um pixel
14 cont++; 15 if (msg.length()>3) 16 { 17 tam=msg.length(); 18 char1=msg.charAt(tam-1); 19 char2=msg.charAt(tam-2); 20 char3=msg.charAt(tam-3);
21 if ((char1=='*') && (char2=='*') && (char3=='*'))
22 {
23 for (int x=0; x<=msg.length()-4; x++)
24 aux=aux+msg.charAt(x); 25 msg=aux; 26 return(msg); 27 } 28 } 29 if (contBits<8){ 30 if (contBits==0) 31 {
32 if ((pixel[0] & mascara)==1)
33 buffer = (char)((buffer)|1); //desloca um bit pra esquerda e
coloca o bit um
34 else buffer = (char)((buffer)&(~1)); //desloca um bit pra esquerda
e coloca o bit zero
35 }
36 else
37 {
38 if ((pixel[0] & mascara)==1)
39 buffer = (char)((buffer<<1)|1); //desloca um bit pra esquerda e
coloca o bit um
40 else buffer = (char)((buffer<<1)&(~1)); //desloca um bit pra
esquerda e coloca o bit zero
41 } 42 contBits++; 43 }else{ 44 contBits = 0; 45 vet[contAux]=(char)buffer; 46 buffer=0; 47 if (contAux<99) 48 contAux++; 49 else{ 50 contAux=0; 51 maior = vet[0]; 52 qtdemaior = 1; 53 for (i=0;i<99;i++){ 54 qtde = 1; 55 for (j=i+1;j<100;j++) 56 if (vet[i] == vet[j]) 57 qtde++;
58 if (qtde>qtdemaior) { 59 qtdemaior = qtde; 60 maior = vet[i]; 61 } 62 } 63 msg = msg + (char)maior; 64 System.out.println(msg); 65 } 66 } 67 } 68 return msg; 69 }