Skip to main content
gamedev.net
🔒 Locked

RLE Encoding problem?

Started by Sander Aerts Dec 2, 2002 at 1:14 AM 0 replies 450+ views
Original Post
Sander Aerts
Sander Aerts
Lo all, i have a problem encoding a rle encode tga file, i use the following code. All input variables are set correct. So there need to be going something wrong in this code
  
do {
                    fread(&tgachunkheader, 1, 1, fp);                    
                    if (tgachunkheader < 128){
                        /* RAW Pixel */
                        tgachunkheader++;
                        for (int cc = 0; cc < tgachunkheader; cc++){
                            fread(tga_pixel, 1, tgaheader.bytesperpixel, fp);
                            tga_temp_img.imageData[currentbyte]         = tga_pixel[2];
                            tga_temp_img.imageData[currentbyte + 1]     = tga_pixel[1];
                            tga_temp_img.imageData[currentbyte + 2]     = tga_pixel[0];
                            if (tgaheader.bytesperpixel == 4) 
                                tga_temp_img.imageData[currentbyte + 3] = tga_pixel[3];
                            currentbyte += tgaheader.bytesperpixel;
                        }
                    } else {
                        /* RLE Encoded pixel(s) */
                        tgachunkheader -= 127;
                        fread(tga_pixel, 1, tgaheader.bytesperpixel, fp);
                        for (int cc = 0; cc < tgachunkheader; cc++){
                            tga_temp_img.imageData[currentbyte]         = tga_pixel[2];
                            tga_temp_img.imageData[currentbyte + 1]     = tga_pixel[1];
                            tga_temp_img.imageData[currentbyte + 2]     = tga_pixel[0];
                            if (tgaheader.bytesperpixel == 4) 
                                tga_temp_img.imageData[currentbyte + 3] = tga_pixel[3];
                            currentbyte += tgaheader.bytesperpixel;
                        }
                    }
                    currentpixel += tgachunkheader;
                } while (currentpixel < tgapixels);  
  
I hope somebody can help me, i am getting nuts after trying for about 3 to 4 hours :S ------ With kind regards, Sander Aerts aka DrSnugels Crap --------------------------- mov ax, 013h; int 10h; mov ax, 0xa000h; mov es, ax; mov di, 3360; mov al, 15; stosb; mov ax, 0002h; int 21h; mov ax, 03h; int 10h;
------With kind regards,Sander Aerts aka DrSnugelsCrap :)---------------------------mov ax, 013h; int 10h; mov ax, 0xa000h;mov es, ax; mov di, 3360; mov al, 15;stosb; mov ax, 0002h; int 21h;mov ax, 03h; int 10h;
smokes
smokes
From you post I guess you wan't to decode.. eg read.. an RLE encoded (compressed) TGA file?.. well the source below is a rip from my 2D engine.. I loads compressed or uncompressed TGA's and it works.. I know that the code is horrible.. and that it relies on structures defined elsewhere in my engine (GFX_Surface etc) but if no one else answers your question perhaps you can draw some meaning from it :-).. I haven't read your code because I hate debugging other people's code.. the way I wrote my TGA loader was by downloading the specification (from wotsit). I then coded started to code my loader step by step going through the spec.. :-)


    
// TGA loader ------------------------------------------------------------------------------

// TGA image loading rutines

// supports loading of:

//

// Uncompressed 16 bit images

// RLE compressed 16 bit images


unsigned short Convert_TGAColor(unsigned short temp)
{
unsigned short color = 0;
unsigned char r,g,b;

r = (temp & 0x7C00) >> 10;
g = (temp & 0x03E0) >> 5;
b = (temp & 0x001F);

if( g != 0 )
g = (2*g)+1;

color = RGB_16BIT565(r, g, b);
return color;
}

int DeflateType2_16(GFX_Surface *surface, unsigned char *data, int length)
{
unsigned short *ptr1 = (unsigned short *) data;
unsigned short temp;
int len = length/2;
int index;
// if not format555 then convert color to RGB565 from RGB555

if( !Format555 )
{
for( index = 0; index < len; index++ )
{
temp = *ptr1;
*ptr1 = Convert_TGAColor(temp);
ptr1++;
}
}
// flip bitmap

ptr1 = (unsigned short *) data;
unsigned short *ptr2 = (unsigned short *) malloc(length);
int y,y2;
y2 = surface->Height-1;
for( y = 0; y < surface->Height; y++ )
{
memcpy(ptr2+(y*surface->Width),ptr1+(y2*surface->Width), surface->Width*2);
y2--;
}
// copy the crap to the surface

unsigned short *bitmap = GFX_LockSurface(surface);
if( bitmap == NULL )
{
free(ptr2);
return GFX_ERROR;
}
unsigned short *src = ptr2;
for( y = 0; y < surface->Height; y++ )
{
memcpy(bitmap, src, surface->Width*2);
bitmap += Pitch;
src += surface->Width;
}
GFX_UnlockSurface(surface);
free(ptr2);
return GFX_OK;
}

unsigned char * tga_rle_decode16(unsigned char *data, int outsize)
{
unsigned char *dst_buffer = (unsigned char *) malloc(outsize);
unsigned short *dst_ptr = (unsigned short *) dst_buffer;
unsigned char *src_ptr = data;
bool done = false;
unsigned char cmd;
unsigned char len;
unsigned short color;
int index;
int pixel_counter = 0;

while(!done)
{
cmd = *src_ptr;
if( cmd & 0x80 ) // rle run

{
len = (cmd & 0x7F)+1;
color = MAKEWORD(*(src_ptr+1), *(src_ptr+2));
for( index = 0; index < len; index++ )
{
*dst_ptr = color;
dst_ptr++;
}
src_ptr += 3;
pixel_counter += len;
}
else // non rle run

{
len = (cmd & 0x7F)+1;
memcpy(dst_ptr, src_ptr+1, len*2);
dst_ptr += len;
src_ptr += (len*2)+1;
pixel_counter += len;
}
if( pixel_counter >= (outsize/2) )
{
done = true;
}
}
return dst_buffer;
}

GFX_Surface * GFX_CreateSurfaceFromTGA(char *filename)
{
int err = VFS_fopen(filename);
if( err != VFS_OK ) // error

return NULL;
unsigned char LengthOfIDField;
unsigned char ImageType;
unsigned short ImageWidth;
unsigned short ImageHeight;
unsigned char ImageDepth;
int error;

// find file size


int FileLength = VFS_GetFileSize(filename);

VFS_fread(&LengthOfIDField,1);
VFS_fseek(2,SEEK_SET);
VFS_fread(&ImageType,1);
VFS_fseek(12,SEEK_SET);
VFS_fread(&ImageWidth,2);
VFS_fread(&ImageHeight,2);
VFS_fread(&ImageDepth,1);
VFS_fseek(18+LengthOfIDField,SEEK_SET);
int minus = VFS_ftell();

unsigned char *ImageData = (unsigned char *) malloc(FileLength-minus);
VFS_fread(ImageData, FileLength-minus);
VFS_fclose();

if( (ImageType != 2) && (ImageType != 10) )
{
// unsupported format

free(ImageData);
return NULL;
}
// create surface

GFX_Surface *surface = GFX_CreateSurface(ImageWidth,ImageHeight);
if( (ImageType == 2) && (ImageDepth == 16) )
{
error = DeflateType2_16(surface, ImageData, 2*(ImageWidth*ImageHeight));
if( error != GFX_OK )
{
free(ImageData);
GFX_DestroySurface(surface);
return NULL;
}
}
if( (ImageType == 10) && (ImageDepth == 16) )
{
unsigned char *imgdata = tga_rle_decode16(ImageData, 2*(ImageWidth*ImageHeight));
error = DeflateType2_16(surface, imgdata, 2*(ImageWidth*ImageHeight));
if( error != GFX_OK )
{
free(ImageData);
free(imgdata);
GFX_DestroySurface(surface);
return NULL;
}
free(imgdata);
}
free(ImageData);
return surface;
}
// end of TGA loader -----------------------------------------------------------------------



ps. the VFS_ routines are just encapsulations of the regular standard library routines ( C, not C++ ).. they can be replaced.. VFS_fseek with fseek etc

[edited by - Smokes on December 2, 2002 8:01:13 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.