Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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<blockSize;j++)
  193.                 {
  194.                         RGB* srcBits = mainBits + blockSize*blockSize*(k+1) + blockSize*j;
  195.                         a = 0;
  196.                         for (i=0;i<size;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<size;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<size;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.  
  286.