forked from KolibriOS/kolibrios
286 lines
6.4 KiB
C++
286 lines
6.4 KiB
C++
|
#include "kosSyst.h"
|
|||
|
#include "KosFile.h"
|
|||
|
#include "gfxdef.h"
|
|||
|
#include "crc32.h"
|
|||
|
|
|||
|
extern "C" void __stdcall lzma_decompress(
|
|||
|
const void* source,
|
|||
|
void* destination,
|
|||
|
unsigned dest_length);
|
|||
|
|
|||
|
struct export_item
|
|||
|
{
|
|||
|
const char* name;
|
|||
|
const void* func;
|
|||
|
};
|
|||
|
|
|||
|
typedef void* (__stdcall *img_decode_t)(const void* data, unsigned len, void* parameters);
|
|||
|
typedef void (__stdcall *img_to_rgb2_t)(const void* image, void* destination);
|
|||
|
typedef void (__stdcall *img_destroy_t)(void* image);
|
|||
|
typedef void (__stdcall *img_lib_init_t)(void); // really fastcall with 4 args, but called from asm code
|
|||
|
|
|||
|
img_lib_init_t img_lib_init = NULL;
|
|||
|
img_decode_t img_decode = NULL;
|
|||
|
img_to_rgb2_t img_to_rgb2 = NULL;
|
|||
|
img_destroy_t img_destroy = NULL;
|
|||
|
|
|||
|
export_item* libini_exports = NULL;
|
|||
|
static const char libini_name[] = "/sys/lib/libimg.obj";
|
|||
|
|
|||
|
extern "C" int strcmp(const char* str1, const char* str2);
|
|||
|
#pragma intrinsic(strcmp)
|
|||
|
|
|||
|
void jpeg_decompress(
|
|||
|
const void* source,
|
|||
|
unsigned source_length,
|
|||
|
void* destination,
|
|||
|
unsigned dest_length)
|
|||
|
{
|
|||
|
if (!libini_exports)
|
|||
|
{
|
|||
|
__asm
|
|||
|
{
|
|||
|
mov eax, 68
|
|||
|
mov ebx, 19
|
|||
|
mov ecx, offset libini_name
|
|||
|
int 40h
|
|||
|
mov [libini_exports], eax
|
|||
|
}
|
|||
|
if (!libini_exports)
|
|||
|
{
|
|||
|
rtlDebugOutString("Cannot load libimg.obj");
|
|||
|
kos_ExitApp();
|
|||
|
}
|
|||
|
for (export_item* p = libini_exports; p->name; p++)
|
|||
|
{
|
|||
|
if (!strcmp(p->name,"lib_init"))
|
|||
|
img_lib_init = (img_lib_init_t)p->func;
|
|||
|
else if (!strcmp(p->name,"img_decode"))
|
|||
|
img_decode = (img_decode_t)p->func;
|
|||
|
else if (!strcmp(p->name,"img_to_rgb2"))
|
|||
|
img_to_rgb2 = (img_to_rgb2_t)p->func;
|
|||
|
else if (!strcmp(p->name,"img_destroy"))
|
|||
|
img_destroy = (img_destroy_t)p->func;
|
|||
|
}
|
|||
|
if (!img_lib_init || !img_decode || !img_to_rgb2 || !img_destroy)
|
|||
|
{
|
|||
|
rtlDebugOutString("Required exports were not found in libimg.obj");
|
|||
|
kos_ExitApp();
|
|||
|
}
|
|||
|
__asm
|
|||
|
{
|
|||
|
mov eax, offset kos_malloc
|
|||
|
mov ebx, offset kos_free
|
|||
|
mov ecx, offset kos_realloc
|
|||
|
call img_lib_init
|
|||
|
}
|
|||
|
}
|
|||
|
void* image = img_decode(source, source_length, NULL);
|
|||
|
if (!image)
|
|||
|
{
|
|||
|
rtlDebugOutString("JPEG error");
|
|||
|
kos_ExitApp();
|
|||
|
}
|
|||
|
img_to_rgb2(image, destination);
|
|||
|
img_destroy(image);
|
|||
|
}
|
|||
|
|
|||
|
////// CKosBitmap
|
|||
|
|
|||
|
CKosBitmap::CKosBitmap()
|
|||
|
{
|
|||
|
this->bmpID = -1;
|
|||
|
this->buffer = NULL;
|
|||
|
this->sizeX = 0;
|
|||
|
this->sizeY = 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
CKosBitmap::~CKosBitmap()
|
|||
|
{
|
|||
|
if ( this->buffer != NULL ) delete this->buffer;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>㧪<EFBFBD> <20><> ᦠ⮣<E1A6A0> 䠩<><E4A0A9>
|
|||
|
bool CKosBitmap::LoadFromArch( SCompBmpHeader *bmpArchDesc, CKosFile *fromFile, int ID )
|
|||
|
{
|
|||
|
Byte *tmpBuff;
|
|||
|
|
|||
|
//
|
|||
|
if ( this->buffer != NULL )
|
|||
|
{
|
|||
|
delete this->buffer;
|
|||
|
this->buffer = NULL;
|
|||
|
}
|
|||
|
//
|
|||
|
this->buffer = new RGB[bmpArchDesc->sizeX * bmpArchDesc->sizeY];
|
|||
|
//
|
|||
|
tmpBuff = new Byte[bmpArchDesc->compressedSize];
|
|||
|
//
|
|||
|
fromFile->Seek( SEEK_SET, bmpArchDesc->physicalOffset );
|
|||
|
if ( fromFile->Read( tmpBuff, bmpArchDesc->compressedSize ) == bmpArchDesc->compressedSize )
|
|||
|
{
|
|||
|
//
|
|||
|
if ( bmpArchDesc->compressedSize == bmpArchDesc->uncompressedSize+1)
|
|||
|
{
|
|||
|
// JPEG image
|
|||
|
jpeg_decompress( tmpBuff, bmpArchDesc->compressedSize,
|
|||
|
this->buffer, bmpArchDesc->sizeX * bmpArchDesc->sizeY * 3);
|
|||
|
}
|
|||
|
else if ( bmpArchDesc->compressedSize != bmpArchDesc->uncompressedSize )
|
|||
|
{
|
|||
|
// LZMA-packed BMP
|
|||
|
lzma_decompress( tmpBuff, this->buffer, bmpArchDesc->uncompressedSize);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
memcpy( (Byte *)(this->buffer), tmpBuff, bmpArchDesc->compressedSize );
|
|||
|
}
|
|||
|
//
|
|||
|
this->sizeX = bmpArchDesc->sizeX;
|
|||
|
this->sizeY = bmpArchDesc->sizeY;
|
|||
|
this->bmpID = ID;
|
|||
|
}
|
|||
|
//
|
|||
|
delete tmpBuff;
|
|||
|
//
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// <20>뢥<EFBFBD><EBA2A5><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>⨭<EFBFBD><E2A8AD>
|
|||
|
void CKosBitmap::Draw( Word x, Word y )
|
|||
|
{
|
|||
|
//
|
|||
|
if ( this->buffer != NULL )
|
|||
|
//
|
|||
|
kos_PutImage( this->buffer, this->sizeX, this->sizeY, x, y );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 㪠<><E3AAA0>⥫<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
RGB * CKosBitmap::GetBits()
|
|||
|
{
|
|||
|
return this->buffer;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ࠧ<><E0A0A7><EFBFBD> <20><><EFBFBD>⨭<EFBFBD><E2A8AD>
|
|||
|
void CKosBitmap::GetSize( Word &cx, Word &cy )
|
|||
|
{
|
|||
|
cx = this->sizeX;
|
|||
|
cy = this->sizeY;
|
|||
|
}
|
|||
|
|
|||
|
// ᮧ<><E1AEA7><EFBFBD><EFBFBD> <20><><EFBFBD>⨭<EFBFBD><E2A8AD> <20><> <20><><EFBFBD><EFBFBD>襩
|
|||
|
void CKosBitmap::Scale(Word size, RGB *mainBits)
|
|||
|
{
|
|||
|
buffer = new RGB[(sizeX=blockSize)*(sizeY=blockSize*11)];
|
|||
|
memset((Byte*)buffer,0,3*blockSize*blockSize*11);
|
|||
|
RGB* tmpBuf = new RGB[blockSize*size];
|
|||
|
for (int k=0;k<11;k++)
|
|||
|
{
|
|||
|
int delta = (blockSize - size)/2;
|
|||
|
int i,j;
|
|||
|
int a;
|
|||
|
int d1 = blockSize/size;
|
|||
|
int d2 = (blockSize-d1*(size))*256/size;
|
|||
|
// ᣫ<><E1A3AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><>ਧ<EFBFBD><E0A8A7>⠫<EFBFBD>
|
|||
|
RGB* ptrBuf = tmpBuf;
|
|||
|
for (j=0;j<blockSize;j++)
|
|||
|
{
|
|||
|
RGB* srcBits = mainBits + blockSize*blockSize*(k+1) + blockSize*j;
|
|||
|
a = 0;
|
|||
|
for (i=0;i<size;i++)
|
|||
|
{
|
|||
|
ptrBuf->b = srcBits->b + (srcBits[1].b-srcBits[0].b)*a/256;
|
|||
|
ptrBuf->g = srcBits->g + (srcBits[1].g-srcBits[0].g)*a/256;
|
|||
|
ptrBuf->r = srcBits->r + (srcBits[1].r-srcBits[0].r)*a/256;
|
|||
|
ptrBuf++;
|
|||
|
srcBits += d1;
|
|||
|
a += d2;
|
|||
|
if (a >= 256)
|
|||
|
{
|
|||
|
a -= 256;
|
|||
|
srcBits++;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
// ᣫ<><E1A3AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>⨪<EFBFBD><E2A8AA><EFBFBD>
|
|||
|
for (j=0;j<size;j++)
|
|||
|
{
|
|||
|
ptrBuf = buffer + blockSize*blockSize*k + blockSize*delta + delta+j;
|
|||
|
RGB* srcBits = tmpBuf + j;
|
|||
|
a = 0;
|
|||
|
for (i=0;i<size;i++)
|
|||
|
{
|
|||
|
ptrBuf->b = srcBits->b + (srcBits[size].b-srcBits[0].b)*a/256;
|
|||
|
ptrBuf->g = srcBits->g + (srcBits[size].g-srcBits[0].g)*a/256;
|
|||
|
ptrBuf->r = srcBits->r + (srcBits[size].r-srcBits[0].r)*a/256;
|
|||
|
ptrBuf += blockSize;
|
|||
|
srcBits += d1*size;
|
|||
|
a += d2;
|
|||
|
if (a >= 256)
|
|||
|
{
|
|||
|
a -= 256;
|
|||
|
srcBits += size;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
delete tmpBuf;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
////////////////////// CFishka ///////////////////////
|
|||
|
|
|||
|
CFishka::CFishka( CKosBitmap *fromBmp, int yOffset, RGB insColour )
|
|||
|
{
|
|||
|
int i, c;
|
|||
|
|
|||
|
//
|
|||
|
this->bits = fromBmp->GetBits() + (yOffset * blockSize);
|
|||
|
this->transColour = insColour;
|
|||
|
//
|
|||
|
this->highLighted = new RGB[blockSize * blockSize];
|
|||
|
//
|
|||
|
for ( i = 0; i < (blockSize * blockSize); i++ )
|
|||
|
{
|
|||
|
//
|
|||
|
this->highLighted[i] = this->bits[i];
|
|||
|
//
|
|||
|
if ( this->highLighted[i] != this->transColour )
|
|||
|
{
|
|||
|
c = ( this->highLighted[i].b * 185 ) / 100;
|
|||
|
this->highLighted[i].b = (c > 255) ? 255 : c;
|
|||
|
c = ( this->highLighted[i].g * 185 ) / 100;
|
|||
|
this->highLighted[i].g = (c > 255) ? 255 : c;
|
|||
|
c = ( this->highLighted[i].r * 185 ) / 100;
|
|||
|
this->highLighted[i].r = (c > 255) ? 255 : c;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
CFishka::~CFishka()
|
|||
|
{
|
|||
|
//
|
|||
|
delete this->highLighted;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
RGB * CFishka::GetBits()
|
|||
|
{
|
|||
|
return this->bits;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
RGB * CFishka::GetHighlightedBits()
|
|||
|
{
|
|||
|
return this->highLighted;
|
|||
|
}
|
|||
|
|