Team Ai
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes847downloads
FileBMP.txt345 linesDownload Raw Back to Utils
1 2#help_index "Graphics/Windows BMP Files"3 4#define BMP_COLORS_NUM  165 6class CFileBMP7{8  U16 type;9  U32 file_size;10  U32 reserved;11  U32 data_offset;12 13  U32 header_size;14  U32 width;15  U32 height;16  U16 planes;17  U16 bit_cnt;18  U32 compression;19  U32 image_size;20  U32 x_pixs_per_meter;21  U32 y_pixs_per_meter;22  U32 colors_used;23  U32 important_colors;24 25  U0 end;26 27  CBGR24 palette[BMP_COLORS_NUM];28};29 30public CFileBMP *BMP4To(CDC *dc)31{//To Windows 4-bit BMP.32  U8 *src,*ptr;33  CBGR48 palette[COLORS_NUM];34  I64 i,x,y,w=dc->width>>1,35        size=sizeof(CFileBMP)+dc->width*dc->height>>1;36  CFileBMP *bmp =CAlloc(size);37  bmp->type     ='BM';38  bmp->planes   =1;39  bmp->file_size        =size;40  bmp->data_offset=sizeof(CFileBMP);41  bmp->header_size=offset(CFileBMP.end)-offset(CFileBMP.header_size);42  bmp->width    =dc->width;43  bmp->height   =dc->height;44  bmp->bit_cnt  =4;45  bmp->image_size       =dc->width*dc->height>>1;46  GrPaletteGet(palette);47#assert COLORS_NUM==BMP_COLORS_NUM48  for (i=0;i<BMP_COLORS_NUM;i++) {49    bmp->palette[i].b=palette[i].b>>8;50    bmp->palette[i].g=palette[i].g>>8;51    bmp->palette[i].r=palette[i].r>>8;52    bmp->palette[i].pad=0;53  }54  ptr=bmp(U8 *)+bmp->data_offset;55  for (y=dc->height-1;y>=0;y--) {56    src=y*dc->width_internal+dc->body;57    for (x=0;x<w;x++) {58      *ptr|=(*src++&15)<<4;59      *ptr|=*src++&15;60      ptr++;61    }62  }63  return bmp;64}65 66public CFileBMP *BMPRLE4To(CDC *dc)67{//To Windows RLE4 bit BMP.68  U8 *src,*ptr,*start;69  I64 i,x,y,w=dc->width,cnt,pattern;70  CBGR48 palette[COLORS_NUM];71  CFileBMP *bmp =CAlloc(sizeof(CFileBMP)+2*(dc->width+1)*dc->height);72  bmp->type     ='BM';73  bmp->planes   =1;74  bmp->data_offset=sizeof(CFileBMP);75  bmp->header_size=offset(CFileBMP.end)-offset(CFileBMP.header_size);76  bmp->width    =dc->width;77  bmp->height   =dc->height;78  bmp->bit_cnt  =4;79  bmp->compression=2; //RLE480  GrPaletteGet(palette);81#assert COLORS_NUM==BMP_COLORS_NUM82  for (i=0;i<BMP_COLORS_NUM;i++) {83    bmp->palette[i].b=palette[i].b>>8;84    bmp->palette[i].g=palette[i].g>>8;85    bmp->palette[i].r=palette[i].r>>8;86    bmp->palette[i].pad=0;87  }88  start=ptr=bmp(U8 *)+bmp->data_offset;89  for (y=dc->height-1;y>=0;y--) {90    src=y*dc->width_internal+dc->body;91    x=0;92    while (x<w) {93      pattern=(src[0]&15)<<4+src[1]&15;94      if (x+1<w && src[0]&15==src[1]&15) {95        src+=2;96        cnt=2;97        x+=2;98        while (x<w && cnt<U8_MAX) {99          if (*src&15==pattern&15) {100            src++;101            cnt++;102            x++;103          } else104            break;105        }106      } else {107        src+=2;108        if (x+1<w)109          cnt=2;110        else111          cnt=1;112        x+=2;113      }114      *ptr++=cnt;115      *ptr++=pattern;116    }117    *ptr(U16 *)++=0;118  }119  bmp->image_size=ptr-start;120  bmp->file_size=sizeof(CFileBMP)+bmp->image_size;121  return bmp;122}123 124public CFileBMP *BMP24To(CDC *dc)125{//To Windows 24-bit BMP.126  U8 *src;127  I64 i,x,y,size=offset(CFileBMP.end)+dc->width*dc->height*sizeof(CBGR24);128  CBGR24 *bgr;129  CFileBMP *bmp =CAlloc(size);130  bmp->type     ='BM';131  bmp->planes   =1;132  bmp->file_size        =size;133  bmp->data_offset=offset(CFileBMP.end);134  bmp->header_size=offset(CFileBMP.end)-offset(CFileBMP.header_size);135  bmp->width    =dc->width;136  bmp->height   =dc->height;137  bmp->bit_cnt  =32;138  bmp->image_size       =dc->width*dc->height<<2;139 140  bgr=bmp(U8 *)+bmp->data_offset;141  for (y=dc->height-1;y>=0;y--) {142    src=y*dc->width_internal+dc->body;143    for (x=0;x<dc->width;x++) {144      i=*src++;145      if (i&BLUE)  bgr->b=0x7F;146      if (i&GREEN) bgr->g=0x7F;147      if (i&RED)   bgr->r=0x7F;148      if (i&8) {149        if (bgr->b) bgr->b=0xFF;150        if (bgr->g) bgr->g=0xFF;151        if (bgr->r) bgr->r=0xFF;152      }153      bgr(U8 *)+=4;154    }155  }156  return bmp;157}158 159public I64 BMPWrite(U8 *filename,CDC *dc,I64 bits=4)160{//Window's BMP Files.161  I64 size;162  CFileBMP *bmp;163  if (bits==4) {164    if (IsDotZ(filename)) //.Z compression is better than RLE165      bmp=BMP4To(dc);166    else {167      bmp=BMPRLE4To(dc);168      if (bmp->file_size>sizeof(CFileBMP)+dc->width*dc->height>>1) {169        Free(bmp);170        bmp=BMP4To(dc);171      }172    }173  } else if (bits==24)174    bmp=BMP24To(dc);175  else {176    "Format Not Supported.\n";177    return 0;178  }179  size=bmp->file_size;180  FileWrite(filename,bmp,bmp->file_size);181  Free(bmp);182  return size;183}184 185U8 *BMPPaletteNew(CFileBMP *bmp)186{187  I64 i,j,best,score,best_score;188  CBGR48 palette[COLORS_NUM];189  U8 *res=CAlloc(BMP_COLORS_NUM*sizeof(U8));190  GrPaletteGet(palette);191#assert COLORS_NUM==BMP_COLORS_NUM192  for (i=0;i<BMP_COLORS_NUM;i++) {193    best=i;194    best_score=I64_MAX;195    for (j=0;j<BMP_COLORS_NUM;j++) {196      score=SqrI64(bmp->palette[i].r-palette[j].r>>8)+197            SqrI64(bmp->palette[i].g-palette[j].g>>8)+198            SqrI64(bmp->palette[i].b-palette[j].b>>8);199      if (score<best_score) {200        best=j;201        best_score=score;202      }203    }204    res[i]=best;205  }206  return res;207}208 209U8 ms_paint_palette[BMP_COLORS_NUM]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15};210 211I64 BMP24Color(CBGR24 *ptr,Bool dither_probability)212{213  I64 res,k;214  if (dither_probability) {215    k=RandU32;216    if (SqrI64(ptr->r)+SqrI64(ptr->g)+SqrI64(ptr->b)>=3*SqrI64(k.u8[0]))217      res=8;218    else219      res=0;220    if (ptr->r>=k.u8[1]) res|=RED;221    if (ptr->g>=k.u8[2]) res|=GREEN;222    if (ptr->b>=k.u8[3]) res|=BLUE;223  } else {224    if (SqrI64(ptr->r)+SqrI64(ptr->g)+SqrI64(ptr->b)>=SqrI64(0x80)) {225      res=8;226      if (ptr->r>=0x80) res|=RED;227      if (ptr->g>=0x80) res|=GREEN;228      if (ptr->b>=0x80) res|=BLUE;229    } else {230      res=0;231      if (ptr->r>=0x40) res|=RED;232      if (ptr->g>=0x40) res|=GREEN;233      if (ptr->b>=0x40) res|=BLUE;234    }235  }236  return res;237}238 239public CDC *BMPRead(U8 *filename,Bool dither_probability=FALSE,240        Bool use_ms_paint_palette=FALSE)241{//Window's BMP Files.242  I64 i,j,cnt;243  U8 *palette_map,*ptr;244  Bool rle;245  CFileBMP *bmp;246  CDC *res=NULL;247  if (ptr=FileRead(filename)) {248    bmp=ptr;249    if (0<bmp->width<I32_MAX && 0<bmp->height<I32_MAX) {250      res=DCNew(bmp->width,bmp->height);251      ptr+=bmp->data_offset;252      if (bmp->compression==2)253        rle=TRUE;254      else255        rle=FALSE;256      if (use_ms_paint_palette)257        palette_map=ms_paint_palette;258      else259        palette_map=BMPPaletteNew(bmp);260      if (bmp->bit_cnt==4) {261        for (i=bmp->height-1;i>=0;i--)262          if (rle) {//We don't support full RLE4, just our own subset263            j=0;264            while (cnt=*ptr++) {265              if (cnt==1) {266                res->color=palette_map[*ptr++&15];267                GrPlot(res,j++,i);268              } else {269                if (cnt==2 && *ptr>>4!=*ptr&15) {270                  res->color=palette_map[*ptr&15];271                  GrPlot(res,j+1,i);272                  res->color=palette_map[*ptr>>4];273                  GrPlot(res,j,i);274                  ptr++;275                  j+=2;276                } else {277                  res->color=palette_map[*ptr++&15];278                  while (cnt--)279                    GrPlot(res,j++,i);280                }281              }282            }283            ptr++;284          } else285            for (j=0;j<(bmp->width+7)&~7;) {286              res->color=palette_map[*ptr&15];287              GrPlot(res,j+1,i);288              res->color=palette_map[*ptr>>4];289              GrPlot(res,j,i);290              ptr++;291              j+=2;292            }293        if (!use_ms_paint_palette)294          Free(palette_map);295      } else if (bmp->bit_cnt==24) {296        for (i=bmp->height-1;i>=0;i--) {297          for (j=0;j<bmp->width;j++,ptr+=3) {298            res->color=BMP24Color(ptr,dither_probability);299            GrPlot(res,j,i);300          }301          ptr+=bmp->width&3;302        }303        if (!use_ms_paint_palette)304          Free(palette_map);305      } else if (bmp->bit_cnt>=32) {306        for (i=bmp->height-1;i>=0;i--)307          for (j=0;j<bmp->width;j++,ptr+=4) {308            res->color=BMP24Color(ptr,dither_probability);309            GrPlot(res,j,i);310          }311        if (!use_ms_paint_palette)312          Free(palette_map);313      } else {314        "Format Not Supported.\n";315        DCDel(res);316        res=NULL;317      }318    } else319      "Invalid BMP File\n";320    Free(bmp);321  }322  return res;323}324 325#help_index "Graphics/Sprite;Graphics/Windows BMP Files;"\326        "DolDoc/Output;StdOut/DolDoc"327public U0 DocBMP(CDoc *doc=NULL,U8 *filename,Bool dither_probability=FALSE,328        Bool use_ms_paint_palette=FALSE)329{//Put a BMP file into a document as a sprite.330  CDC *dc=BMPRead(filename,dither_probability,use_ms_paint_palette);331  U8 *elems=DC2Sprite(dc);332  DocSprite(doc,elems);333  Free(elems);334  DCDel(dc);335}336 337#help_index "Graphics/Windows BMP Files;Graphics/Scrn"338public I64 BMPScrnCapture(U8 *filename,I64 bits=4,Bool include_zoom=TRUE)339{//Capture scrn as BMP file.340  CDC *dc=DCScrnCapture(include_zoom);341  I64 size=BMPWrite(filename,dc,bits);342  DCDel(dc);343  return size;344}345