forked from KolibriOS/kolibrios
c2fbdf929c
git-svn-id: svn://kolibrios.org@1805 a494cfbc-eb01-0410-851d-a64ba20cac60
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;
|
||
}
|
||
|