00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00042 #include "omicron/internal.h"
00043 #include "omicron/file.h"
00044 #include "omicron/render.h"
00045 #include "omicron/image.h"
00046
00047
00048
00049
00050
00051
00052
00053
00054 #define IDT_RGB 2
00055 #define IDT_RGBRLE 10
00056
00057
00058 static ulong _tga_imagedatatype;
00059 static uchar _tga_idfieldsize;
00060 static ulong _tga_bottomup;
00061 static ulong _tga_interleave;
00062 static long _tga_dataofs;
00063 static ulong _tga_origx,
00064 _tga_origy;
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 bool image_c::load_tga_rgb
00076 (
00077 file_t *file
00078 )
00079 {
00080 AssertReturnValue1(file, false);
00081
00082 char *wp;
00083 char r,g,b,a;
00084
00085
00086 buflen = width*height*4;
00087 buf = new char[buflen];
00088
00089 if (!buf)
00090 return false;
00091
00092
00093 wp = buf;
00094
00095
00096 if (_tga_bottomup)
00097 wp += buflen-width*4;
00098
00099
00100 gv.fileman->seek( file, _tga_dataofs, SEEK_SET );
00101
00102
00103 while( !gv.fileman->eof(file) && wp >= buf && wp < buf+buflen)
00104 {
00105 gv.fileman->getpixel( file, &r, &g, &b, &a, bpp );
00106
00107 *wp = r; wp++;
00108 *wp = g; wp++;
00109 *wp = b; wp++;
00110 *wp = a; wp++;
00111
00112 if ( _tga_bottomup && (wp-buf) % (width * 4) == 0 )
00113 wp -= width*4*2;
00114 }
00115
00116 bpp = 32;
00117 gv.fileman->close(file);
00118 return true;
00119 }
00120
00121 bool image_c::load_tga_rgbrle
00122 (
00123 file_t *file
00124 )
00125 {
00126 AssertReturnValue1(file, false);
00127
00128 char *wp;
00129 char r,g,b,a;
00130 ulong x, y;
00131
00132
00133 buflen = width * height * 4;
00134 buf = new char[buflen];
00135
00136 if (!buf)
00137 return false;
00138
00139
00140 gv.fileman->seek( file, _tga_dataofs, SEEK_SET );
00141
00142 y = x = 0;
00143 if (_tga_bottomup)
00144 y = height-1;
00145
00146 wp = buf;
00147
00148
00149 while(!gv.fileman->eof(file) && y>=0 && y<height)
00150 {
00151 uchar h = (uchar)gv.fileman->getch(file);
00152 ulong count;
00153
00154 count = (h&0x7f)+1;
00155
00156 if (h&0x80)
00157 {
00158 gv.fileman->getpixel( file, &r, &g, &b, &a, bpp );
00159
00160 for ( ulong i=0; i<count; i++ )
00161 {
00162 long ofs = (x+y*width)*4;
00163
00164 wp[0+ofs] = r;
00165 wp[1+ofs] = g;
00166 wp[2+ofs] = b;
00167 wp[3+ofs] = a;
00168
00169 x++;
00170
00171 if ( x >= width )
00172 {
00173 x %= width;
00174 if (_tga_bottomup)
00175 y--;
00176 else
00177 y++;
00178 }
00179 }
00180
00181 }
00182 else
00183 {
00184 for ( ulong i=0; i<count; i++ )
00185 {
00186 gv.fileman->getpixel( file, &r, &g, &b, &a, bpp );
00187
00188 long ofs = (x+y*width)*4;
00189
00190 wp[0+ofs] = r;
00191 wp[1+ofs] = g;
00192 wp[2+ofs] = b;
00193 wp[3+ofs] = a;
00194
00195 x++;
00196
00197 if ( x>= width )
00198 {
00199 x %= width;
00200 if (_tga_bottomup)
00201 y--;
00202 else
00203 y++;
00204 }
00205 }
00206
00207 }
00208 }
00209
00210 bpp = 32;
00211 gv.fileman->close(file);
00212 return true;
00213 }
00214
00215
00216
00217
00218
00219 bool image_c::load_tga(const char *filename)
00220 {
00221 AssertReturnValue1(filename, false);
00222
00223 file_t *file = gv.fileman->load(filename, false);
00224
00225 AssertReturnValue1(file, false);
00226
00227 SafeArrayDelete(buf);
00228
00229 gv.fileman->getch(file);
00230
00231 _tga_idfieldsize = (uchar)gv.fileman->getch(file);
00232 _tga_imagedatatype = (uchar)gv.fileman->getch(file);
00233
00234 gv.fileman->seek( file, 8, SEEK_SET );
00235
00236 _tga_origx = gv.fileman->getch(file) | gv.fileman->getch(file)<<8;
00237 _tga_origy = gv.fileman->getch(file) | gv.fileman->getch(file)<<8;
00238
00239
00240 width = (ushort)gv.fileman->getch(file);
00241 width |= (ushort)gv.fileman->getch(file)<<8;
00242
00243 height = (ushort)gv.fileman->getch(file);
00244 height |= (ushort)gv.fileman->getch(file)<<8;
00245
00246 bpp = (char)gv.fileman->getch(file);
00247
00248 if (bpp == 32)
00249 hasalpha = true;
00250 else
00251 hasalpha = false;
00252
00253 char bb = (char)gv.fileman->getch(file);
00254 _tga_bottomup = !(bb & 1<<5);
00255 _tga_interleave = bb & 3<<6;
00256
00257 _tga_dataofs = 18+_tga_idfieldsize;
00258
00259 switch(_tga_imagedatatype)
00260 {
00261 case IDT_RGB: return load_tga_rgb( file );
00262 case IDT_RGBRLE: return load_tga_rgbrle( file );
00263 }
00264 return false;
00265 }