123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- /*
- THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
- SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
- END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
- ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
- IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
- SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
- FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
- CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
- AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
- COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <conio.h>
- #include <math.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <io.h>
- #include <dos.h>
- #include <malloc.h>
- #include <ctype.h>
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- typedef unsigned int DWORD;
- typedef struct
- {
- BYTE Field1;
- BYTE Field2;
- BYTE DataType ;
- BYTE Field41H ;
- BYTE Field41L ;
- BYTE Field42H ;
- BYTE Field42L ;
- BYTE Field43 ;
- WORD XOrigin ;
- WORD YOrigin ;
- WORD Width ;
- WORD Height ;
- BYTE BitsPerPixel;
- BYTE Field56 ;
- } TGA_FILE_HEADER;
- typedef struct {
- WORD Width;
- WORD Height;
- WORD Data[1];
- } BITMAP15;
- BITMAP15 * ReadInTGA(char * filename )
- {
- BITMAP15 * NewBitmap;
- short row_b,col_b,row_e,col_e;
- char *buffer;
- TGA_FILE_HEADER imghead;
- int infile;
- int numread;
- short len ;
- short row,dcol,col_now,drow;
- char quitflag ;
- WORD bufindex, value ;
- BYTE count;
- short tempcnt;
- short BufSize, RowsPerRead, BytesPerRow;
- short i;
- WORD tmpbuf[320];
- // Try to open file
- infile = open(filename,(O_BINARY|O_RDONLY) ) ;
- if (infile==-1) {
- printf( "TGAto15BPP: '%s' not found.\n", filename );
- return NULL;
- }
- // Read the image header
- numread = read(infile,(char*)&imghead, sizeof(TGA_FILE_HEADER) ) ;
- if ( numread != sizeof(TGA_FILE_HEADER) ) {
- printf( "TGAto15BPP: Error reading '%s' header.\n", filename );
- close(infile);
- return NULL;
- }
- // get the data in header
- dcol = imghead.Width;
- drow = imghead.Height;
- // Assign column,row begin , displacement to input Origion
- col_b = imghead.XOrigin ;
- row_b = imghead.YOrigin ;
- col_b = 0 ;
- row_b = 0 ;
- // check if orgion overflow
- if ( (row_b>320) || (col_b>480) ) {
- printf( "TGAto15BPP: Origin overflow reading '%s'.", filename );
- close(infile);
- return NULL;
- }
- // Bound the image in maxrow, maxcal
- col_e = dcol + col_b - 1 ;
- row_e = drow + row_b - 1 ;
- if (col_e>320)
- col_e = 320 ;
- if (row_e>480)
- row_e = 480 ;
- // check if 16 bits per pixel, now support VIGA16 file only
- if (imghead.BitsPerPixel != 16 ) {
- printf( "TGAto15BPP: '%s' is not a valid 16bpp TGA file.\n", filename );
- close(infile);
- return NULL;
- }
- NewBitmap = (BITMAP15 *)malloc( sizeof(BITMAP15)+((col_e-col_b+1)*(row_e-row_b+1)*3) );
- if (NewBitmap == NULL ) {
- printf( "TGAto15bpp: Error allocating bitmap memory for '%s'.\n", filename );
- return NULL;
- }
- NewBitmap->Height = row_e - row_b + 1;
- NewBitmap->Width = col_e - col_b + 1;
- // allocate a buffer as large as possible
- BufSize = 1024;
- while ( ((buffer=(char *)malloc((size_t)BufSize))==NULL) && (BufSize>=1024) ) {
- BufSize -= 1024 ;
- }
- // check if buffer enough, if not return MEMORY FULL
- if (BufSize<1024) {
- printf( "TGAto15BPP: Error allocating buffer for '%s'.\n", filename );
- close(infile);
- free( buffer );
- free( NewBitmap);
- return NULL;
- }
- BytesPerRow = dcol * 2 ;
- RowsPerRead = BufSize / BytesPerRow ;
- // Load image file routines...
- if (imghead.DataType == 2) {
- // This image file is not compressed
- row = row_b ;
- while (row <= row_e) {
- if ( (row+RowsPerRead) > row_e)
- RowsPerRead = row_e - row + 1;
- read(infile,buffer,BytesPerRow*RowsPerRead);
- bufindex = 0 ;
- for (value=0; value<RowsPerRead; value++) {
- for (i=col_b; i<=col_e; i++ )
- memcpy( &(NewBitmap->Data[ NewBitmap->Width*(NewBitmap->Height-row-1)+i ]), &(buffer[bufindex+2*(i-col_b)]), 2 );
- //NewBitmap->Data[ NewBitmap->Width*(NewBitmap->Height-row-1)+i ] = buffer[bufindex+i-col_b];
- row++;
- bufindex += BytesPerRow ;
- } // for
- } // while
- // free the allocated buffer, close opened file
- free(buffer) ;
- close(infile);
- return NewBitmap;
- }
- if (imghead.DataType != 10) {
- // Not a valid TGA file. Free the allocated buffer, close opened file
- printf( "TGAto15BPP: '%s' compression type is invalid.\n", filename );
- free(buffer) ;
- close(infile);
- free( NewBitmap);
- return NULL;
- }
- // init col_now, quitflag to 0,init row to the start row
- col_now = 0 ;
- row = row_b ;
- quitflag = 0 ;
- // read a block of data to buffer
- numread = read(infile,buffer,BufSize);
- while ( (numread>0) && (quitflag==0) ) {
- // init bufindex, while loop to decode data
- bufindex = 0 ;
- while ( (bufindex<numread) && (quitflag==0) ) {
- // get the first data in buffer, inc bufindex
- count = *(buffer+bufindex) ;
- bufindex++;
- // check if count a data or a counter
- if ( count >= 128 ) {
- // if end of buffer, read next block, and continue to decode them
- if (bufindex>=numread) {
- numread = read(infile,buffer,BufSize) ;
- if (numread>0) {
- bufindex = 0 ;
- memcpy(&value,(buffer+bufindex),2);
- bufindex += 2 ;
- }
- else
- quitflag = 1 ;
- }
- else
- if ( (bufindex+1) >= numread ) {
- value = *(buffer+bufindex) ;
- numread = read(infile,buffer,BufSize) ;
- if (numread>0) {
- bufindex = 0 ;
- value += *(buffer+bufindex) << 8 ;
- bufindex++;
- }
- else
- quitflag = 1 ;
- }
- else {
- memcpy(&value,(buffer+bufindex),2);
- bufindex += 2 ;
- }
- // dec count by 127, store data to
- // tmpbuf, adjust col_now
- count -= 127 ; // 127
- while (count>0) {
- tmpbuf[col_now] = value ;
- col_now++;
- count--;
- } // while
- } // if count
- else {
- // not counter, inc count, cal tempcnt
- count++;
- tempcnt = 2*count ;
- // check if end of buffer, if yes read next
- // block to buffer, continue to decode
- if ( (bufindex+tempcnt) >= numread ) {
- while ( (bufindex+2)<=numread ) {
- memcpy(&tmpbuf[col_now],(buffer+bufindex), 2);
- col_now++;
- tempcnt -= 2 ;
- bufindex += 2 ;
- }
- if ( bufindex<numread ) {
- value = *(buffer+bufindex) ;
- numread = read(infile,buffer,BufSize) ;
- if (numread>0) {
- bufindex = 0 ;
- value += *(buffer+bufindex) << 8 ;
- tmpbuf[col_now] = value ;
- col_now++;
- bufindex++;
- tempcnt -= 2 ;
- }
- else
- quitflag = 1 ;
- }
- else
- {
- numread = read(infile,buffer,BufSize) ;
- if (numread>0)
- bufindex = 0 ;
- else
- quitflag = 1 ;
- }
- if (tempcnt>0)
- {
- memcpy(&tmpbuf[col_now],(buffer+bufindex), tempcnt) ;
- col_now += ( tempcnt / 2) ;
- bufindex += tempcnt ;
- } // if tempcnt
- } // if buffindex
- else
- {
- memcpy(&tmpbuf[col_now],(buffer+bufindex),tempcnt);
- bufindex += tempcnt ;
- col_now += count;
- } // else buffindex
- } // else count
- // check if tmpbuf enough to be a row, if yes
- // output the row to board, inc row
- if ( col_now>=dcol )
- {
- for (i=col_b; i<=col_e; i++ )
- NewBitmap->Data[ NewBitmap->Width*(NewBitmap->Height-row-1)+i ] = tmpbuf[i-col_b];
- row++;
- if (row>row_e)
- quitflag = 1 ;
- len = col_now - dcol ;
- if (len>0)
- memcpy(&tmpbuf[0],&tmpbuf[dcol], (2*len) ) ;
- col_now = len;
- } // if col_now >dcol
- } // while bufindex
- // read another block to be decoded
- numread = read(infile,buffer,BufSize) ;
- } // while numread
- // if there were some data in tmpbuf, output it
- if (col_now>0) {
- for (i=col_b; i<=(col_e+col_now); i++ )
- NewBitmap->Data[ NewBitmap->Width*(NewBitmap->Height-row-1)+i ] = tmpbuf[i-col_b];
- }
- // free the allocated buffer, close opened file
- free(buffer) ;
- close(infile);
- return NewBitmap;
- }
|