/*****************/ /*** Layer RGB ***/ /*****************/ #include <DaveLib.h> #include <List2d.h> #include "MkLevelLayer.h" #include "MkLevelLayerRGB.h" /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ CMkLevelLayerRGB::CMkLevelLayerRGB(sExpLayerHdr *LayerHdr) { int *iPtr; u8 *Ptr=(u8*)LayerHdr; Type=LayerHdr->Type; SubType=LayerHdr->SubType; Width=LayerHdr->Width; Height=LayerHdr->Height; RGBMap.SetSize(Width,Height); iPtr=(int*)(Ptr+sizeof(sExpLayerHdr)); ShadeFlag=*iPtr++; sRGBCol *RGB=(sRGBCol*)iPtr; for (int Y=0; Y<Height; Y++) { for (int X=0; X<Width; X++) { sRGBElem ThisElem; ThisElem.RGB=*RGB++; ThisElem.RGB.P=0; ThisElem.TableIdx=0; // ThisElem.RGB.R&=-8; // ThisElem.RGB.G&=-8; // ThisElem.RGB.B&=-8; RGBMap.Set(X,Y,ThisElem); } } } /*****************************************************************************/ /*****************************************************************************/ /*** Pre-Process *************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CMkLevelLayerRGB::PreProcess(CMkLevel *Core) { int X,Y; int ColorCount; int c; // build RGB List for (Y=0; Y<Height; Y++) { for (X=0; X<Width; X++) { sRGBElem &ThisElem=RGBMap.Get(X,Y); sRGBList ThisRGB; ThisRGB.RGB=ThisElem.RGB; ThisRGB.Count=0; int Idx=InRGBList.Add(ThisRGB); ThisElem.TableIdx=Idx; InRGBList[Idx].Count++; } } ColorCount=InRGBList.size(); printf("------ %i Colors ------\n",ColorCount); // Sort RGB List by usage for (c=0; c<ColorCount; c++) { sRGBList &ThisRGB=InRGBList[c]; int s=0; int SortListSize=SortRGBList.size(); for (; s<SortListSize; s++) { if (SortRGBList[s].Count<ThisRGB.Count) break; } SortRGBList.insert(s,ThisRGB); } // Build Remap table for (c=0; c<ColorCount; c++) { int Idx=SortRGBList.Find(InRGBList[c]); RemapTable.push_back(Idx); /* sRGBCol &In=InRGBList[c].RGB; sRGBCol &Out=SortRGBList[RemapTable[c]].RGB; if (In.R!=Out.R || In.G!=Out.G || In.B!=Out.B) { printf("%i %i %i\t%i %i %i\n",In.R,In.G,In.B,Out.R,Out.G,Out.B); } */ } // Remap all above 256 for (c=256;c<ColorCount;c++) { sRGBCol &ThisRGB=InRGBList[RemapTable[c]].RGB; RemapTable[c ]=FindClosestRGB(ThisRGB); } // Build Out Map OutMap.SetSize(Width,Height); for (Y=0; Y<Height; Y++) { for (X=0; X<Width; X++) { sRGBElem &ThisElem=RGBMap.Get(X,Y); u8 Idx=RemapTable[ThisElem.TableIdx]; OutMap.Set(X,Y,Idx); } } // Build Out RGB Table if (ColorCount>256) ColorCount=256; OutRGBTable.SetSize(ColorCount,16); int RGBInc=6; if (ShadeFlag) RGBInc=-6; for (c=0;c<ColorCount;c++) { sRGBCol &ThisRGB=SortRGBList[c].RGB; int R=ThisRGB.R; int G=ThisRGB.G; int B=ThisRGB.B; for (int s=0; s<16; s++) { sRGBCol RGB; RGB.R=R; RGB.G=G; RGB.B=B; OutRGBTable.Set(c,s,RGB); R+=RGBInc; G+=RGBInc; B+=RGBInc; if (R<0) R=0; else if (R>255) R=255; if (G<0) G=0; else if (G>255) G=255; if (B<0) B=0; else if (B>255) B=255; } } } /*****************************************************************************/ int CMkLevelLayerRGB::FindClosestRGB(sRGBCol const &RGB) { int CIdx=-1; int CVal=0; for (int i=0; i<256; i++) { int ThisVal=(SortRGBList[i].RGB.R*SortRGBList[i].RGB.R)+ (SortRGBList[i].RGB.G*SortRGBList[i].RGB.G)+(SortRGBList[i].RGB.B*SortRGBList[i].RGB.B); if (CIdx==-1 || ThisVal<CVal) { CIdx=i; CVal=ThisVal; } } return(CIdx); } /*****************************************************************************/ /*****************************************************************************/ /*** Process *****************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CMkLevelLayerRGB::Process(CMkLevel *Core) { } /*****************************************************************************/ /*****************************************************************************/ /** Write ********************************************************************/ /*****************************************************************************/ /*****************************************************************************/ int CMkLevelLayerRGB::Write(CMkLevel *Core,FILE *File,const char *LayerName) { int ThisPos=ftell(File); sLayerHdr Hdr; sLayerRGBHdr RGBHdr; Hdr.Type=Type; Hdr.SubType=SubType; Hdr.Width=Width; Hdr.Height=Height; fwrite(&Hdr,sizeof(sLayerHdr),1,File); int HdrPos=ftell(File); fwrite(&RGBHdr,sizeof(sLayerRGBHdr),1,File); RGBHdr.RGBMap=WriteRGBMap(File); PadFile(File); RGBHdr.RGBTable=WriteRGBTable(File); PadFile(File); // rewrite header int RetPos=ftell(File); fseek(File,HdrPos,SEEK_SET); fwrite(&RGBHdr,sizeof(sLayerRGBHdr),1,File); fseek(File,RetPos,SEEK_SET); Size=ftell(File)-ThisPos; return(ThisPos); } /*****************************************************************************/ int CMkLevelLayerRGB::WriteRGBMap(FILE *File) { int ThisPos=ftell(File); for (int Y=0; Y<Height; Y++) { for (int X=0; X<Width; X++) { u8 Idx=OutMap.Get(X,Y); fwrite(&Idx,1,sizeof(u8),File); } } printf("--> RGBMap %i %i\n",ThisPos,ftell(File)-ThisPos); return(ThisPos); } /*****************************************************************************/ int CMkLevelLayerRGB::WriteRGBTable(FILE *File) { int ThisPos=ftell(File); int ListSize=OutRGBTable.GetWidth(); for (int c=0; c<ListSize; c++) { for (int s=0; s<16; s++) { sRGBCol &RGB=OutRGBTable.Get(c,s); fwrite(&RGB,1,sizeof(sRGBCol),File); } } printf("--> RGBTable %i %i\n",ThisPos,ftell(File)-ThisPos); return(ThisPos); }