📄 image.cpp
字号:
/*
image.c Copyright (C) 1998-1999 Damir Sagidullin
*/
#include <stdlib.h>
#include <stdio.h>
#include "unpak.h"
//#include "console.h"
#include "image.h"
//------------------- DEFINITIONS & CONSTANTS -------------------//
#pragma pack (push, 1)
typedef struct
{// targa file header
byte id_length;
byte colormap_type;
byte image_type;
ushort colormap_index;
ushort colormap_length;
byte colormap_size;
ushort x_origin, y_origin;
ushort width, height;
byte pixel_size;
byte attributes;
} tga_header_t;
typedef struct
{
char *data;
int width;
int height;
} picinfo_t;
//-------------------------- VARIABLES --------------------------//
static char *filedata;
//-------------------------- FUNCTIONS --------------------------//
int jpeg_decompress (char *buf, int size, picinfo_t *pi);
void CalculateImageColor (bitmap *bm);
int TargaDecode (bitmap *bm, byte *data, int size, char *name);
int JpegDecode (bitmap *bm, char *data, int size, char *name);
int ReadImage (bitmap *bm, char *name, packfile_t *pf)
{
int size;
char *data, *file_ext;
int result;
bm->data = NULL;
bm->texturenum = -1;
if((size = PackFileGet (pf, name, &data)) <=0 ) return FALSE;
file_ext = strchr (name, '.');
if (file_ext == NULL)
{
MessageBox(NULL, "Unknown image \"%s\" format", "Error", NULL);
return FALSE;
}
if (!strcmp (file_ext, ".tga"))
result = TargaDecode (bm , (byte *)data, size, name);
else
if (!strcmp (file_ext, ".jpg"))
result = JpegDecode (bm , data, size, name);
else
{
MessageBox(NULL, "Unknown image \"%s\" format", "Error", NULL);
return FALSE;
}
free (data);
if (result) CalculateImageColor (bm);
return result;
}
void CalculateImageColor (bitmap *bm)
{
int red, green, blue, gray;
int i, numPixels;
byte *src;
if (bm->data == NULL) return;
red = green = blue = gray = 0;
i = numPixels = bm->width * bm->height;
src = (byte *)bm->data;
if (bm->bpp == 24)
{
while ((i--) > 0)
{
red += *src++;
green += *src++;
blue += *src++;
}
} else
if (bm->bpp == 32)
{
while ((i--) > 0)
{
red += *src++;
green += *src++;
blue += *src++;
src++;
}
} else
if (bm->bpp == 8)
{
while ((i--) > 0)
{
gray += *src++;
}
red = green = blue = gray;
}
bm->r = red / numPixels;
bm->g = green / numPixels;
bm->b = blue / numPixels;
}
int TargaDecode (bitmap *bm, byte *data, int size, char *name)
{
int width, height, numPixels;
int row, column;
byte red, green, blue, alpha;
byte packetHeader, packetSize, j;
byte bytesPerPixel;
byte *rgba, *dest;
tga_header_t *header;
header = (tga_header_t *)data;
data += sizeof(tga_header_t);
// Only types 2 and 10 are supported
if (header->image_type!=2 && header->image_type!=10)
{;
MessageBox(NULL, "Unsupported tga image \"%s\" type (type=%d)", "Error", NULL);
return FALSE;
}
// Only 24bit or 32bit pixels are supported
if ((header->colormap_type!=0)
|| (header->pixel_size!=32 && header->pixel_size!=24))
{
MessageBox(NULL, "Unsupported tga image \"%s\" pixel size (size=%d)", "Error", NULL);
return FALSE;
}
bm->width = width = header->width;
bm->height = height = header->height;
bm->bpp = header->pixel_size;
numPixels = width * height;
bytesPerPixel = (header->pixel_size == 32) ? 4 : 3;
// Allocate memory for decoded image
rgba = (byte *)malloc(numPixels * bytesPerPixel);
if (!rgba)
{
MessageBox(NULL, "Can't allocate memory (size=%d)", "Error", NULL);
return FALSE;
}
if (header->image_type == 2)
{// Uncompressed RGB image
row = height;
while ((row--) > 0)
{
if (header->attributes & 0x20)
dest = rgba + (height - row - 1)*width*bytesPerPixel;
else
dest = rgba + row*width*bytesPerPixel;
for (column=0; column<width; column++)
{
if (header->pixel_size == 24)
{
blue = *data++;
green = *data++;
red = *data++;
*dest++ = red;
*dest++ = green;
*dest++ = blue;
} else
if (header->pixel_size == 32)
{
blue = *data++;
green = *data++;
red = *data++;
alpha = *data++;
*dest++ = red;
*dest++ = green;
*dest++ = blue;
*dest++ = alpha;
}
}
}
} else
if (header->image_type==10)
{// RLE RGB image
row = height;
while ((row--) > 0)
{
if (header->attributes & 0x20)
dest = rgba + (height - row - 1)*width*bytesPerPixel;
else
dest = rgba + row*width*bytesPerPixel;
for (column=0; column<width; )
{
packetHeader = *data++;
packetSize = 1 + (packetHeader & 0x7f);
// RLE packet
if (packetHeader & 0x80)
{
if (header->pixel_size==24)
{
blue = *data++;
green = *data++;
red = *data++;
} else
if (header->pixel_size==32)
{
blue = *data++;
green = *data++;
red = *data++;
alpha = *data++;
}
for (j=0; j<packetSize; j++)
{
*dest++ = red;
*dest++ = green;
*dest++ = blue;
if(header->pixel_size==32) *dest++ = alpha;
column++;
if (column == width)
{
column = 0;
if (row > 0) row--;
else goto end_decode;
if (header->attributes & 0x20)
dest = rgba + (height - row - 1)*width*bytesPerPixel;
else
dest = rgba + row*width*bytesPerPixel;
}
}
} else
{// Non-RLE packet
for (j=0; j<packetSize; j++)
{
if (header->pixel_size == 24)
{
blue = *data++;
green = *data++;
red = *data++;
*dest++ = red;
*dest++ = green;
*dest++ = blue;
} else
{
blue = *data++;
green = *data++;
red = *data++;
alpha = *data++;
*dest++ = red;
*dest++ = green;
*dest++ = blue;
*dest++ = alpha;
}
column++;
if (column == width)
{
column = 0;
if (row > 0) row--;
else goto end_decode;
if (header->attributes & 0x20)
dest = rgba + (height - row - 1)*width*bytesPerPixel;
else
dest = rgba + row*width*bytesPerPixel;
}
}
}
}
end_decode:;
}
}
bm->data = (byte *)rgba;
return TRUE;
}
int JpegDecode (bitmap *bm, char *data, int size, char *name)
{
picinfo_t pi;
if (jpeg_decompress (data, size, &pi))
{
MessageBox(NULL, "Can't decompress jpeg image \"%s\"", "Error", NULL);
return FALSE;
}
bm->data = (byte *)pi.data;
bm->width = pi.width;
bm->height = pi.height;
bm->bpp = 24;
return TRUE;;
}
void ConvertImageToGrayscale (bitmap *bm)
{
int i, numPixels;
byte *dest, *src;
bitmap src_bm = *bm;
if (src_bm.data == NULL) return;
i = numPixels = src_bm.width * src_bm.height;
dest = (byte *)malloc (numPixels);
src = (byte *)src_bm.data;
bm->data = (byte *)dest;
if (bm->bpp == 24)
while ((i--)>0)
{
*dest++ = (*(src) + *(src+1) + *(src+2))/3;
src += 3;
}
else
if (bm->bpp == 32)
while ((i--)>0)
{
*dest++ = (*(src) + *(src+1) + *(src+2))/3;
src += 4;
}
bm->r = bm->g = bm->b = (bm->r + bm->g + bm->b)/3;
bm->bpp = 8;
free (src_bm.data);
}
void ResizeImage (bitmap *bm, int width, int height)
{
int i, j, k, x, y, offset_y, offset_x, bytesPerPixel;
byte *dest, *src;
bitmap src_bm = *bm;
if (!width || !height) return;
if (src_bm.data == NULL) return;
bytesPerPixel = (src_bm.bpp + 1) >> 3;
dest = (byte *)malloc (width * height * bytesPerPixel);
src = (byte *)src_bm.data;
bm->data = (byte *)dest;
bm->width = width;
bm->height = height;
for (j=0; j<height; j++)
{
y = (j * src_bm.height) / height;
offset_y = y * src_bm.width;
for (i=0; i<width; i++)
{
x = (i * src_bm.width) / width;
offset_x = (offset_y + x) * bytesPerPixel;
for (k=0; k<bytesPerPixel; k++)
*dest++ = src[offset_x++];
}
}
free (src_bm.data);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -