📄 targa_provider_generic.cpp
字号:
*a = 255;
}
//
}
pos += 2;
break;
case 24:
*b = file[pos];
*g = file[pos+1];
*r = file[pos+2];
*a = 255;
if (transparent &&
*r == trans_redcol &&
*g == trans_greencol &&
*b == trans_bluecol)
{
*a = 0;
ret = false;
}
pos += 3;
break;
case 32:
*a = file[pos+3];
if (use_alphapixels && !(*a))
{
*r = trans_redcol;
*g = trans_greencol;
*b = trans_bluecol;
ret = false;
}
else
{
*b = file[pos];
*g = file[pos+1];
*r = file[pos+2];
if (transparent &&
*r == trans_redcol &&
*g == trans_greencol &&
*b == trans_bluecol)
{
*a = 0;
ret = false;
}
//
else
if (ignore_alphachannel)
{
// else if we're not using any alphapixels at all, then alpha should be 255.
*a = 255;
}
//
}
pos += 4;
break;
}
return ret;
}
/*
Read and convert a colormap-index into an rgba-color.
This function speculates in an index to exist in the
file directly at the current position.
*/
void CL_TargaProvider_Generic::read_from_colormap(
unsigned char *a,
unsigned char *b,
unsigned char *g,
unsigned char *r)
{
if (pos >= filesize)
throw CL_Error("Invalid targa file!?");
// if the colormap is <= 256 entries large, the
// index will be contained in a byte -
// otherwise in a short
int entry;
if (map_length <= 256)
{
entry = file[pos++];
}
else
{
entry = *((unsigned short *) &file[pos]);
SWAP_IF_BIG(entry);
pos += 2;
}
if (entry < 0 || entry >= map_length)
throw CL_Error("Invalid targa file!?");
// convert index-value to rgba-values using the colormap
*r = color_map[entry*4+0];
*g = color_map[entry*4+1];
*b = color_map[entry*4+2];
*a = color_map[entry*4+3];
}
/*
CODE FOR DECODING TYPE 1 TARGA FILES
*/
void CL_TargaProvider_Generic::read_colormapped()
{
read_header(true);
image = new unsigned char[pitch * height * 4];
int ystart = map_direction_y == 1 ? 0 : height-1;
int xstart = map_direction_x == 1 ? 0 : pitch-1;
for (int y = ystart;y>=0&&y<height;y+=map_direction_y)
{
for (int x = xstart; x>=0 && x<pitch;x+=map_direction_x)
{
read_from_colormap(&image[(x+y*pitch)*4],
&image[(x+y*pitch)*4+1],
&image[(x+y*pitch)*4+2],
&image[(x+y*pitch)*4+3]);
}
}
}
/*
CODE FOR DECODING TYPE 2 TARGA FILES
*/
void CL_TargaProvider_Generic::read_uncompressed_rgb()
{
read_header(false);
int ystart = map_direction_y == 1 ? 0 : height-1;
int xstart = map_direction_x == 1 ? 0 : pitch-1;
image = new unsigned char[pitch * height * 4];
switch (bpp)
{
case 16:
{
for (int y = ystart;y>=0&&y<height;y+=map_direction_y)
{
for (int x = xstart; x>=0 && x<pitch;x+=map_direction_x)
{
bool v = read_rgb_16(&image[(x+y*pitch)*4+0],
&image[(x+y*pitch)*4+1],
&image[(x+y*pitch)*4+2],
&image[(x+y*pitch)*4+3]);
if (v)
{
if (x < bounding_left) bounding_left = x;
if (y < bounding_top) bounding_top = y;
if (x > bounding_right) bounding_right = x;
if (y > bounding_bottom) bounding_bottom = y;
}
}
}
}
break;
case 24:
{
for (int y = ystart;y>=0&&y<height;y+=map_direction_y)
{
for (int x = xstart; x>=0 && x<pitch;x+=map_direction_x)
{
bool v = read_rgb_24(&image[(x+y*pitch)*4+0],
&image[(x+y*pitch)*4+1],
&image[(x+y*pitch)*4+2],
&image[(x+y*pitch)*4+3]);
if (v)
{
if (x < bounding_left) bounding_left = x;
if (y < bounding_top) bounding_top = y;
if (x > bounding_right) bounding_right = x;
if (y > bounding_bottom) bounding_bottom = y;
}
}
}
}
break;
case 32:
{
for (int y = ystart;y>=0&&y<height;y+=map_direction_y)
{
for (int x = xstart; x>=0 && x<pitch;x+=map_direction_x)
{
bool v = read_rgb_32(&image[(x+y*pitch)*4+0],
&image[(x+y*pitch)*4+1],
&image[(x+y*pitch)*4+2],
&image[(x+y*pitch)*4+3]);
if (v)
{
if (x < bounding_left) bounding_left = x;
if (y < bounding_top) bounding_top = y;
if (x > bounding_right) bounding_right = x;
if (y > bounding_bottom) bounding_bottom = y;
}
}
}
}
break;
default:
throw CL_Error("Unknown bpp!");
}
}
/*
CODE FOR DECODING TYPE 9 TARGA FILES
*/
void CL_TargaProvider_Generic::read_runlength_encoded_colormapped_rgb()
{
read_header(true);
image = new unsigned char[pitch * height * 4];
int ystart = map_direction_y == 1 ? 0 : height-1;
int xstart = map_direction_x == 1 ? 0 : pitch-1;
int line = ystart;
int xpos = xstart;
while (line >= 0 && line < height)
{
unsigned char head = file[pos++];
unsigned char type = (head & 128)>>7;
unsigned char repcount = (head & 127)+1;
switch (type)
{
// RAW PACKET
case 0:
for (;repcount>0;repcount--)
{
read_from_colormap(&image[(xpos+line*pitch)*4],
&image[(xpos+line*pitch)*4+1],
&image[(xpos+line*pitch)*4+2],
&image[(xpos+line*pitch)*4+3]);
xpos+=map_direction_x;
if (xpos < 0 || xpos >= pitch)
{
xpos = xstart;
line += map_direction_y;
}
}
break;
// RUNLENGTH ENCODED PACKET
case 1:
{
unsigned char r, g, b, a;
read_from_colormap(&r, &g, &b, &a);
for (;repcount>0;repcount--)
{
image[((line*pitch+xpos)*4)+0] = r;
image[((line*pitch+xpos)*4)+1] = g;
image[((line*pitch+xpos)*4)+2] = b;
image[((line*pitch+xpos)*4)+3] = a;
xpos+=map_direction_x;
if (xpos < 0 || xpos >= pitch)
{
xpos = xstart;
line += map_direction_y;
}
}
}
break;
}
}
}
/*
CODE FOR DECODING TYPE 10 TARGA FILES
*/
void CL_TargaProvider_Generic::read_runlength_encoded_rgb()
{
read_header(false);
image = new unsigned char[pitch * height * 4];
int ystart = map_direction_y == 1 ? 0 : height-1;
int xstart = map_direction_x == 1 ? 0 : pitch-1;
int line = ystart;
int xpos = xstart;
while (line >= 0 && line < height)
{
unsigned char head = file[pos++];
unsigned char type = (head & 128)>>7;
unsigned char repcount = (head & 127)+1;
switch (type)
{
// RAW PACKET
case 0:
for (;repcount>0;repcount--)
{
bool v = read_rgb(&image[((line*pitch+xpos)*4)+0],
&image[((line*pitch+xpos)*4)+1],
&image[((line*pitch+xpos)*4)+2],
&image[((line*pitch+xpos)*4)+3]);
if (v)
{
if (xpos < bounding_left) bounding_left = xpos;
if (line < bounding_top) bounding_top = line;
if (xpos > bounding_right) bounding_right = xpos;
if (line > bounding_bottom) bounding_bottom = line;
}
xpos+=map_direction_x;
if (xpos < 0 || xpos >= pitch)
{
xpos = xstart;
line += map_direction_y;
}
}
break;
// RUNLENGTH ENCODED PACKET
case 1:
{
unsigned char r, g, b, a;
bool v = read_rgb(&r, &g, &b, &a);
for (;repcount>0;repcount--)
{
image[((line*pitch+xpos)*4)+0] = r;
image[((line*pitch+xpos)*4)+1] = g;
image[((line*pitch+xpos)*4)+2] = b;
image[((line*pitch+xpos)*4)+3] = a;
if (v)
{
if (xpos < bounding_left) bounding_left = xpos;
if (line < bounding_top) bounding_top = line;
if (xpos > bounding_right) bounding_right = xpos;
if (line > bounding_bottom) bounding_bottom = line;
}
xpos+=map_direction_x;
if (xpos < 0 || xpos >= pitch)
{
xpos = xstart;
line += map_direction_y;
}
}
}
break;
}
}
}
void *CL_TargaProvider_Generic::get_data()
{
return image+bounding_left*4+bounding_top*pitch*4;
}
/*
Lock the surfaceprovider - which basically means open the file
and read the image into a temporary memory buffer - until
unlock() is called.
*/
void CL_TargaProvider_Generic::perform_lock()
{
if (locked) return;
cl_assert(provider != NULL);
input_source = provider->open_source(filename.c_str());
cl_assert(input_source!=NULL);
no_sprs = 1;
filesize = input_source->size();
file = new unsigned char[filesize];
cl_assert(file != NULL);
int num_bytes_read = input_source->read(file, filesize);
cl_assert(num_bytes_read == ((int) filesize));
// read the data
read_data();
if (bounding_left > bounding_right) bounding_left = bounding_right;
if (bounding_top > bounding_bottom) bounding_top = bounding_bottom;
delete[] file;
delete input_source;
file = NULL;
locked = true;
// this could be integrated better, but since this targa class
// look like shit, and I'm too tired to clean it, I just hack CL_PixelBuffer
// support into it. -- mbn 9. feb 2002
CL_PixelBuffer_Generic::format.enable_colorkey(uses_src_colorkey());
CL_PixelBuffer_Generic::format.set_colorkey(get_src_colorkey());
CL_PixelBuffer_Generic::format.set_depth(get_depth());
CL_PixelBuffer_Generic::format.set_red_mask(get_red_mask());
CL_PixelBuffer_Generic::format.set_green_mask(get_green_mask());
CL_PixelBuffer_Generic::format.set_blue_mask(get_blue_mask());
CL_PixelBuffer_Generic::format.set_alpha_mask(get_alpha_mask());
CL_PixelBuffer_Generic::pitch = get_pitch();
CL_PixelBuffer_Generic::width = get_width();
CL_PixelBuffer_Generic::height = get_height();
}
void CL_TargaProvider_Generic::perform_unlock()
{
locked = false;
delete[] color_map;
delete[] image;
image = color_map = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -