Subversion Repositories Kolibri OS

Rev

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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. extern "C" __stdcall lzma_set_dict_size(unsigned logdictsize);
  5. extern "C" __stdcall lzma_compress(
  6.         const void* source,
  7.         void* destination,
  8.         unsigned length,
  9.         void* workmem);
  10.  
  11. typedef struct
  12. {
  13.         short int sizeX;
  14.         short int sizeY;
  15.         int compressedSize;
  16.         int physicalOffset;
  17.         int uncompressedSize;
  18. } SCompBmpHeader;
  19.  
  20. int main(int argc, char* argv[])
  21. {
  22.         if (argc < 3)
  23.         {
  24.                 printf("Usage: bmp2src <destination> <src1> <src2> ...\n");
  25.                 return 1;
  26.         }
  27.         FILE* fo = fopen(argv[1], "wb");
  28.         if (!fo)
  29.         {
  30.                 printf("Cannot create destination file\n");
  31.                 return 2;
  32.         }
  33.         int n=0;
  34.         SCompBmpHeader* hea = (SCompBmpHeader*)malloc((argc-2)*sizeof(SCompBmpHeader));
  35.         void** ptrs = (void**)malloc((argc-2)*4);
  36.         lzma_set_dict_size(20);
  37.         void* workmem = (void*)malloc(0x509000 + (1<<20)*19/2);
  38.         for (int i=2;i<argc;i++)
  39.         {
  40.                 FILE* fi = fopen(argv[i], "rb");
  41.                 if (!fi)
  42.                 {
  43.                         printf("Cannot open input file %s\n",argv[i]);
  44.                         continue;
  45.                 }
  46.                 unsigned char buf[0x36];
  47.                 fread(buf,1,0x36,fi);
  48.                 if (buf[0] != 'B' || buf[1] != 'M')
  49.                 {
  50.                         if (buf[0] != 0xFF || buf[1] != 0xD8)
  51.                         {
  52.                                 printf("%s: unrecognized type\n",argv[i]);
  53.                                 fclose(fi);
  54.                                 continue;
  55.                         }
  56.                         // JPEG
  57.                         printf("Processing %s ...",argv[i]);
  58.                         fseek(fi,0,SEEK_END);
  59.                         unsigned insize = ftell(fi);
  60.                         void* output = malloc(insize);
  61.                         unsigned char* ptr = (unsigned char*)output;
  62.                         *ptr++ = 0xFF;
  63.                         *ptr++ = 0xD8;
  64.                         // Now load JPEG file, skipping all APPx markers
  65.                         fseek(fi,2,SEEK_SET);
  66.                         bool bOk = false;
  67.                         for (;;)
  68.                         {
  69.                                 if (fread(buf,1,4,fi) != 4 || buf[0] != 0xFF)
  70.                                 {
  71.                                         printf("%s: invalid JPEG file\n",argv[i]);
  72.                                         bOk = false;
  73.                                         break;
  74.                                 }
  75.                                 // ignore APPx markers
  76.                                 if (buf[1] >= 0xE0 && buf[1] <= 0xEF)
  77.                                 {
  78.                                         fseek(fi,buf[2]*256 + buf[3] - 2,SEEK_CUR);
  79.                                         continue;
  80.                                 }
  81.                                 unsigned len = buf[2]*256 + buf[3] + 2;
  82.                                 fseek(fi,-4,SEEK_CUR);
  83.                                 fread(ptr,1,len,fi);
  84.                                 if (buf[1]>=0xC0 && buf[1]<=0xCF && buf[1]!=0xC4 && buf[1]!=0xC8 && buf[1]!=0xCC)
  85.                                 {
  86.                                         // found SOFn marker
  87.                                         hea[i-2].sizeX = (unsigned char)ptr[4+3]*256 + (unsigned char)ptr[4+4];
  88.                                         hea[i-2].sizeY = (unsigned char)ptr[4+1]*256 + (unsigned char)ptr[4+2];
  89.                                         bOk = true;
  90.                                 }
  91.                                 ptr += len;
  92.                                 if (buf[1] == 0xDA)
  93.                                 {
  94.                                         // SOS marker
  95.                                         len = insize - ftell(fi);
  96.                                         fread(ptr,1,len,fi);
  97.                                         ptr += len;
  98.                                         break;
  99.                                 }
  100.                         }
  101.                         if (!bOk) {printf(" invalid\n");free(ptr);continue;}
  102.                         hea[i-2].compressedSize = ptr - (unsigned char*)output;
  103.                         hea[i-2].uncompressedSize = hea[i-2].compressedSize - 1;
  104.                         hea[i-2].physicalOffset = (i==2) ? 0 :
  105.                                 hea[i-3].physicalOffset+hea[i-3].compressedSize;
  106.                         ptrs[i-2] = output;
  107.                         ++n;
  108.                         printf(" OK\n");
  109.                         continue;
  110.                 }
  111.                 if (buf[0x1C] != 24)
  112.                 {
  113.                         printf("Input file %s is not 24-bit BMP\n",argv[i]);
  114.                         fclose(fi);
  115.                         continue;
  116.                 }
  117.                 int width = *(int*)(buf+0x12);
  118.                 int linesize = (width*3+3)&~3;
  119.                 int height = *(int*)(buf+0x16);
  120.                 void* input = malloc(width*height*3);
  121.                 void* packed = malloc(9*width*height*3/8 + 0x80);
  122.                 for (int p=0;p<height;p++)
  123.                 {
  124.                         fseek(fi,(height-p-1)*linesize+0x36,SEEK_SET);
  125.                         fread((char*)input+p*width*3, 1, width*3, fi);
  126.                 }
  127.                 fclose(fi);
  128.                 hea[i-2].sizeX = (short)width;
  129.                 hea[i-2].sizeY = (short)height;
  130.                 unsigned uncompressedSize = width*height*3;
  131.                 hea[i-2].uncompressedSize = uncompressedSize;
  132.                 hea[i-2].physicalOffset = (i==2) ? 0 :
  133.                         hea[i-3].physicalOffset+hea[i-3].compressedSize;
  134.                 printf("Compressing %s ...",argv[i]);
  135.                 unsigned compressedSize = lzma_compress(input,packed,
  136.                         uncompressedSize,workmem);
  137.                 if (compressedSize >= uncompressedSize)
  138.                 {
  139.                         compressedSize = uncompressedSize;
  140.                         free(packed);
  141.                         ptrs[i-2] = input;
  142.                 }
  143.                 else
  144.                 {
  145.                         ptrs[i-2] = packed;
  146.                         free(input);
  147.                 }
  148.                 printf(" %d -> %d\n",uncompressedSize, compressedSize);
  149.                 hea[i-2].compressedSize = compressedSize;
  150.                 ++n;
  151.         }
  152.         for (i=0;i<n;i++)
  153.                 hea[i].physicalOffset += 4+n*sizeof(SCompBmpHeader);
  154.         fwrite(&n,4,1,fo);
  155.         fwrite(hea,sizeof(SCompBmpHeader),n,fo);
  156.         for (i=0;i<n;i++)
  157.         {
  158.                 fwrite(ptrs[i],1,hea[i].compressedSize,fo);
  159.                 free(ptrs[i]);
  160.         }
  161.         fclose(fo);
  162.         free(hea);
  163.         free(workmem);
  164.         free(ptrs);
  165.         return 0;
  166. }
  167.