• Advertisement

Archived

This topic is now archived and is closed to further replies.

RLE Encoding problem?

This topic is 5529 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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;

Share this post


Link to post
Share on other sites
Advertisement
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]

Share this post


Link to post
Share on other sites

  • Advertisement