+ All Categories
Home > Documents > TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Date post: 26-Oct-2014
Category:
Upload: josquin-corrales
View: 101 times
Download: 2 times
Share this document with a friend
Description:
Uploaded from Google Docs
Popular Tags:
76
TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation by Josquin S Corrales Prepared For Dr. Yacoub El-Ziq MatrixView USA February 8, 2007
Transcript
Page 1: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation

by

Josquin S Corrales

Prepared For

Dr. Yacoub El-Ziq

MatrixView USA

February 8, 2007

Page 2: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Table of Contents

Overview .................................................................................................................................................. 3Development Platform Configuration .................................................................................................. 3

TIFF to GIF Conversion ........................................................................................................................... 4Reference TIFF to GIF Converter Design ............................................................................................4TIFF File Format2 ................................................................................................................................ 4GIF File Format ....................................................................................................................................4

Embedded LZW ........................................................................................................................................ 8Device Driver ...................................................................................................................................9DataFlow: ........................................................................................................................................ 9malloc/xil_malloc .......................................................................................................................... 11EDK Debugger .............................................................................................................................. 13

Fast Simplex Link ................................................................................................................................... 13LZW Compression Algorithm..................................................................................................................13Appendix A: Stand Alone Re/TIFF Sources ........................................................................................... 14Appendix B: Microblaze Implementation Sources ................................................................................. 37

Page 3: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Overview

The project objective was to develop a chip design that performed image file format conversion for an input TIFF to output GIF. In order to simplify the process, the projected was divided into three parts.

Part I demonstrates a C version of the converter than runs on common x86 architectures in order to gain an understanding of TIFF and GIF file formats. No specialized hardware or chip was used.

Part II demonstrates porting the C converter an embedded processor running on an FPGA using IP cores provided by the Xilinx Embedded Development Kit (EDK) and the development board support packages (BSP).

Part III demonstrates a Verilog module that performs the data conversion.

Development Platform Configuration

Software

Windows Xp Home Edition with Service Pack 2 Xilinx Integrated Software Environment (ISE) Release Version 6.3.03i Xilinx Embedded Development Kit (EDK) Release Version 6.3 Microsoft Visual C++ Version 6.0 Development Environment Cygwin UNIX emulation for Windows (DLL Version 1.5.18) utilites including gcc (GCC) 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125) ImageMagick's "convert" utility and source coders/gif.c (ImageMagick-6.2.8) with giflib-4.1.4 by Eric S. Raymond, and tiff-3.8.2 by Sam Leffler

Hardware

Spartan-3 LC development kit (DS-KIT-3SLC400 Rev 2)1 from AVNET, formerly Memec Design Serial port connect PC to dev board.

The Spartan-3 LC development board features the 400K-gate Xilinx Spartan-3 device

(XC3S400-4PQ208CES) in the 208-pin quad flat-pack package.

Page 4: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Figure 1: Spartan-3 LC development

TIFF to GIF Conversion

TIFF -> Re/TIFF -> GIF

Reference TIFF to GIF Converter Design

Re/TIFF LZW encoder sources were based upon an open source tool from ImageMagick (ImageMagick-6.2.8) which links against the giflib-4.1.4 for a working 12-bit implementation of the LZW compression algorithm. Uncompressed GIF images can be produced by setting the compile options to utilize libungif-4.1.4.

TIFF File Format2

Figure 2: TIFF File Format

GIF File Format

The elements of the GIF include the internals/mechanics of reader (aka decoder) and the writer (aka encoder). There are rules that define how the encoder and decoder work in the GIF specification3. Due to legal issues associated with LZW encoding, developers have devised GIF images using uncompressed data also know as an "ungif" Image Data block.

Page 5: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

The GIF file format follows a grammar that provides a division of the byte steam and high level overview. The basic definition of the GIF allows for a data stream to contain only the header, the logical screen descriptor, a global color table and a trailer. This will define a GIF image, which can be processed by viewer without error, but will not display any picture because it does not contain image data block.

The Grammar.

<GIF Data Stream> ::= Header <Logical Screen> <Data>* Trailer

<Logical Screen> ::= Logical Screen Descriptor [Global Color Table]

<Data> ::= <Graphic Block> |

<Special-Purpose Block>

<Graphic Block> ::= [Graphic Control Extension] <Graphic-Rendering Block>

<Graphic-Rendering Block> ::= <Table-Based Image> |

Plain Text Extension

<Table-Based Image> ::= Image Descriptor [Local Color Table] Image Data

<Special-Purpose Block> ::= Application Extension | Comment Extension

The header contains some constant values that describe the file format that follows, sometimes referred to as the "Magic Number". The Logical Screen Descriptor contains the image width, height, global color table flag, along with other settings that define the format of the data stored in the Image Data block. The Global Color Table contains red-green-blue (RGB) color triplets in three sets of octets (e.g. 24-bits of RGB color entires). This block defines a maximum of 256 RGB entries and at a very basic level each Image Data octet is an index into this color table.

The Image Descriptor is a header type block that specifies left position, top, width, height and other data of the Image Data block that follows. The Image Data block specifies the LZW Minimum Code size and the Image Data represented by codewords output by the LZW compression algo. This is the heart of how GIFs store image data.

The details of how LZW compression is used to produce the codewords stored in the Image Data block is as follows. LZW is a lossless compression scheme because no round off errors or quantization occurs as in the application of transforms (e.g. wavelets) or other schemes. LZW compression operates by reading the input data, and then producing fixed length output codewords that are used to substitute longer running data input sequences. The codewords are devised by advancing an internal state machine counter called the "string table".

Two special code words are added and enumerated to the string table which are the "clear code" and "end of stream code". The "clear" codeword provides the key to the uncompressed gif format. When the clear codeword is encounted by the LZW decoder, it resets the internal string table state machine.

Uncompressed GIFs are image files that do not use LZW compression to compress their image data but are still recognizable as GIF by decoders which expect LZW compression image blocks. The idea is to

Page 6: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

emit only single-symbol string codes, plus a Clear code every so often to keep the decoder from increasing the code width. The GIF byte order is little-endian. TIFF which has a designator for either.

Sample output run

jsc01@LOCALHOST ~/im

$ ls -aFl hi_uc.tiff

-rw-r--r-- 1 jsc01 None 17130 Nov 2 16:13 hi_uc.tiff

jsc01@LOCALHOST ~/im

$ ./retiff hi_uc.tiff hi_retiff.gif debug

IFD offset 4224

IFD records 16

4226 Tag fe Type 4

4232 Tag 100 Type 3

cols 132

423e Tag 101 Type 3

rows 115

424a Tag 102 Type 3

bps 8

size 15180 from row x cols

4256 Tag 103 Type 3

4262 Tag 106 Type 3

426e Tag 10d Type 2

427a Tag 111 Type 4

strip count 15

strip offset 1632

4286 Tag 115 Type 3

4292 Tag 116 Type 4

rows per strip 8

429e Tag 117 Type 4

strip byte counts offset 69c

42aa Tag 11a Type 5

Page 7: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

42b6 Tag 11b Type 5

42c2 Tag 128 Type 3

42ce Tag 131 Type 2

42da Tag 140 Type 3

colormap size 768

colormap offset 80

Strip byte sizes:

offset 0 byte size 1056

offset 13 byte size 1056

offset 14 byte size 396

TIFF image size 15180 from byte counts

Strip offsets:

offset 0 is 6d8

offset 13 is 3c78

offset 14 is 4098

Read image data

0. Read 0420 bytes of 0420 byte counts, offset 0006d8

13. Read 0420 bytes of 0420 byte counts, offset 003c78

14. Read 018c bytes of 018c byte counts, offset 004098

EncodeGIF

clear code 100

end of information code 101

clear code 00

69 08 1c 48 b0 a0 c1 83 08 13 2a 5c c8 b0 a1 c3 87 10 23 4a 9c 48 b1 a2 c5 8b 18 33 6a dc c8 b1 a3 c7 8f 20 43 8a 1c 49 b2 a4 c9 93 28 53 aa 5c 89 12 c5 89 14 2f 53 a0 60

1. wrote 0x0420 bytes

49 53 24 cc 14 38 53 a8 d0 a9 b3 a6 4f 8d 38 4f c4 5c b1 73 85 51 16 44 7f 2a 9d a8 d3 e5 4b 15 46 a1 aa 60 d1 02 69 8a a5 58 1b 36 3d 81 e2 83 09 13 42 85 b6 70 c1 02 a9 0a 15 21 4f 7c 5d 6b a2 26 d1 a0 5c 99 e2 ec ea 15

Page 8: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

ec 5c 9c 53 cb 5a f5 f8 f2 c3 88 0f 80 01 bf 54 c9 42 a8 09 12 1f 38 70 00 7b 22 22 ce c0 24 ec ea 24 fa 36 45 55 16 57 37 7e 05 7c 18 31 60 11 1f 48 e0 34 89 99 84 07 0e 19 32 54 98 70 81 c3 07 14 53 1d c2 0c 1c da 6e 51 b3 38 57 90 5d 91 19 a3 89 0d ae 23 a7 f0 0c 98 84 71 d1 24 51 78 46 9d c1 02 85 09 cf 33 90 38 d1 02 2d c3 e1 80 83 87 8e fc d4 e8 64 15 64 7b

length 254

5b 34 a1 d8 b5 eb 13 1f 36 5c b8 b0 3d f4 07 f1

2. wrote 0x0420 bytes

15. wrote 0x018c bytes

5f 1e e7 0a 17 32 6c e8 f0 21 c4 88 12 17 c6 80 91 c2 84 09 12 26 4e a4 48 a1 62 05 0b 18 2f 26 4a cc 18 21 82 04 0a 16 32 54 10 38 e1 41 04 0a 19 32 5c c0 b0 21 03 07 0e 24 77 f2 ec c9 d3 85 8b 13 27 36 ae f8 18 63 a4 4f 87 2c 48 6c 38 b9 92 c3 87 0f 19 2c 50 a8 80 61 e6 06 a8 22 3e ac 48 ea f5 6b d2 17 2e 5e 90 85 11 03 ac c3 0f 24 38 08 dc e0 f6 e6 4c 9c 1c b2 72 20 41 02 21 da bc 7a f7 f6 5c 7a 22 ea cc 0b 71 39 64 a0 ab 96 c4 89 b3 7c 17 33 6e 4c 83 05 0a 15 76 37 54 10 9c 33 67 54 c4 27 60 38 ee ec 19 ac 8b 8e 29 a2 42 1d 41 22 aa 08 8c 2c 14 7f 6e ed 7a 22 d9 14 1c 3f 60 14 8a 51 c5 0b d6 af 77 f3 66 28 b6 e3 c7 e0 64 7b 13 2f ae 70 ac c8 e4 c6 97 33 6f ee fc 39 f4 e8 d2 a7 53 5f 1e 10

19cf bytes of 3b4c bytes compressed

Done.

Figure 3: MSVC++ Binary View of File hi_retiff.gif used to verify correctness of output file format bytes

Figure 4: hi_retiff.gif image file

Embedded LZW

Several factors changed to nature of the assignment including the file format of TIFF in that it is not directly serializable and can be up to 2 GB in size.

Page 9: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Device Driver

Device driver API allow access to VHDL and Verilog IP cores from an embedded processor application.

UART Timing

universal asynchronous receiver/transmitter interrupt based data I/O

DataFlow:

TIFF file -> Re/TIFF (host cpu) -> UART -> LZW (fpga) -> UART -> Re/TIFF (host cpu) -> GIF file

The Xilinx Platform Studio (XPS) includes a wizard to design an embedded processor system. The EDK provides the VHDL IP cores listed Table in listed in cores which map to the Spartan-3 LC development hardware. The mapping is set via an Microprocessor Hardware Specification (MHS) file (e.g. System.mhs). An MHS file defines the configuration of the embedded processor system, and includes the Bus architecture, Peripherals, Processor, Connectivity, and Address space.4 The Base System Builder (BSB) wizard is a software tool that help users quickly build a working embedded processor system targeted at a specific development board.

Peripheral HW Ver Instance

microblaze 3.00.a Microblaze_0

opb_mdm 2.00.a debug_module

lmb_bram_if_cntlr 1.00.b dlmb_cntlr

lmb_bram_if_cntlr 1.00.b ilmb_cntlr

bram_block 1.00.a lmb_bram

opb_uartlite 1.00.b RS232

opb_gpio 3.01.b LEDs_4Bit

opb_gpio 3.01.b LED_7Segment

opb_gpio 3.01.b Push_Buttons_1Bit

opb_gpio 3.01.b DIP_Switches_4Bit

opb_intc 1.00.c opb_intc_0

Table 1: Hardware Platform Specification which maps to the System.mhs file

Serial Port Communication Parameters: 115,200 baud, 8 data bits, 1 parity bit, 50 MHz clock rate.

115200

Page 10: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

8

0

1

50000000

Figure 5: MicroBlaze Processor Reference Guide. Embedded Development Kit EDK 6.3i. UG081 (v4.2) November 18 2004, pp 12.

Figure 6: Spartan3 LC Board Hardware Components

Page 11: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Figure 7: RS232 interface to the UART device, processor core, and BRAM5.

The text number plus the data and bss represent the total memory consumed by the embedded design.

At GMT date and time: 2007:1:14:15:55:43

Command bash -c "cd /xygdrive/d/design/m3d5/; mb-size D:/design/m3d5/tiff2gif/executable.elf; exit;" Started...

text data bss dec hex filename

3356 3216 12 6584 19b8 D:/design/m3d5/tiff2gif/executable.elf

Done.

malloc/xil_malloc

These calls are unimplemented for the Spartan-3 with this version of the EDK. There are Xilinx tech notes explaining that their usage does not properly release memory back to the embedded processor.

Page 12: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Figure 8: System.pbd

Table 1: Summary of Spartan-3 FPGA Attributes

Device

System

Gates

Equivalent

Logic Cells

CLB Array

(One CLB = Four Slices) Distributed

RAM (bits1)

Block RAM

(bits1)

Dedicated

Page 13: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Multipliers DCMs

Maximum

User I/O

Maximum

Differential

I/O Pairs

XC3S4002 400K 8,064 32 28 896 56K 288K 16 4 264 1166

EDK Debugger

Fast Simplex Link

This part of the assignment is <<<TBD>>>, but can be accomplished via the On-chip Peripheral Bus Fast Simplex Link IP (opb_fsl). FSL provides a bootstrap device driver interface into the MicroBlaze processor, VHDL entity bus, and provisions for custom Verilog module integration.

LZW Compression AlgorithmTerry A. Welch describes the Lempel-Ziv Welch (LZW) algorithm in a paper titled, "A Technique for High-Performance Data Compression", in the June 1984 IEEE volume 17, issue 6 publication on page 15. The value of this compression algorithm lies in its fast runtime performance for compressing and decompressing data, which proved to be an evolutionary advancement in the development of compression algorithms from the known Huffman coding method.

LZW utilizes a greedy graph coloring algorithm to populate the input string table. The serialized data stream is read into a prefix string table, and if the input does not match anything in the string table, a new code word is output, and added into the string table. Data compressed in this method produces higher entropy characteristics, making further compression inefficient.

Page 14: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Appendix A: Stand Alone Re/TIFF Sources /*

File:

retiff.h

Description :

Re-TIFF header data types

Compile line : gcc -ansi -g -o retiff retiff.c

Written by : JSC 11/29/06

*/

#define UBYTE unsigned char /* 1 byte */

#define USHORT unsigned short /* 2 bytes */

#define ULONG unsigned long /* 4 bytes */

/* */

#define IFD_OFFSET_L 4L

#define IFD_SIZE (UBYTE) 12

/* Used to reset offsets */

#define TAG_STRIPOFFSETS 273

#define TAG_COLORMAP 320

/* Used to re-align image data */

#define TAG_SAMPLESPERPIXEL 277

#define TAG_ROWSPERSTRIP 278

#define TAG_STRIPBYTECOUNTS 279

#define TAG_IMAGEWIDTH 256 /* cols */

#define TAG_IMAGELENGTH 257 /* rows */

#define TAG_BITSPERSAMPLE 258

#define BITSPERBYTE 8

/* debug levels */

int DEBUG = 0;

/*

For storing TIFF data and interpreting

Page 15: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

the values

*/

typedef union _udata {

UBYTE b_val[4];

USHORT s_val[2];

ULONG l_val;

} udata; /* unsigned data */

/*

Image File Directory Entries

*/

typedef struct _ifd {

USHORT tag_id;

USHORT type;

UBYTE n[4];

udata vo; /* value offset */

} ifd;

/*

RAW image format

*/

typedef struct _retiff {

USHORT height,

width;

USHORT bps; /* bits per sample */

ULONG size; /* # of rows in image data array,

* in byte counts array, &

* in strip offsets array

*/

ifd *p_cmh; /* color map header */

USHORT *p_cm; /* color map palette */

ULONG *p_bytecounts; /* array of size of strip data */

Page 16: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

ULONG *p_stripoffsets; /* TIFF file data strip offsets */

UBYTE **p_imagedata; /* [rows][columns] */ /* image data */

} retiff;

typedef struct _lzwGIF {

unsigned int height,

width;

unsigned int size; /* malloc size */

unsigned int length; /* used size (non-free)*/

unsigned char *data; /* compressed data */

unsigned int cm_size; /* color map size */

unsigned char *cm; /* color map */

} lzwGIF;

#define MaxCode(number_bits) ((1UL << (number_bits))-1)

/* Mystery: Why

5003 ??

0001 0011 1000 1011

0x138b

*/

#define MaxHashTable /* 5003 */ /* 2051 */ 617 /* fits! */

#define MaxGIFBits /* 12UL */ /* 11UL */ 9UL /* fits! */

#define MaxGIFTable (1UL << MaxGIFBits)

#define GIFOutputCode(code) \

{ \

/* \

Emit a code. \

*/ \

if (bits > 0) \

datum |= (code) << bits; \

else \

datum=code; \

Page 17: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

bits+=number_bits; \

while (bits >= 8) \

{ \

/* \

Add a character to current packet. \

*/ \

if (code == clear_code) { \

printf("\nclear code %.2x\n", (unsigned char) (datum & 0xff)); \

} else { \

printf("%.2x ", (datum & 0xff)); \

} \

fflush(stdout); \

packet[length++]=(unsigned char) (datum & 0xff); \

if (length >= 254) \

{ \

length &= 0xff; \

memcpy(&p_gif->data[p_gif->length], &length , 1); \

p_gif->length++; \

{ \

int i; \

for (i=0; i < length; ++i, ++p_gif->length) { \

/* printf("%.2x ",packet[i]); */ \

p_gif->data[p_gif->length] = packet[i]; \

} \

} \

/* \

memcpy(&p_gif->data[p_gif->length], &packet[0], length); \

p_gif->length += length; \

*/ \

/* \

Page 18: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

{ \

int i; \

for (i = 0; i < length; ++i) { \

printf("%.2x ", packet[i]); \

} \

puts(""); \

} \

*/ \

printf("\nlength %d\n\n",length); \

fflush(stdout); \

length=0; \

} \

datum>>=8; \

bits-=8; \

} \

if (free_code > max_code) \

{ \

number_bits++; \

if (number_bits == MaxGIFBits) \

max_code=MaxGIFTable; \

else \

max_code=MaxCode(number_bits); \

} \

}

int EncodeImage(retiff *p_retiff, lzwGIF *p_gif, const unsigned long data_size);

/*

File:

retiff.c

Description :

Reads an input TIFF so that the Image File Directory (IFD)

Page 19: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

entries are ordered first and the bitmap data last.

Creates a GIF output.

Compile line : gcc -ansi -g -o retiff retiff.c

Written by : JSC 11/23/06

*/

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <assert.h>

#include "retiff.h"

int main(int argc, char *argv[]) {

FILE *fh;

UBYTE ifd_size;

int i, j;

udata *p_dat;

ifd **p_ifd;

unsigned int rows;

unsigned int cols;

unsigned int size; /* measured in bytes */

udata ssize;

/* byte counts */

unsigned int bc_index;

/* output */

ULONG s_offset;

ULONG cm_offset;

retiff *p_retiff;

lzwGIF *p_gif;

if (argc < 3) {

printf("Usage: %s <in.tiff> <out.gif> [DEBUG]\n\n", argv[0]);

puts("\tRewrites input TIFF IFD entries to top of file.\n");

Page 20: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

exit(-1);

}

if (argc == 4) {

DEBUG = 1;

} else {

DEBUG = 0;

}

p_dat = (udata *) calloc(1, sizeof(udata));

fh = fopen(argv[1],"rb");

fseek(fh, IFD_OFFSET_L, SEEK_CUR); /* assume little-endian */

/* Read in IFD offset val */

fread(&p_dat->b_val[0], 4*sizeof(UBYTE), 1, fh);

if (DEBUG)

printf("IFD offset %x\n", p_dat->l_val);

/* Seek forward to IFD entries */

fseek(fh, (long) p_dat->l_val, SEEK_SET);

/* Read number of IFD entries value */

fread(&p_dat->b_val[0], 2*sizeof(UBYTE), 1, fh);

if (DEBUG)

printf("IFD records %d\n", p_dat->s_val[0]);

/* allocate ifd structure */

ifd_size = p_dat->s_val[0];

p_ifd = (ifd **) calloc(ifd_size, sizeof(ifd*));

for (i=0; i < ifd_size; ++i) {

p_ifd[i] = (ifd *) calloc(1, sizeof(ifd));

}

p_retiff = (retiff *) calloc(1, sizeof(retiff));

/* using calloc to initialize members to 0's */

p_gif = (lzwGIF *) calloc(1, sizeof(lzwGIF));

for (i=0; i < ifd_size && !feof(fh); ++i) {

Page 21: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

fpos_t pos;

fgetpos(fh, &pos);

if (DEBUG)

printf("%x\t", pos);

if (!fread(p_ifd[i], sizeof(ifd), 1, fh)) {

break;

}

if (DEBUG)

printf("Tag %x\tType %x\n", p_ifd[i]->tag_id, p_ifd[i]->type);

switch (p_ifd[i]->tag_id) {

case TAG_ROWSPERSTRIP : {

if (DEBUG)

printf("\trows per strip %d\n", p_ifd[i]->vo.l_val);

break;

}

case TAG_IMAGEWIDTH : {

cols = p_ifd[i]->vo.l_val;

p_gif->width = p_ifd[i]->vo.l_val;

if (DEBUG)

printf("\tcols %d\n", cols);

break;

}

case TAG_IMAGELENGTH : {

rows = p_ifd[i]->vo.l_val;

p_gif->height = (unsigned short) p_ifd[i]->vo.l_val;

if (DEBUG)

printf("\trows %d\n", rows);

break;

}

case TAG_BITSPERSAMPLE : {

Page 22: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

size = (rows * cols * p_ifd[i]->vo.l_val) / BITSPERBYTE;

p_retiff->bps = p_ifd[i]->vo.s_val[0]; /* higher order bits assumed to be 0

based on TIFF spec and sample file */

if (DEBUG) {

printf("\tbps %d\n", p_ifd[i]->vo.l_val);

printf("\tsize %d from row x cols\n", size);

}

break;

}

case TAG_STRIPOFFSETS : {

ssize.b_val[0] = p_ifd[i]->n[0];

ssize.b_val[1] = p_ifd[i]->n[1];

ssize.b_val[2] = p_ifd[i]->n[2];

ssize.b_val[3] = p_ifd[i]->n[3];

s_offset = p_ifd[i]->vo.l_val;

if (DEBUG) {

printf("\tstrip count %d\n", ssize.l_val);

printf("\tstrip offset %d\n", s_offset);

}

break;

}

case TAG_STRIPBYTECOUNTS : {

bc_index = i;

if (DEBUG)

printf("\tstrip byte counts offset %x\n", p_ifd[i]->vo.l_val);

break;

}

case TAG_COLORMAP : {

udata csize;

cm_offset = p_ifd[i]->vo.l_val;

Page 23: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

csize.b_val[0] = p_ifd[i]->n[0];

csize.b_val[1] = p_ifd[i]->n[1];

csize.b_val[2] = p_ifd[i]->n[2];

csize.b_val[3] = p_ifd[i]->n[3];

if (DEBUG) {

printf("\tcolormap size %d\n", csize.l_val);

printf("\tcolormap offset %d\n", cm_offset);

}

/* assumption is 256 RGB tuplets */

/* assign color map structure */

p_retiff->p_cmh = p_ifd[i];

p_retiff->p_cm = (USHORT *) calloc(csize.l_val, sizeof(USHORT));

/* read color map data */

fseek(fh, (long) p_ifd[i]->vo.l_val, SEEK_SET);

fread(p_retiff->p_cm, sizeof(USHORT), csize.l_val, fh);

/* transfer to GIF */

p_gif->cm_size = csize.l_val;

p_gif->cm = (unsigned char *) calloc(csize.l_val, sizeof(unsigned char));

for (i=0, j=0; i < p_gif->cm_size-2; ++j) {

p_gif->cm[i] = (UBYTE) p_retiff->p_cm[j]; /* Red */

p_gif->cm[i+1] = (UBYTE) p_retiff->p_cm[j + 256]; /* Green */

p_gif->cm[i+2] = (UBYTE) p_retiff->p_cm[j + 512]; /* Blue */

i = i + 3;

}

break;

}

}

}

fflush(stdout);

/*

Page 24: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Save/Print out the byte count values

*/

{

unsigned int *p_offsets = NULL;

udata size;

memcpy(&size, p_ifd[bc_index]->n, sizeof(ULONG));

p_offsets = (unsigned int *) calloc(size.l_val, sizeof(unsigned int));

/* seek forward to the byte counts */

fseek(fh, (long) p_ifd[bc_index]->vo.l_val, SEEK_SET);

fread(p_offsets, sizeof(unsigned int), size.l_val, fh);

if (DEBUG)

puts("\nStrip byte sizes:");

p_retiff->size = size.l_val;

p_retiff->p_bytecounts = (ULONG *) calloc(size.l_val, sizeof(ULONG));

for (i=0; i < size.l_val; ++i) {

if (DEBUG)

printf("\toffset %d byte size %d\n", i, p_offsets[i]);

p_retiff->p_bytecounts[i] = p_offsets[i];

p_gif->size += p_offsets[i];

}

if (DEBUG)

printf("\tTIFF image size %d from byte counts\n",p_gif->size);

free(p_offsets);

}

/*

Save/print out the strip offsets

*/

{

unsigned int *p_offsets = NULL;

p_offsets = (unsigned int *) calloc(ssize.l_val, sizeof(unsigned int));

Page 25: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

p_retiff->p_stripoffsets = (ULONG *) calloc(ssize.l_val, sizeof(ULONG));

fseek(fh, (long) s_offset, SEEK_SET);

fread(p_offsets, sizeof(unsigned int), ssize.l_val, fh);

if (DEBUG)

puts("\nStrip offsets:");

for (i=0; i < ssize.l_val; ++i) {

p_retiff->p_stripoffsets[i] = p_offsets[i];

if (DEBUG)

printf("\toffset %d is %x\n", i, p_offsets[i]);

}

free(p_offsets);

p_offsets=NULL;

}

/*

Read image data into retiff data struct

*/

{

int b_read; /* bytes read */

p_retiff->p_imagedata = (UBYTE **) calloc(p_retiff->size, sizeof(UBYTE *));

puts("\nRead image data");

for (i=0; i < p_retiff->size; ++i) {

b_read = 0;

p_retiff->p_imagedata[i] = (UBYTE *) calloc(p_retiff->p_bytecounts[i], sizeof(UBYTE));

fseek(fh, (long) p_retiff->p_stripoffsets[i], SEEK_SET);

b_read = fread(p_retiff->p_imagedata[i], sizeof(UBYTE), p_retiff->p_bytecounts[i], fh);

if (feof(fh)) {

if (DEBUG)

puts("End of file encountered");

}

if (DEBUG)

Page 26: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

printf("%d.\tRead %.4x bytes of %.4x byte counts, offset %.6x\n",

i, b_read, p_retiff->p_bytecounts[i], p_retiff->p_stripoffsets[i]);

}

}

/*

* LZW Compress to GIF structure

*/

{

p_gif->data = (unsigned char *) calloc(p_gif->size, sizeof (unsigned char));

#define LZW_CODE_BIT_SIZE 9

EncodeImage(p_retiff, p_gif, LZW_CODE_BIT_SIZE); /* 9 */

if (DEBUG)

printf("\n%x bytes of %x bytes compressed\n", p_gif->length, p_gif->size);

}

/*

* Write the GIF file

*/

{

unsigned char buf[256];

FILE *fh_gif;

fh_gif = fopen(argv[2], "wb");

/* Header */

sprintf(buf, "%s", "GIF89a");

fwrite(buf, sizeof(unsigned char), 6, fh_gif);

/* Logical Screen Descriptor */

fwrite(&p_gif->width, sizeof(unsigned short), 1, fh_gif);

fwrite(&p_gif->height, sizeof(unsigned short), 1, fh_gif);

buf[0]=0xf7; /* packed field */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

buf[0]=0x00; /* background color index */

Page 27: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

buf[0]=0x00; /* pixel aspect ratio */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

/* Global Color Table */

fflush(fh_gif);

fwrite(p_gif->cm, sizeof(unsigned char), p_gif->cm_size, fh_gif);

fflush(fh_gif);

/* Image Descriptor */

buf[0]=0x2c; /* Image Separator */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

fflush(fh_gif);

buf[0]=0x00; /* Image Left Position */

buf[1]=0x00;

fwrite(buf, sizeof(unsigned char), 2, fh_gif);

buf[0]=0x00; /* Image Top Position */

buf[1]=0x00;

fwrite(buf, sizeof(unsigned char), 2, fh_gif);

fwrite(&p_gif->width, sizeof(unsigned short), 1, fh_gif);

fwrite(&p_gif->height, sizeof(unsigned short), 1, fh_gif);

buf[0]=0x00; /* Packed Fields */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

/* Table Based Image Data */

buf[0]=LZW_CODE_BIT_SIZE-1; /* LZW Minimum Code Size */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

/* Image Data */

{

unsigned char *p_data;

p_data = &p_gif->data[0];

for (i=0 ; i < p_gif->length ; ++i) {

fwrite(p_data++, sizeof(unsigned char), 1, fh_gif);

Page 28: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

fflush(fh_gif);

}

}

/* Trailers */

buf[0] = 0x00;

buf[1] = 0x3b;

fwrite(buf, sizeof(unsigned char), 2, fh_gif);

fflush(fh_gif);

fclose(fh_gif);

fh_gif = NULL;

}

/* free memory used */

if (p_retiff->p_cm != NULL) {

free(p_retiff->p_cm);

p_retiff->p_cm = NULL;

}

if (p_retiff->p_bytecounts != NULL) {

free(p_retiff->p_bytecounts);

p_retiff->p_bytecounts = NULL;

}

if (p_retiff->p_stripoffsets != NULL) {

free(p_retiff->p_stripoffsets);

p_retiff->p_stripoffsets = NULL;

}

if (p_retiff->p_imagedata != NULL) {

for (i=0; i<p_retiff->size; i++) {

if (p_retiff->p_imagedata[i] != NULL) {

free(p_retiff->p_imagedata[i]);

p_retiff->p_imagedata[i] = NULL;

}

Page 29: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

}

free(p_retiff->p_imagedata);

p_retiff->p_imagedata = NULL;

}

free(p_retiff);

p_retiff = NULL;

if (p_gif->cm != NULL) {

free(p_gif->cm);

p_gif->cm = NULL;

}

{ /* free gif lzw data */

if (p_gif->data != NULL) {

free(p_gif->data);

p_gif->data = NULL;

}

}

free(p_gif);

p_gif = NULL;

for (j=0; j < ifd_size; ++j) {

free(p_ifd[j]);

p_ifd[j] = NULL;

}

free(p_ifd);

p_ifd=NULL;

fclose(fh);

fh=NULL;

free(p_dat);

p_dat = NULL;

if (DEBUG)

puts("Done.");

Page 30: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

exit(0);

}

/*

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% %

% E n c o d e I m a g e %

% %

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%

% EncodeImage LZW compresses an image via GIF-coding.

%

% The format of the EncodeImage method is:

%

% int EncodeImage(

% retiff *p_retiff,

% lzwGIF *p_gif,

% const unsigned long data_size)

%

% A description of each parameter follows:

%

% o p_retiff: The address of a structure defining the image data.

%

% o p_gif: output gif image block

%

% o data_size: The number of bits in the compressed packet.

%

% Comments:

%

% JSC 10/28/06 Modified from ImageMagick-6.2.8 coders/gif.c and adapted

% for Re-TIFFing

Page 31: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

%

*/

int EncodeImage(retiff *p_retiff, lzwGIF *p_gif, const unsigned long data_size) {

unsigned char

index;

long

displacement,

k,

y;

register long

i,

x;

size_t

length;

short

*hash_code,

*hash_prefix,

waiting_code;

unsigned char

*packet,

*hash_suffix;

unsigned long

bits,

clear_code,

datum,

end_of_information_code,

free_code,

max_code,

next_pixel,

number_bits;

Page 32: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

/*

Allocate encoder tables.

*/

assert(p_retiff != (retiff *) NULL);

packet=(unsigned char *) calloc(256, sizeof(*packet));

/* codes */

hash_code=(short *) calloc(MaxHashTable, sizeof(*hash_code));

/* omega */

hash_prefix=(short *) calloc(MaxHashTable, sizeof(*hash_prefix));

/* K */

hash_suffix=(unsigned char *) calloc(MaxHashTable, sizeof(*hash_suffix));

/* test for calloc failure e.g. OutOfMemory Exception */

if ((packet == (unsigned char *) NULL) || (hash_code == (short *) NULL) ||

(hash_prefix == (short *) NULL) ||

(hash_suffix == (unsigned char *) NULL)) {

if (packet != (unsigned char *) NULL)

free(packet);

if (hash_code != (short *) NULL)

free(hash_code);

if (hash_prefix != (short *) NULL)

free(hash_prefix);

if (hash_suffix != (unsigned char *) NULL)

free(hash_suffix);

return (0); /* FALSE */

}

/*

Initialize GIF encoder.

*/

number_bits=data_size;

max_code=MaxCode(number_bits);

Page 33: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

clear_code=((short) 1UL << (data_size-1));

end_of_information_code=clear_code+1;

if (DEBUG) {

puts("\nEncodeGIF");

printf("\tclear code %x\n",clear_code);

printf("\tend of information code %x\n",end_of_information_code);

}

free_code=clear_code+2;

length=0;

datum=0;

bits=0;

for (i=0; i < MaxHashTable; i++)

hash_code[i]=0;

GIFOutputCode(clear_code);

/*

Encode pixels.

*/

waiting_code=0;

for (y=0; y < (long) p_retiff->size; y++) {

if (y == 0)

/*

LZW algo: Initialize table to contain single-char strings.

Read first input char -- prefix string w (omega)

w == waiting_code or prefix

*/

waiting_code=(short) p_retiff->p_imagedata[0][0];

for (x=(y == 0) ? 1 : 0; x < (long) p_retiff->p_bytecounts[y]; x++) {

index=p_retiff->p_imagedata[y][x] & 0xff;

/*

Probe hash table.

Page 34: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

*/

/*

LZW algo (continued)

Step: Read next input character k

if no such k (input exhausted): code(w) -> output : EXIT

if wk exists in string table: wk -> w; repeat Step

else wk not in string table : code(w) -> output;

wk -> string table;

k -> w; repeat Step

*/

k=(long) (index << (MaxGIFBits-8))+waiting_code;

if (k >= MaxHashTable)

k-=MaxHashTable;

next_pixel=0; /* MagickFalse; */

displacement=1;

/* if wk exists in string table ? */

if (hash_code[k] > 0) {

if ((hash_prefix[k] == waiting_code) &&

(hash_suffix[k] == (unsigned char) index)) {

/* yes -- repeat Step */

waiting_code=hash_code[k];

continue;

}

if (k != 0)

displacement=MaxHashTable-k;

for ( ; ; ) {

k-=displacement;

if (k < 0)

k+=MaxHashTable;

if (hash_code[k] == 0)

Page 35: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

break;

if ((hash_prefix[k] == waiting_code) &&

(hash_suffix[k] == (unsigned char) index)) {

waiting_code=hash_code[k];

next_pixel=1; /* MagickTrue; */

break;

}

}

if (next_pixel == 1) /* MagickTrue */

continue;

}

GIFOutputCode((unsigned long) waiting_code);

if (free_code < MaxGIFTable) {

hash_code[k]=(short) free_code++;

hash_prefix[k]=waiting_code;

hash_suffix[k]=(unsigned char) index;

} else {

/*

Fill the hash table with empty entries.

*/

for (k=0; k < MaxHashTable; k++) {

hash_code[k]=0;

}

/*

Reset compressor and issue a clear code.

*/

free_code=clear_code+2;

GIFOutputCode(clear_code);

number_bits=data_size;

max_code=MaxCode(number_bits);

Page 36: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

}

waiting_code=(short) index;

}

if (DEBUG)

printf("\n%d. wrote 0x%.4x bytes\n", y + 1,

p_retiff->p_bytecounts[y]);

}

/*

Flush out the buffered code.

*/

GIFOutputCode((unsigned long) waiting_code);

GIFOutputCode(end_of_information_code);

if (bits > 0)

{

/*

Add a character to current packet.

*/

packet[length++]=(unsigned char) (datum & 0xff);

if (length >= 254)

{

memcpy(&p_gif->data[p_gif->length], &length, 1);

p_gif->length++;

memcpy(&p_gif->data[p_gif->length], &packet[0], length);

p_gif->length += length;

length=0;

}

}

/*

Flush accumulated data.

*/

Page 37: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

if (length > 0) {

printf("%.2x ",length);

memcpy(&p_gif->data[p_gif->length], &length, 1);

p_gif->length++;

memcpy(&p_gif->data[p_gif->length], &packet[0], length);

p_gif->length += length;

{

int i;

for (i = 0; i < length; ++i) {

printf("%.2x ", packet[i]);

}

puts("");

}

}

/*

Free encoder memory.

*/

free(hash_suffix);

free(hash_prefix);

free(hash_code);

free(packet);

return (1); /* TRUE */

}

Appendix B: Microblaze Implementation Sources

mb_tg.h : Microblaze TIFF to GIF header file listing

mb_tg.c : Microblaze TIFF to GIF source file listing

retiff.h : Re/TIFF header file listing

retiff.c : Re/TIFF source file listing

/*

Page 38: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

File:

mb_tg.h

Description :

MicroBlaze (uB) TIFF to GIF header data definitions

Compile line : Xilinx EDK 6.3 EDK_Gmm.12.3

Written by : JSC 12/02/06

*/

#define TRUE 1

#define FALSE 0

/* UART data input */

volatile Xuint8 d_buf; /* single byte data buffer */

volatile Xuint8 d_flag; /* signals data received from UART */

/* LED : */

/* 6543210 */

#define LED_ZERO 0x01 // 0 = 0000001 = 1 = 0x01

#define LED_ONE 0x4f /* 1 = 1001111 = 79 = 0x4f */

#define LED_TWO 0x12 // 2 = 0010010 = 18 = 0x12

#define LED_THREE 0x06 // 3 = 0000110 = 6 = 0x06

#define LED_FOUR 0x4c // 4 = 1001100 = 76 = 0x4c

#define LED_FIVE 0x24 // 5 = 0100100 = 36 = 0x24

#define LED_SIX 0x20 // 6 = 0100000 = 32 = 0x20

#define LED_SEVEN 0x0f // 7 = 0001111 = 15 = 0x0f

#define LED_EIGHT 0x00 // 8 = 0000000 = 0 = 0x00

#define LED_NINE 0x04 // 9 = 0000100 = 4 = 0x04

/* 6543210 */

#define LED_A 0x08 // A = 0001000 = 8 = 0x08

#define LED_C 0x31 // C = 0110001 = 49 = 0x31

#define LED_E 0x30 // E = 0110000 = 48 = 0x30

#define LED_a 0x02 // a = 0000010

#define LED_b 0x60 // b = 1100000

Page 39: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

#define LED_c 0x72 // c = 1110010

#define LED_d 0x42 // d = 1000010

#define LED_e 0x10 // e = 0010000

#define LED_f 0x38 // f = 0111000

#define LED_SEG_ZERO 0x7f

#define LED_SEG_ONE 0x7f - 0x01

#define LED_SEG_TWO 0x7f - 0x02

#define LED_SEG_THREE 0x7f - 0x04

#define LED_SEG_FOUR 0x7f - 0x08

#define LED_SEG_FIVE 0x7f - 0x10

#define LED_SEG_SIX 0x7f - 0x20

#define LED_SEG_SEVEN 0x7f - 0x40

#define CR 0x0d /* carriage return */

#define NL 0x0a /* new line (text mode) */

#define PAUSE(LEN) \

{ \

int l; \

for (l=0; l < LEN; ++l) { \

/* wait */; \

} \

}

#define UPDATE_LED(led, led_state) \

switch (led) { \

case 0: \

led++; led_state = LED_SEG_ZERO; break; \

case 1: \

led++; led_state = LED_SEG_ONE; break; \

case 2: \

led++; led_state = LED_SEG_TWO; break; \

case 3: \

Page 40: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

led++; led_state = LED_SEG_THREE; break; \

case 4: \

led++; led_state = LED_SEG_FOUR; break; \

case 5: \

led++; led_state = LED_SEG_FIVE; break; \

case 6: \

led++; led_state = LED_SEG_SIX; break; \

default: \

led = 0; led_state = LED_SEG_SEVEN; break; \

} \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, led_state)

#define LED_PRINT(val) \

switch (0x0f & val) { \

case 0: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_ZERO); \

break; \

case 1: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_ONE); \

break; \

case 2: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_TWO); \

break; \

case 3: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_THREE); \

break; \

case 4: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_FOUR); \

break; \

case 5: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_FIVE); \

Page 41: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

break; \

case 6: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_SIX); \

break; \

case 7: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_SEVEN); \

break; \

case 8: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_EIGHT); \

break; \

case 9: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_NINE); \

break; \

case 0xa: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_a); \

break; \

case 0xb: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_b); \

break; \

case 0xc: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_c); \

break; \

case 0xd: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_d); \

break; \

case 0xe: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_e); \

break; \

case 0xf: \

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_f); \

Page 42: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

}

/* image dimensions */

#define X_SIZE 4 /* read from UART */

#define Y_SIZE 4

#define XY_SIZE 8

Xuint8 x_buf[4] = { 0, 0, 0, 0};

Xuint8 y_buf[4] = { 0, 0, 0, 0};

Xuint32 x_dim = 0;

Xuint32 y_dim = 0;

/* dc = dimension component (x or y) */

/* dc_buf = dc buffer for storing unsigned byte tuples

* byte order is little endian */

/* dim_size = iterator counter (X_SIZE or Y_SIZE) */

#define GET_IMG_DIM(DC, DC_BUF, DIM_SIZE) \

for (zd_flag = 0; zd_flag < DIM_SIZE; ++zd_flag) { \

while (!d_flag); /* wait for data i/o */ \

d_flag = FALSE; /* lower flag */ \

\

/* capture image size */ \

DC_BUF[zd_flag] = d_buf; \

} \

DC = \

DC_BUF[0] + \

(DC_BUF[1] << 8) + \

(DC_BUF[2] << 16) + \

(DC_BUF[3] << 24);

/*

Q: Where does the number 5003 come from?

A: When LZW max codeword size is 12 bits, aka the value spec

by "MaxGIFBits" constant, then...

Page 43: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

5003 = 2^12 + 2^12 * 20%, stepped up to nearest prime number

for optimal hash table size

*/

#define MaxHashTable /* 5003 */ /* 2459 */ /* 1229 */ 617 /* fits! */

#define MaxGIFBits /* 12UL */ /* 11UL */ /* 10UL */ 9UL /* fits! */

#define MaxGIFTable ( 1UL << MaxGIFBits )

#define MaxCode(number_bits) (( 1UL << ( number_bits ))-1)

#define LZW_CODE_BIT_SIZE 9 /* fr. EncodeImage, sets max LZW codeword size */

Xint16 hash_code[MaxHashTable] = {

/*

1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6

*/

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 11 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 12 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 13 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 14 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 15 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 17 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 18 */

Page 44: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 19 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 21 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 22 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 23 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 24 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 25 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 26 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 27 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 28 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 29 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 31 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 33 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 34 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 35 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 37 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 38 */

0, 0, 0, 0, 0, 0, 0, 0, 0

/*

1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6

*/

};

Xint16 hash_prefix[MaxHashTable] = {

/*

1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6

*/

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */

Page 45: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 11 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 12 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 13 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 14 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 15 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 17 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 18 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 19 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 21 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 22 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 23 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 24 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 25 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 26 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 27 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 28 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 29 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 31 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 */

Page 46: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 33 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 34 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 35 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 37 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 38 */

0, 0, 0, 0, 0, 0, 0, 0, 0

/*

1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6

*/

};

Xuint8 hash_suffix[MaxHashTable] = {

/*

1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6

*/

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 11 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 12 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 13 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 14 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 15 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 */

Page 47: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 17 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 18 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 19 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 21 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 22 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 23 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 24 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 25 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 26 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 27 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 28 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 29 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 31 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 33 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 34 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 35 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 37 */

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 38 */

0, 0, 0, 0, 0, 0, 0, 0, 0

/*

1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6

*/

};

#define GIFOutputCode(code) { \

/* \

Emit a code. \

*/ \

Page 48: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

if (bits > 0) \

datum |= (code) << bits; \

else \

datum=code; \

bits+=number_bits; \

while (bits >= 8) { \

/* \

Add a character to current packet. \

*/ \

XUartLite_SendByte \

(XPAR_RS232_BASEADDR, \

(datum & 0xff)); \

datum>>=8; \

bits-=8; \

} \

if (free_code > max_code) { \

number_bits++; \

if (number_bits == MaxGIFBits) \

max_code=MaxGIFTable; \

else \

max_code=MaxCode(number_bits); \

} \

}

/*

File:

mb_tg.c

Description :

MicroBlaze (uB) TIFF to GIF UART interrupt data driven converter

* These drivers will be generated in your

* XPS project when you run the "Generate Libraries" menu item

Page 49: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

* in XPS.

* Your XPS project directory is at:

* D:\design\memec_3slc_design3

Compile line : Xilinx EDK 6.3 EDK_Gmm.12.3

Written by : JSC 12/02/06

12/13/06 Updated to incorporate LZW

*/

#include <xuartlite_l.h> /* uartlite peripheral control functions */

#include <xintc_l.h> /* interrupt controller peripheral control functions */

// Located in: microblaze_0/include/xparameters.h

#include "xparameters.h"

#include "xutil.h"

#include "xgpio_l.h"

#include "mb_tg.h"

void uart_int_handler(void *baseaddr_p) {

/* While UART receive FIFO has data */

while (!XUartLite_mIsReceiveEmpty(baseaddr_p)) {

/* Read character (s) */

d_flag = TRUE;

d_buf = XUartLite_RecvByte((Xuint32) baseaddr_p);

}

}

/*

* Routine to write a pattern out to a GPIO

* which is configured as an output

* PARAMETER C_ALL_INPUTS = 0

*/

void WriteToGPOutput(Xuint32 BaseAddress, int gpio_width) {

int i=0, j=0, k=0;

int numTimes = 5;

Page 50: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

XGpio_mSetDataDirection(BaseAddress, 1, 0x00000000); /* Set as outputs */

while (numTimes > 0) {

j = 1;

for(i=0; i<(gpio_width-1); i++) {

XGpio_mSetDataReg(BaseAddress, 1, j);

j = j << 1;

for (k=0; k<100000; k++) {

; //wait

}

}

j = 1;

j = ~j;

for(i=0; i<(gpio_width-1); i++) {

XGpio_mSetDataReg(BaseAddress, 1, j);

j = j << 1;

for (k=0; k<100000; k++) {

; //wait

}

}

numTimes--;

}

}

/*

* Routine to read data from a GPIO

* which is configured as an input

* PARAMETER C_ALL_INPUTS = 1

*/

Xuint32 ReadFromGPInput(Xuint32 BaseAddress) {

Xuint32 data = XGpio_mGetDataReg(BaseAddress, 1);

return data;

Page 51: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

}

//====================================================

int main (void) {

Xuint8 /* unsigned 8-bit */

i,

index;

Xint16 /* signed short */

waiting_code;

Xint32 /* long */

displacement,

k;

Xuint32 /* unsigned long */

x,

y;

Xuint32 /* unsigned long */

bits,

clear_code,

datum,

end_of_information_code,

free_code,

max_code,

next_pixel,

number_bits;

Xint8 led,

led_state;

Xuint8 zd_flag; /* zero data flag */

/*

Initialize LZW encoder.

*/

for (k=0; k < MaxHashTable; k++) {

Page 52: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

hash_code[k]=0;

hash_prefix[k]=0;

hash_suffix[k]=0;

}

number_bits = /* data_size */ LZW_CODE_BIT_SIZE;

max_code = MaxCode(number_bits);

clear_code = ((Xint16) 1UL << (/* data_size */ LZW_CODE_BIT_SIZE - 1));

end_of_information_code = clear_code + 1;

free_code = clear_code+2;

datum = 0;

bits = 0;

waiting_code = 0;

index = 0; /* image data value */

/* interrupt state initialization */

led = 0;

zd_flag = 0; /* zero data flag used to determine when to set prefix */

d_flag = FALSE;

d_buf = 0;

/* Sets up interrupts */

XGpio_mSetDataDirection(XPAR_LED_7SEGMENT_BASEADDR, 1, 0x0);

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_ONE);

microblaze_enable_interrupts();

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_TWO);

/* Register UART interrupt handler */

XIntc_RegisterHandler

(

XPAR_OPB_INTC_0_BASEADDR,

XPAR_OPB_INTC_0_RS232_INTERRUPT_INTR,

(XInterruptHandler) uart_int_handler,

(void *) XPAR_RS232_BASEADDR);

Page 53: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

/* Register External interrupt handler */

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_THREE);

XIntc_mMasterEnable(XPAR_OPB_INTC_0_BASEADDR);

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_FOUR);

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_FIVE);

XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR, XPAR_RS232_INTERRUPT_MASK);

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_SIX);

XUartLite_mEnableIntr(XPAR_RS232_BASEADDR);

//XUartLite_ResetFifos(XPAR_RS232_BASEADDR);

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_THREE);

GET_IMG_DIM(y_dim, y_buf, Y_SIZE);

UPDATE_LED(led, led_state);

GIFOutputCode(clear_code);

for (y = 0; y < y_dim; ++y) {

GET_IMG_DIM(x_dim, x_buf, X_SIZE);

if (y == 0) {

/*

* LZW algo: Initialize table to contain single-char strings.

* Read first input char -- prefix string w (omega)

* w == waiting_code aka "prefix"

*/

while (!d_flag); /* wait for data i/o */

d_flag = FALSE; /* lower flag */

/* assign waiting data */

waiting_code=(short) d_buf;

}

for (x=((y == 0) ? 1 : 0); x < x_dim; ++x) {

while (!d_flag); /* wait for data i/o */

d_flag = FALSE; /* lower flag */

/* assign waiting data */

Page 54: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

index = d_buf;

/*

Probe hash table.

*/

/*

* LZW algo (continued)

* Step: Read next input character k

* if no such k (input exhausted): code(w) -> output : EXIT

* if wk exists in string table: wk -> w; repeat Step

* else wk not in string table : code(w) -> output;

* wk -> string table;

* k -> w; repeat Step

*/

k=(long) (index << (MaxGIFBits-8))+waiting_code;

if (k >= MaxHashTable)

k-=MaxHashTable;

next_pixel=0; /* MagickFalse; */

displacement=1;

/* if wk exists in string table ? */

if (hash_code[k] > 0) {

if ((hash_prefix[k] == waiting_code) &&

(hash_suffix[k] == (unsigned char) index)) {

/* yes -- repeat Step */

waiting_code=hash_code[k];

continue;

}

if (k != 0)

displacement=MaxHashTable-k;

for ( ; ; ) {

k-=displacement;

Page 55: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

if (k < 0)

k+=MaxHashTable;

if (hash_code[k] == 0)

break;

if ((hash_prefix[k] == waiting_code) &&

(hash_suffix[k] == (unsigned char) index)) {

waiting_code=hash_code[k];

next_pixel=1; /* MagickTrue; */

break;

}

}

if (next_pixel == 1) /* MagickTrue */

continue;

}

GIFOutputCode((unsigned long) waiting_code);

if (free_code < MaxGIFTable) {

hash_code[k]=(short) free_code++;

hash_prefix[k]=waiting_code;

hash_suffix[k]=(unsigned char) index;

} else {

/*

Fill the hash table with empty entries.

*/

UPDATE_LED(led, led_state);

for (k=0; k < MaxHashTable; k++) {

hash_code[k]=0;

}

/*

Reset compressor and issue a clear code.

*/

Page 56: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

free_code=clear_code+2;

GIFOutputCode(clear_code);

number_bits= /* data_size */ LZW_CODE_BIT_SIZE;

max_code=MaxCode(number_bits);

}

waiting_code=(short) index;

} /* for (x...) */

} /* for (y...) */

END_OF_DATA:

GIFOutputCode((unsigned long) waiting_code);

GIFOutputCode(end_of_information_code);

if (bits > 0) {

/*

Add a character to current packet.

*/

XUartLite_SendByte(XPAR_RS232_BASEADDR, (datum & 0xff));

}

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_ZERO);

WriteToGPOutput(XPAR_LEDS_4BIT_BASEADDR, 4);

WriteToGPOutput(XPAR_LED_7SEGMENT_BASEADDR, 7);

XGpio_mSetDataReg(XPAR_LED_7SEGMENT_BASEADDR, 1, LED_ZERO);

return 0;

}

/*

File:

retiff.h

Description :

Re-TIFF header data types

Compile line : gcc -ansi -g -o retiff retiff.c

Written by : JSC 11/29/06

Page 57: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

Rev History :

01/04/07 JSC Updated for threaded FPGA LZW UART Tx/Rx data

types and functions.

*/

#define UBYTE unsigned char /* 1 byte */

#define USHORT unsigned short /* 2 bytes */

#define ULONG unsigned long /* 4 bytes */

/* */

#define IFD_OFFSET_L 4L

#define IFD_SIZE (UBYTE) 12

/* Used to reset offsets */

#define TAG_STRIPOFFSETS 273

#define TAG_COLORMAP 320

/* Used to re-align image data */

#define TAG_SAMPLESPERPIXEL 277 /* */

#define TAG_ROWSPERSTRIP 278

#define TAG_STRIPBYTECOUNTS 279

#define TAG_IMAGEWIDTH 256 /* cols */

#define TAG_IMAGELENGTH 257 /* rows */

#define TAG_BITSPERSAMPLE 258 /* */

#define BITSPERBYTE 8

/* Serial I/O COM */

#define BUF_SIZE 16 /* Serial I/O read buffer */

#define TIME_OUT 50 /* # times to check Rx buffer */

#define MAX_GIF_BLK_SIZE 0xff /* Max GIF image block size */

#define DIM_SIZE 4 /* Serial i/o writer */

/* Debug level */

int DEBUG = 0;

/*

For storing TIFF data and interpreting

Page 58: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

the values

*/

typedef union _udata {

UBYTE b_val[4];

USHORT s_val[2];

ULONG l_val;

} udata; /* unsigned data */

/*

Image File Directory Entries

*/

typedef struct _ifd {

USHORT tag_id;

USHORT type;

UBYTE n[4];

udata vo; /* value offset */

} ifd;

/*

RAW image format

*/

typedef struct _retiff {

USHORT height,

width;

USHORT bps; /* bits per sample */

ULONG size; /* # of rows in image data array,

* in byte counts array, &

* in strip offsets array

*/

ifd *p_cmh; /* color map header */

USHORT *p_cm; /* color map palette */

ULONG *p_bytecounts; /* array of size of strip data */

Page 59: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

ULONG *p_stripoffsets; /* TIFF file data strip offsets */

UBYTE **p_imagedata; /* [rows][columns] */ /* image data */

} retiff;

typedef struct _lzwGIF {

unsigned int height,

width;

unsigned int size; /* malloc size */

unsigned int length; /* used size (non-free)*/

unsigned char *data; /* compressed data */

unsigned int cm_size; /* color map size */

unsigned char *cm; /* color map */

} lzwGIF;

int fd; /* global file desciptor */

void serial_open(char *device); /* serial com i/o aka Tx/Rx */

void* serial_write(void *ptr); /* threaded writer Tx */

int EncodeImage(retiff *p_retiff, lzwGIF *p_gif, const unsigned long data_size);

/*

File:

retiff.c

Description :

Reads an input TIFF so that the Image File Directory (IFD)

entries are ordered first and the bitmap data last. Added

threaded serial I/O. Parts derived from tsl.c, whose header

is also included.

Creates a GIF output.

Compile line : gcc -ansi -g -o retiff retiff.c

Written by : JSC 11/23/06

01/03/07 Added Multi-threaded, and FPGA Tx/Rx

12/13/06 Added FPGA UART Serial I/O. Moved LZW into FPGA.

*/

Page 60: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

/*

$Id: tsl.c,v 1.12 2004/01/26 06:58:50 james Exp james $

tsl, temperature sensor data logger

Copyright (C) 2000 James Cameron ([email protected])

This program is free software; you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation; either version 2 of the License, or

(at your option) any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program; if not, write to the Free Software

Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

*/

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <assert.h>

#include <termios.h>

#include <fcntl.h>

#include <pthread.h>

#include "retiff.h"

int main(int argc, char *argv[]) {

FILE *fh;

UBYTE ifd_size;

int i, j;

udata *p_dat;

ifd **p_ifd;

Page 61: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

unsigned int rows;

unsigned int cols;

unsigned int size; /* measured in bytes */

udata ssize;

/* byte counts */

unsigned int bc_index;

/* output */

ULONG s_offset;

ULONG cm_offset;

retiff *p_retiff;

lzwGIF *p_gif;

if (argc < 3) {

printf("Usage: %s <in.tiff> <out.gif> [DEBUG]\n\n", argv[0]);

puts("\tRewrites input TIFF IFD entries to top of file.\n");

exit(-1);

}

if (argc == 4) {

DEBUG = 1;

} else {

DEBUG = 0;

}

p_dat = (udata *) calloc(1, sizeof(udata));

fh = fopen(argv[1], "rb");

fseek(fh, IFD_OFFSET_L, SEEK_CUR); /* assume little-endian */

/* Read in IFD offset val */

fread(&p_dat->b_val[0], 4*sizeof(UBYTE), 1, fh);

if (DEBUG)

printf("IFD offset %x\n", p_dat->l_val);

/* Seek forward to IFD entries */

fseek(fh, (long) p_dat->l_val, SEEK_SET);

Page 62: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

/* Read number of IFD entries value */

fread(&p_dat->b_val[0], 2*sizeof(UBYTE), 1, fh);

if (DEBUG)

printf("IFD records %d\n", p_dat->s_val[0]);

/* allocate ifd structure */

ifd_size = p_dat->s_val[0];

p_ifd = (ifd **) calloc(ifd_size, sizeof(ifd*));

for (i=0; i < ifd_size; ++i) {

p_ifd[i] = (ifd *) calloc(1, sizeof(ifd));

}

p_retiff = (retiff *) calloc(1, sizeof(retiff));

/* using calloc to initialize members to 0's */

p_gif = (lzwGIF *) calloc(1, sizeof(lzwGIF));

for (i=0; i < ifd_size && !feof(fh); ++i) {

fpos_t pos;

fgetpos(fh, &pos);

if (DEBUG)

printf("%x\t", pos);

if (!fread(p_ifd[i], sizeof(ifd), 1, fh)) {

break;

}

if (DEBUG)

printf("Tag 0x%.4x (%d) \tType %x\n", p_ifd[i]->tag_id, p_ifd[i]->tag_id, p_ifd[i]->type);

switch (p_ifd[i]->tag_id) {

case TAG_ROWSPERSTRIP : {

if (DEBUG)

printf("\trows per strip %d\n", p_ifd[i]->vo.l_val);

break;

}

case TAG_IMAGEWIDTH : {

Page 63: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

cols = p_ifd[i]->vo.l_val;

p_gif->width = p_ifd[i]->vo.l_val;

if (DEBUG)

printf("\tcols %d\n", cols);

break;

}

case TAG_IMAGELENGTH : {

rows = p_ifd[i]->vo.l_val;

p_gif->height = (unsigned short) p_ifd[i]->vo.l_val;

if (DEBUG)

printf("\trows %d\n", rows);

break;

}

case TAG_BITSPERSAMPLE : {

size = (rows * cols * p_ifd[i]->vo.l_val) / BITSPERBYTE;

p_retiff->bps = p_ifd[i]->vo.s_val[0]; /* higher order bits assumed to be 0

based on TIFF spec and sample file */

if (DEBUG) {

printf("\tbps %d\n", p_ifd[i]->vo.l_val);

printf("\tsize %d from row x cols\n", size);

}

break;

}

case TAG_STRIPOFFSETS : {

ssize.b_val[0] = p_ifd[i]->n[0];

ssize.b_val[1] = p_ifd[i]->n[1];

ssize.b_val[2] = p_ifd[i]->n[2];

ssize.b_val[3] = p_ifd[i]->n[3];

s_offset = p_ifd[i]->vo.l_val;

if (DEBUG) {

Page 64: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

printf("\tstrip count %d\n", ssize.l_val);

printf("\tstrip offset %d\n", s_offset);

}

break;

}

case TAG_STRIPBYTECOUNTS : {

bc_index = i;

if (DEBUG)

printf("\tstrip byte counts 0x%.4x\n", p_ifd[i]->vo.l_val);

break;

}

case TAG_COLORMAP : {

udata csize;

cm_offset = p_ifd[i]->vo.l_val;

csize.b_val[0] = p_ifd[i]->n[0];

csize.b_val[1] = p_ifd[i]->n[1];

csize.b_val[2] = p_ifd[i]->n[2];

csize.b_val[3] = p_ifd[i]->n[3];

if (DEBUG) {

printf("\tcolormap size %d\n", csize.l_val);

printf("\tcolormap offset %d\n", cm_offset);

}

/* assumption is 256 RGB tuplets */

/* assign color map structure */

p_retiff->p_cmh = p_ifd[i];

p_retiff->p_cm = (USHORT *) calloc(csize.l_val, sizeof(USHORT));

/* read color map data */

fseek(fh, (long) p_ifd[i]->vo.l_val, SEEK_SET);

fread(p_retiff->p_cm, sizeof(USHORT), csize.l_val, fh);

/* transfer to GIF */

Page 65: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

p_gif->cm_size = csize.l_val;

p_gif->cm = (unsigned char *) calloc(csize.l_val, sizeof(unsigned char));

for (i=0, j=0; i < p_gif->cm_size-2; ++j) {

p_gif->cm[i] = (UBYTE) p_retiff->p_cm[j]; /* Red */

p_gif->cm[i+1] = (UBYTE) p_retiff->p_cm[j + 256]; /* Green */

p_gif->cm[i+2] = (UBYTE) p_retiff->p_cm[j + 512]; /* Blue */

i = i + 3;

}

break;

}

}

}

fflush(stdout);

/*

Save/Print out the byte count values

*/

{

unsigned int *p_offsets = NULL;

udata size;

memcpy(&size, p_ifd[bc_index]->n, sizeof(ULONG));

p_offsets = (unsigned int *) calloc(size.l_val, sizeof(unsigned int));

/* seek forward to the byte counts */

fseek(fh, (long) p_ifd[bc_index]->vo.l_val, SEEK_SET);

fread(p_offsets, sizeof(unsigned int), size.l_val, fh);

if (DEBUG)

puts("\nStrip byte sizes:");

p_retiff->size = size.l_val;

p_retiff->p_bytecounts = (ULONG *) calloc(size.l_val, sizeof(ULONG));

p_gif->size = 0;

for (i=0; i < size.l_val; ++i) {

Page 66: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

if (DEBUG)

printf("\toffset %d byte size %d\n", i, p_offsets[i]);

p_retiff->p_bytecounts[i] = p_offsets[i];

p_gif->size += p_offsets[i];

}

if (DEBUG)

printf("\tTIFF image size %d from byte counts\n",p_gif->size);

free(p_offsets);

}

/*

Save/print out the strip offsets

*/

{

unsigned int *p_offsets = NULL;

p_offsets = (unsigned int *) calloc(ssize.l_val, sizeof(unsigned int));

p_retiff->p_stripoffsets = (ULONG *) calloc(ssize.l_val, sizeof(ULONG));

fseek(fh, (long) s_offset, SEEK_SET);

fread(p_offsets, sizeof(unsigned int), ssize.l_val, fh);

if (DEBUG)

puts("\nStrip offsets:");

for (i=0; i < ssize.l_val; ++i) {

p_retiff->p_stripoffsets[i] = p_offsets[i];

if (DEBUG)

printf("\toffset %d is %x\n", i, p_offsets[i]);

}

free(p_offsets);

p_offsets=NULL;

}

/*

* Read image data into retiff data struct

Page 67: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

*/

{

int b_read; /* bytes read */

p_retiff->p_imagedata = (UBYTE **) calloc(p_retiff->size, sizeof(UBYTE *));

if (DEBUG)

puts("\nRead image data");

for (i=0; i < p_retiff->size; ++i) {

b_read = 0;

p_retiff->p_imagedata[i] = (UBYTE *) calloc(p_retiff->p_bytecounts[i], sizeof(UBYTE));

fseek(fh, (long) p_retiff->p_stripoffsets[i], SEEK_SET);

b_read = fread(p_retiff->p_imagedata[i], sizeof(UBYTE), p_retiff->p_bytecounts[i], fh);

if (feof(fh)) {

if (DEBUG)

puts("End of file encountered");

}

if (DEBUG)

printf("%d.\tRead %.4x bytes of %.4x byte counts, offset %.6x\n",

i, b_read, p_retiff->p_bytecounts[i], p_retiff->p_stripoffsets[i]);

}

}

/*

* LZW Compress to GIF structure

*/

{

/* thread */

int iret;

pthread_t pth_uart_wrtr; /* fpga data uart writer thread */

/* com serial i/o */

char *device = "/dev/ttyS10"; /* for UNIX build */

int j; /* data uart i/o time counter */

Page 68: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

int retval;

unsigned char rdr_buf[BUF_SIZE];

unsigned char *p_wtr_buf;

unsigned int wrt_buf_sz;

int i; /* LZW data copy counter */

int quot, rmdr; /* To create valid GIF image data blocks */

/* set up thread data & com i/o */

p_wtr_buf = (unsigned char *) calloc(p_gif->size, sizeof (unsigned char));

serial_open(device);

/* spawing thread invokes EncodeImage */

/* EncodeImage(p_retiff, p_gif, 9); */

iret = pthread_create( &pth_uart_wrtr, NULL, serial_write, (void *) p_retiff);

pthread_detach( pth_uart_wrtr ); /* data is writing to UART */

if ( DEBUG )

puts("\nReceiving LZW data...");

for (j = 0, p_gif->length = 0; j < TIME_OUT ; ++j ) {

retval = read(fd, &rdr_buf[0], BUF_SIZE);

if (retval == -1) {

/* no data this cycle */

/* time out counter increment */

continue;

}

for (i = 0; i < retval; ++i) {

p_wtr_buf[p_gif->length++] = rdr_buf[i];

if (DEBUG) {

printf("%.2x ", rdr_buf[i]);

}

}

j = 0;

}

Page 69: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

if (DEBUG)

printf("\nReceived 0x%.4x bytes.\n", p_gif->length);

/* add size sentinals */

wrt_buf_sz = p_gif->length;

quot = p_gif->length / MAX_GIF_BLK_SIZE; /* integer quotent after division */

rmdr = p_gif->length % MAX_GIF_BLK_SIZE; /* remainder after division */

p_gif->length = p_gif->length + quot + ((rmdr == 0) ? 0 : 1); /* extend gif data size */

if (DEBUG) {

printf("div %d, rmdr %d\n", quot, rmdr);

}

/* copy LZW data into GIF image blocks */

p_gif->data = (unsigned char *) calloc(p_gif->length, sizeof (unsigned char));

for (i = 0, j = 0; i < quot + ((rmdr + quot) / MAX_GIF_BLK_SIZE); ++i) {

p_gif->data[j++] = MAX_GIF_BLK_SIZE - 1;

memcpy

(

&p_gif->data[j],

&p_wtr_buf[i * (MAX_GIF_BLK_SIZE - 1)],

(MAX_GIF_BLK_SIZE - 1));

j += MAX_GIF_BLK_SIZE - 1;

}

{

int rmdr2;

rmdr2 = (rmdr + quot) % MAX_GIF_BLK_SIZE;

if (DEBUG)

printf("rmdr2 %d\n",rmdr2);

p_gif->data[j++] = rmdr2;

memcpy

(

&p_gif->data[j],

Page 70: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

&p_wtr_buf[(quot + ((rmdr + quot) / MAX_GIF_BLK_SIZE)) * (MAX_GIF_BLK_SIZE-1)],

rmdr2);

}

free(p_wtr_buf);

if (DEBUG)

printf("\n%x bytes of %x bytes compressed\n", p_gif->length, p_gif->size);

close(fd); /* op delayed in case uart_wrtr is still working */

}

/*

* Write the GIF file

*/

{

unsigned char buf[256];

FILE *fh_gif;

fh_gif = fopen(argv[2], "wb");

/* Header */

sprintf(buf, "%s", "GIF89a");

fwrite(buf, sizeof(unsigned char), 6, fh_gif);

/* Logical Screen Descriptor */

fwrite(&p_gif->width, sizeof(unsigned short), 1, fh_gif);

fwrite(&p_gif->height, sizeof(unsigned short), 1, fh_gif);

buf[0]=0xf7; /* packed field */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

buf[0]=0x00; /* background color index */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

buf[0]=0x00; /* pixel aspect ratio */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

/* Global Color Table */

fflush(fh_gif);

fwrite(p_gif->cm, sizeof(unsigned char), p_gif->cm_size, fh_gif);

Page 71: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

fflush(fh_gif);

/* Image Descriptor */

buf[0]=0x2c; /* Image Separator */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

fflush(fh_gif);

buf[0]=0x00; /* Image Left Position */

buf[1]=0x00;

fwrite(buf, sizeof(unsigned char), 2, fh_gif);

buf[0]=0x00; /* Image Top Position */

buf[1]=0x00;

fwrite(buf, sizeof(unsigned char), 2, fh_gif);

fwrite(&p_gif->width, sizeof(unsigned short), 1, fh_gif);

fwrite(&p_gif->height, sizeof(unsigned short), 1, fh_gif);

buf[0]=0x00; /* Packed Fields */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

/* Table Based Image Data */

buf[0]=0x08; /* LZW Minimum Code Size */

fwrite(buf, sizeof(unsigned char), 1, fh_gif);

/* Image Data */

{

unsigned char *p_data;

p_data = &p_gif->data[0];

for (i=0 ; i < p_gif->length ; ++i) {

fwrite(p_data++, sizeof(unsigned char), 1, fh_gif);

fflush(fh_gif);

}

}

/* Trailers */

buf[0] = 0x00;

buf[1] = 0x3b;

Page 72: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

fwrite(buf, sizeof(unsigned char), 2, fh_gif);

fflush(fh_gif);

fclose(fh_gif);

fh_gif = NULL;

}

/* free memory used */

if (p_retiff->p_cm != NULL) {

free(p_retiff->p_cm);

p_retiff->p_cm = NULL;

}

if (p_retiff->p_bytecounts != NULL) {

free(p_retiff->p_bytecounts);

p_retiff->p_bytecounts = NULL;

}

if (p_retiff->p_stripoffsets != NULL) {

free(p_retiff->p_stripoffsets);

p_retiff->p_stripoffsets = NULL;

}

if (p_retiff->p_imagedata != NULL) {

for (i=0; i<p_retiff->size; i++) {

if (p_retiff->p_imagedata[i] != NULL) {

free(p_retiff->p_imagedata[i]);

p_retiff->p_imagedata[i] = NULL;

}

}

free(p_retiff->p_imagedata);

p_retiff->p_imagedata = NULL;

}

free(p_retiff);

p_retiff = NULL;

Page 73: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

if (p_gif->cm != NULL) {

free(p_gif->cm);

p_gif->cm = NULL;

}

{ /* free gif lzw data */

if (p_gif->data != NULL) {

free(p_gif->data);

p_gif->data = NULL;

}

}

free(p_gif);

p_gif = NULL;

for (j=0; j < ifd_size; ++j) {

free(p_ifd[j]);

p_ifd[j] = NULL;

}

free(p_ifd);

p_ifd=NULL;

fclose(fh);

fh=NULL;

free(p_dat);

p_dat = NULL;

if ( DEBUG )

puts("Done.");

exit(0);

}

/*

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% %

% E n c o d e I m a g e %

Page 74: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

% %

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%

% EncodeImage LZW compresses an image via GIF-coding.

%

% The format of the EncodeImage method is:

%

% int EncodeImage(

% retiff *p_retiff,

% lzwGIF *p_gif,

% const unsigned long data_size)

%

% A description of each parameter follows:

%

% o p_retiff: The address of a structure defining the image data.

%

% o p_gif: output gif image block

%

% o data_size: The number of bits in the compressed packet.

%

% Comments:

%

% JSC 01/03/07 Updated to send to FPGA via UART where LZW byte

% stream is Tx/Rx

% JSC 10/28/06 Modified from ImageMagick-6.2.8 coders/gif.c and adapted

% for Re-TIFFing

%

*/

int EncodeImage(retiff *p_retiff, lzwGIF *p_gif, const unsigned long data_size) {

int x, y, i, retval;

Page 75: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

union _sz {

unsigned char b_size[4];

unsigned long l_size;

} img = {0, 0, 0, 0};

#define DIM_SIZE 4

/* write y dimension */

img.l_size = (unsigned long) p_retiff->size;

retval = write(fd, &img.b_size[0], DIM_SIZE);

for (y = 0, i = 0; y < (long) p_retiff->size; y++) {

/* write x dimension */

img.l_size = (unsigned long) p_retiff->p_bytecounts[y];

retval = write(fd, &img.b_size[0], DIM_SIZE);

for (x=0; x < (long) p_retiff->p_bytecounts[y]; x++) {

/* index=p_retiff->p_imagedata[y][x] & 0xff; */

/* img data val */

retval = write(fd, &p_retiff->p_imagedata[y][x], 1);

}

if (DEBUG)

printf("\n%d. wrote 0x%.4x bytes\n", y + 1, img.l_size);

i += img.l_size;

}

if (DEBUG)

printf("\nEncodeImage exit. Wrote 0x%.4x bytes\n", i);

}

void* serial_write(void *ptr) {

EncodeImage( (retiff *)ptr, NULL, 0);

}

void serial_open(char *device) {

struct termios termios;

fd = open(device, O_RDWR | O_NONBLOCK);

Page 76: TIFF to GIF Converter & LZW Compression Algorithm FPGA Implementation.pdf

/* set the serial port characteristics */

if (tcgetattr(fd, &termios) < 0) {

perror("tcgetattr");

exit(1);

}

if (cfsetospeed(&termios, B115200) < 0) {

perror("cfsetospeed");

exit(1);

}

if (cfsetispeed(&termios, B115200) < 0) {

perror("cfsetispeed");

exit(1);

}

//

// c_cflag termios CS8 = 8 bits

//

termios.c_cflag = CS8 | CSTOPB;

if (tcsetattr(fd, TCSANOW, &termios) < 0) {

perror("tcsetattr");

exit(1);

}

}

1 See http://www.em.avnet.com

2 TIFF. Revision 6.0 Final — June 3, 1992. Adobe Developers Association.

3 spec-gif89a.txt

4 Platform Specification Format Reference Manual. Embedded Development Kit EDK 6.3i. UG131 (v1.0) August 20, 2004, pp 21.

5 Memec 3SLC MicroBlaze Hello World Reference Design. December 1, 2004 Version 6.3.d

6 Xilinx Spartan-3 FPGA Family: Introduction and Ordering Information. DS099-1 (v1.4) January 17, 2005.


Recommended