Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1805 yogev_ezra 1
#include "kosSyst.h"
2
#include "KosFile.h"
3
#include "gfxdef.h"
4
#include "crc32.h"
5
 
6
extern "C" void __stdcall lzma_decompress(
7
	 const void* source,
8
	 void* destination,
9
	 unsigned dest_length);
10
 
11
struct export_item
12
{
13
	const char* name;
14
	const void* func;
15
};
16
 
17
typedef void* (__stdcall *img_decode_t)(const void* data, unsigned len, void* parameters);
18
typedef void (__stdcall *img_to_rgb2_t)(const void* image, void* destination);
19
typedef void (__stdcall *img_destroy_t)(void* image);
20
typedef void (__stdcall *img_lib_init_t)(void);	// really fastcall with 4 args, but called from asm code
21
 
22
img_lib_init_t img_lib_init = NULL;
23
img_decode_t img_decode = NULL;
24
img_to_rgb2_t img_to_rgb2 = NULL;
25
img_destroy_t img_destroy = NULL;
26
 
27
export_item* libini_exports = NULL;
28
static const char libini_name[] = "/sys/lib/libimg.obj";
29
 
30
extern "C" int strcmp(const char* str1, const char* str2);
31
#pragma intrinsic(strcmp)
32
 
33
void jpeg_decompress(
34
	 const void* source,
35
	 unsigned source_length,
36
	 void* destination,
37
	 unsigned dest_length)
38
{
39
	if (!libini_exports)
40
	{
41
		__asm
42
		{
43
			mov	eax, 68
44
			mov	ebx, 19
45
			mov	ecx, offset libini_name
46
			int	40h
47
			mov	[libini_exports], eax
48
		}
49
		if (!libini_exports)
50
		{
51
			rtlDebugOutString("Cannot load libimg.obj");
52
			kos_ExitApp();
53
		}
54
		for (export_item* p = libini_exports; p->name; p++)
55
		{
56
			if (!strcmp(p->name,"lib_init"))
57
				img_lib_init = (img_lib_init_t)p->func;
58
			else if (!strcmp(p->name,"img_decode"))
59
				img_decode = (img_decode_t)p->func;
60
			else if (!strcmp(p->name,"img_to_rgb2"))
61
				img_to_rgb2 = (img_to_rgb2_t)p->func;
62
			else if (!strcmp(p->name,"img_destroy"))
63
				img_destroy = (img_destroy_t)p->func;
64
		}
65
		if (!img_lib_init || !img_decode || !img_to_rgb2 || !img_destroy)
66
		{
67
			rtlDebugOutString("Required exports were not found in libimg.obj");
68
			kos_ExitApp();
69
		}
70
		__asm
71
		{
72
			mov	eax, offset kos_malloc
73
			mov	ebx, offset kos_free
74
			mov	ecx, offset kos_realloc
75
			call	img_lib_init
76
		}
77
	}
78
	void* image = img_decode(source, source_length, NULL);
79
	if (!image)
80
	{
81
		rtlDebugOutString("JPEG error");
82
		kos_ExitApp();
83
	}
84
	img_to_rgb2(image, destination);
85
	img_destroy(image);
86
}
87
 
88
//////  CKosBitmap
89
 
90
CKosBitmap::CKosBitmap()
91
{
92
	this->bmpID = -1;
93
	this->buffer = NULL;
94
	this->sizeX = 0;
95
	this->sizeY = 0;
96
}
97
 
98
 
99
CKosBitmap::~CKosBitmap()
100
{
101
	if ( this->buffer != NULL ) delete this->buffer;
102
}
103
 
104
 
105
// загрузка из сжатого файла
106
bool CKosBitmap::LoadFromArch( SCompBmpHeader *bmpArchDesc, CKosFile *fromFile, int ID )
107
{
108
	Byte *tmpBuff;
109
 
110
	//
111
	if ( this->buffer != NULL )
112
	{
113
		delete this->buffer;
114
		this->buffer = NULL;
115
	}
116
	//
117
	this->buffer = new RGB[bmpArchDesc->sizeX * bmpArchDesc->sizeY];
118
	//
119
	tmpBuff = new Byte[bmpArchDesc->compressedSize];
120
	//
121
	fromFile->Seek( SEEK_SET, bmpArchDesc->physicalOffset );
122
	if ( fromFile->Read( tmpBuff, bmpArchDesc->compressedSize ) == bmpArchDesc->compressedSize )
123
	{
124
		//
125
		if ( bmpArchDesc->compressedSize == bmpArchDesc->uncompressedSize+1)
126
		{
127
			// JPEG image
128
			jpeg_decompress( tmpBuff, bmpArchDesc->compressedSize,
129
				this->buffer, bmpArchDesc->sizeX * bmpArchDesc->sizeY * 3);
130
		}
131
		else if ( bmpArchDesc->compressedSize != bmpArchDesc->uncompressedSize )
132
		{
133
			// LZMA-packed BMP
134
			lzma_decompress( tmpBuff, this->buffer, bmpArchDesc->uncompressedSize);
135
		}
136
		else
137
		{
138
			//
139
			memcpy( (Byte *)(this->buffer), tmpBuff, bmpArchDesc->compressedSize );
140
		}
141
		//
142
		this->sizeX = bmpArchDesc->sizeX;
143
		this->sizeY = bmpArchDesc->sizeY;
144
		this->bmpID = ID;
145
	}
146
	//
147
	delete tmpBuff;
148
	//
149
	return true;
150
}
151
 
152
 
153
// вывести в окно картинку
154
void CKosBitmap::Draw( Word x, Word y )
155
{
156
	//
157
	if ( this->buffer != NULL )
158
		//
159
		kos_PutImage( this->buffer, this->sizeX, this->sizeY, x, y );
160
}
161
 
162
 
163
// получить указатель на область данных
164
RGB * CKosBitmap::GetBits()
165
{
166
	return this->buffer;
167
}
168
 
169
 
170
// получить размер картинки
171
void CKosBitmap::GetSize( Word &cx, Word &cy )
172
{
173
	cx = this->sizeX;
174
	cy = this->sizeY;
175
}
176
 
177
// создать картинку из большей
178
void CKosBitmap::Scale(Word size, RGB *mainBits)
179
{
180
	buffer = new RGB[(sizeX=blockSize)*(sizeY=blockSize*11)];
181
	memset((Byte*)buffer,0,3*blockSize*blockSize*11);
182
	RGB* tmpBuf = new RGB[blockSize*size];
183
	for (int k=0;k<11;k++)
184
	{
185
		int delta = (blockSize - size)/2;
186
		int i,j;
187
		int a;
188
		int d1 = blockSize/size;
189
		int d2 = (blockSize-d1*(size))*256/size;
190
		// сглаживание по горизонтали
191
		RGB* ptrBuf = tmpBuf;
192
		for (j=0;j
193
		{
194
			RGB* srcBits = mainBits + blockSize*blockSize*(k+1) + blockSize*j;
195
			a = 0;
196
			for (i=0;i
197
			{
198
				ptrBuf->b = srcBits->b + (srcBits[1].b-srcBits[0].b)*a/256;
199
				ptrBuf->g = srcBits->g + (srcBits[1].g-srcBits[0].g)*a/256;
200
				ptrBuf->r = srcBits->r + (srcBits[1].r-srcBits[0].r)*a/256;
201
				ptrBuf++;
202
				srcBits += d1;
203
				a += d2;
204
				if (a >= 256)
205
				{
206
					a -= 256;
207
					srcBits++;
208
				}
209
			}
210
		}
211
		// сглаживание по вертикали
212
		for (j=0;j
213
		{
214
			ptrBuf = buffer + blockSize*blockSize*k + blockSize*delta + delta+j;
215
			RGB* srcBits = tmpBuf + j;
216
			a = 0;
217
			for (i=0;i
218
			{
219
				ptrBuf->b = srcBits->b + (srcBits[size].b-srcBits[0].b)*a/256;
220
				ptrBuf->g = srcBits->g + (srcBits[size].g-srcBits[0].g)*a/256;
221
				ptrBuf->r = srcBits->r + (srcBits[size].r-srcBits[0].r)*a/256;
222
				ptrBuf += blockSize;
223
				srcBits += d1*size;
224
				a += d2;
225
				if (a >= 256)
226
				{
227
					a -= 256;
228
					srcBits += size;
229
				}
230
			}
231
		}
232
	}
233
	delete tmpBuf;
234
}
235
 
236
 
237
////////////////////// CFishka ///////////////////////
238
 
239
CFishka::CFishka( CKosBitmap *fromBmp, int yOffset, RGB insColour )
240
{
241
	int i, c;
242
 
243
	//
244
	this->bits = fromBmp->GetBits() + (yOffset * blockSize);
245
	this->transColour = insColour;
246
	//
247
	this->highLighted = new RGB[blockSize * blockSize];
248
	//
249
	for ( i = 0; i < (blockSize * blockSize); i++ )
250
	{
251
		//
252
		this->highLighted[i] = this->bits[i];
253
		//
254
		if ( this->highLighted[i] != this->transColour )
255
		{
256
			c = ( this->highLighted[i].b * 185 ) / 100;
257
			this->highLighted[i].b = (c > 255) ? 255 : c;
258
			c = ( this->highLighted[i].g * 185 ) / 100;
259
			this->highLighted[i].g = (c > 255) ? 255 : c;
260
			c = ( this->highLighted[i].r * 185 ) / 100;
261
			this->highLighted[i].r = (c > 255) ? 255 : c;
262
		}
263
	}
264
}
265
 
266
//
267
CFishka::~CFishka()
268
{
269
	//
270
	delete this->highLighted;
271
}
272
 
273
 
274
//
275
RGB * CFishka::GetBits()
276
{
277
	return this->bits;
278
}
279
 
280
//
281
RGB * CFishka::GetHighlightedBits()
282
{
283
	return this->highLighted;
284
}
285