mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2025-01-17 13:15:35 +00:00
9bc219ee14
About Shared Library (shared) and Module Library (module) type of cmake target INSTALL command has different behaviour for ARCHIVE LIBRARY RUNTIME depending on the platform
637 lines
No EOL
11 KiB
C++
637 lines
No EOL
11 KiB
C++
#include <string.h>
|
|
#include "pic_private.h"
|
|
#include "pic.h"
|
|
|
|
static unsigned long NbPics=0;
|
|
static PIC_PICTURE *HeadPic=NULL;
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
static PIC_PICTURE *GetPic(unsigned long id)
|
|
{
|
|
PIC_PICTURE *pic;
|
|
|
|
for(pic=HeadPic ; pic ; pic=pic->Next)
|
|
{
|
|
if (pic->ID==id)
|
|
{
|
|
return(pic);
|
|
}
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
unsigned long PIC_Load(char* FileName, unsigned char Quantize)
|
|
{
|
|
char ext[4];
|
|
unsigned long type;
|
|
unsigned long i,taken,id;
|
|
PIC_PICTURE *pic;
|
|
char *pDatas;
|
|
char *pPal;
|
|
unsigned long w,h,Depth;
|
|
unsigned long ret;
|
|
|
|
// --- Init
|
|
ret=0;
|
|
type=0;
|
|
id=0;
|
|
taken=0;
|
|
w=0;
|
|
h=0;
|
|
Depth=0;
|
|
pic=NULL;
|
|
pDatas=NULL;
|
|
pPal=NULL;
|
|
// --- Get 1st available ID
|
|
for(i=1 ; i<=NbPics+1 ; i++)
|
|
{
|
|
taken=0;
|
|
for(pic=HeadPic ; pic ; pic=pic->Next)
|
|
{
|
|
if (pic->ID==i)
|
|
{
|
|
taken=1;
|
|
break;
|
|
}
|
|
}
|
|
if (!taken)
|
|
{
|
|
id=i;
|
|
break;
|
|
}
|
|
}
|
|
if (!id)
|
|
{
|
|
Pic_SetError("Load, unable to create ID");
|
|
return(0);
|
|
}
|
|
// --- Load pic
|
|
if (FileName)
|
|
{
|
|
ext[0]=FileName[strlen(FileName)-3];
|
|
ext[1]=FileName[strlen(FileName)-2];
|
|
ext[2]=FileName[strlen(FileName)-1];
|
|
ext[3]=0;
|
|
strupr(ext);
|
|
if ( !strcmp(ext,"JPG") )
|
|
{
|
|
type=1;
|
|
}
|
|
else if ( !strcmp(ext,"TGA") )
|
|
{
|
|
type=2;
|
|
}
|
|
else if ( !strcmp(ext,"BMP") )
|
|
{
|
|
type=3;
|
|
}
|
|
|
|
switch(type)
|
|
{
|
|
// - JPG
|
|
case 1:
|
|
if (!Quantize)
|
|
{
|
|
Depth=24;
|
|
ret=Pic_JPG_Read(FileName,NULL,&pDatas,&w,&h);
|
|
}
|
|
else
|
|
{
|
|
Depth=8;
|
|
ret=Pic_JPG_Read(FileName,&pPal,&pDatas,&w,&h);
|
|
}
|
|
if (!ret)
|
|
{
|
|
Pic_SetError("Load, unable to load JPG file %s",FileName);
|
|
return(0);
|
|
}
|
|
break;
|
|
// - TGA
|
|
case 2:
|
|
ret=Pic_TGA_Read(FileName,&pPal,&pDatas,&w,&h,&Depth);
|
|
if (!ret)
|
|
{
|
|
Pic_SetError("Load, unable to load TGA file %s",FileName);
|
|
return(0);
|
|
}
|
|
break;
|
|
// - BMP
|
|
case 3:
|
|
ret=Pic_BMP_Read(FileName,&pPal,&pDatas,&w,&h,&Depth);
|
|
if (!ret)
|
|
{
|
|
Pic_SetError("Load, unable to load BMP file %s",FileName);
|
|
return(0);
|
|
}
|
|
break;
|
|
// - Unknown
|
|
default:
|
|
Pic_SetError("Load, unknown extension for %s",FileName);
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
// --- Create and place new pic struct
|
|
pic=(PIC_PICTURE *)Pic_calloc(1,sizeof(PIC_PICTURE));
|
|
if (!pic)
|
|
{
|
|
Pic_SetError("Load, not enough memory for internal structure");
|
|
return(0);
|
|
}
|
|
pic->Next=HeadPic;
|
|
HeadPic=pic;
|
|
NbPics++;
|
|
pic->ID=id;
|
|
pic->pDatas=pDatas;
|
|
pic->pPal=pPal;
|
|
pic->Width=w;
|
|
pic->Height=h;
|
|
pic->Depth=Depth;
|
|
return(id);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
unsigned long PIC_Create(char* pPal, char* pDatas, unsigned long w, unsigned long h, unsigned long d)
|
|
{
|
|
unsigned long i,taken,id;
|
|
PIC_PICTURE *pic;
|
|
|
|
// --- Init
|
|
id=0;
|
|
taken=0;
|
|
pic=NULL;
|
|
// --- Get 1st available ID
|
|
for(i=1 ; i<=NbPics+1 ; i++)
|
|
{
|
|
taken=0;
|
|
for(pic=HeadPic ; pic ; pic=pic->Next)
|
|
{
|
|
if (pic->ID==i)
|
|
{
|
|
taken=1;
|
|
break;
|
|
}
|
|
}
|
|
if (!taken)
|
|
{
|
|
id=i;
|
|
break;
|
|
}
|
|
}
|
|
if (!id)
|
|
{
|
|
Pic_SetError("Create, unable to create ID");
|
|
return(0);
|
|
}
|
|
// --- Create pic
|
|
if (!pDatas)
|
|
{
|
|
pDatas=(char *)Pic_calloc(1,w*h*d/8);
|
|
if (!pDatas)
|
|
{
|
|
Pic_SetError("Create, not enough memory for datas");
|
|
return(0);
|
|
}
|
|
}
|
|
if (d==8)
|
|
{
|
|
if (!pPal)
|
|
{
|
|
pPal=(char *)Pic_calloc(1,256*3);
|
|
if (!pPal)
|
|
{
|
|
Pic_SetError("Create, not enough memory for palette");
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pPal=NULL;
|
|
}
|
|
// --- Create and place new pic struct
|
|
pic=(PIC_PICTURE *)Pic_calloc(1,sizeof(PIC_PICTURE));
|
|
if (!pic)
|
|
{
|
|
Pic_SetError("Create, not enough memory for internal structure");
|
|
return(0);
|
|
}
|
|
pic->Next=HeadPic;
|
|
HeadPic=pic;
|
|
NbPics++;
|
|
pic->ID=id;
|
|
pic->pDatas=pDatas;
|
|
pic->pPal=pPal;
|
|
pic->Width=w;
|
|
pic->Height=h;
|
|
pic->Depth=d;
|
|
return(id);
|
|
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
unsigned long PIC_GetInfos( unsigned long id,
|
|
char **ppPal, char **ppDatas,
|
|
unsigned long *pW, unsigned long *pH, unsigned long *pD)
|
|
{
|
|
PIC_PICTURE *pic;
|
|
|
|
pic=GetPic(id);
|
|
if (!pic)
|
|
{
|
|
Pic_SetError("GetInfos, picture internal structure not found");
|
|
return(0);
|
|
}
|
|
if (ppPal)
|
|
{
|
|
*ppPal=pic->pPal;
|
|
}
|
|
if (ppDatas)
|
|
{
|
|
*ppDatas=pic->pDatas;
|
|
}
|
|
if (pW)
|
|
{
|
|
*pW=pic->Width;
|
|
}
|
|
if (pH)
|
|
{
|
|
*pH=pic->Height;
|
|
}
|
|
if (pD)
|
|
{
|
|
*pD=pic->Depth;
|
|
}
|
|
return(id);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
static char* Conv8To24(unsigned long id)
|
|
{
|
|
PIC_PICTURE *pic;
|
|
char *buf;
|
|
unsigned long i;
|
|
|
|
pic=GetPic(id);
|
|
if (!pic)
|
|
{
|
|
Pic_SetError("Conv8To24, picture internal structure not found");
|
|
return(NULL);
|
|
}
|
|
buf=(char *)Pic_malloc(pic->Width*pic->Height*3);
|
|
if (!buf)
|
|
{
|
|
Pic_SetError("Conv8To24, not enough memory for temporary buffer");
|
|
return(NULL);
|
|
}
|
|
for(i=0 ; i<pic->Width*pic->Height ; i++)
|
|
{
|
|
buf[i*3+0]=pic->pPal[pic->pDatas[i]*3+0];
|
|
buf[i*3+1]=pic->pPal[pic->pDatas[i]*3+1];
|
|
buf[i*3+2]=pic->pPal[pic->pDatas[i]*3+2];
|
|
}
|
|
return(buf);
|
|
}
|
|
|
|
// ----------------------------------------
|
|
static char* Conv8To16(unsigned long id)
|
|
{
|
|
PIC_PICTURE *pic;
|
|
unsigned short *buf;
|
|
unsigned long i;
|
|
unsigned short r,g,b,pix16;
|
|
|
|
pic=GetPic(id);
|
|
if (!pic)
|
|
{
|
|
Pic_SetError("Conv8To24, picture internal structure not found");
|
|
return(NULL);
|
|
}
|
|
buf=(unsigned short*)Pic_malloc(pic->Width*pic->Height*2);
|
|
if (!buf)
|
|
{
|
|
Pic_SetError("Conv8To24, not enough memory for temporary buffer");
|
|
return(NULL);
|
|
}
|
|
for(i=0 ; i<pic->Width*pic->Height ; i++)
|
|
{
|
|
b=pic->pPal[pic->pDatas[i]*3+0];
|
|
g=pic->pPal[pic->pDatas[i]*3+1];
|
|
r=pic->pPal[pic->pDatas[i]*3+2];
|
|
r>>=3;
|
|
g>>=3; g&=0x3E;
|
|
b>>=3;
|
|
pix16=(r<<10)+(g<<5)+b;
|
|
buf[i]=pix16;
|
|
}
|
|
return (char*)buf;
|
|
}
|
|
|
|
// ----------------------------------------
|
|
|
|
static char* Conv16To24(unsigned long id)
|
|
{
|
|
PIC_PICTURE *pic;
|
|
unsigned short *pDatas;
|
|
unsigned char *buf;
|
|
unsigned long i;
|
|
unsigned short r,g,b;
|
|
|
|
pic=GetPic(id);
|
|
if (!pic)
|
|
{
|
|
Pic_SetError("Conv16To24, picture internal structure not found");
|
|
return(NULL);
|
|
}
|
|
buf=(unsigned char *)Pic_malloc(pic->Width*pic->Height*3);
|
|
if (!buf)
|
|
{
|
|
Pic_SetError("Conv16To24, not enough memory for temporary buffer");
|
|
return(NULL);
|
|
}
|
|
pDatas=(unsigned short*)pic->pDatas;
|
|
for(i=0 ; i<pic->Width*pic->Height ; i++)
|
|
{
|
|
r=(pDatas[i] & 0x7C00)>>(10-3);
|
|
g=(pDatas[i] & 0x03E0)>>(5-3);
|
|
b=(pDatas[i] & 0x001F)<<3;
|
|
buf[i*3+0]=(unsigned char)r;
|
|
buf[i*3+1]=(unsigned char)g;
|
|
buf[i*3+2]=(unsigned char)b;
|
|
}
|
|
return (char*)buf;
|
|
}
|
|
|
|
// ----------------------------------------
|
|
|
|
static char* Conv24To16(unsigned long id)
|
|
{
|
|
PIC_PICTURE *pic;
|
|
unsigned short *buf;
|
|
unsigned long i;
|
|
unsigned short r,g,b;
|
|
unsigned short pix16;
|
|
|
|
pic=GetPic(id);
|
|
if (!pic)
|
|
{
|
|
Pic_SetError("Conv24To16, picture internal structure not found");
|
|
return(NULL);
|
|
}
|
|
buf=(unsigned short*)Pic_malloc(pic->Width*pic->Height*2);
|
|
if (!buf)
|
|
{
|
|
Pic_SetError("Conv24To16, not enough memory for temporary buffer");
|
|
return(NULL);
|
|
}
|
|
for(i=0 ; i<pic->Width*pic->Height ; i++)
|
|
{
|
|
r=pic->pDatas[i*3+0];
|
|
g=pic->pDatas[i*3+1];
|
|
b=pic->pDatas[i*3+2];
|
|
// r : 5 bits forts (0x7C)
|
|
// g : 5 bits (6e zapped) (0x3E)
|
|
// b : 5 bits faibles (0x1F)
|
|
r>>=3;
|
|
g>>=3; g&=0x3E;
|
|
b>>=3;
|
|
pix16=(r<<10)+(g<<5)+b;
|
|
buf[i]=pix16;
|
|
}
|
|
return (char*)buf;
|
|
}
|
|
|
|
// ----------------------------------------
|
|
|
|
static char* ConvPic(PIC_PICTURE *pic, unsigned long type, char* pErr)
|
|
{
|
|
char *buf;
|
|
unsigned long src,dst;
|
|
|
|
*pErr=0;
|
|
buf=NULL;
|
|
src=pic->Depth;
|
|
if (type==PIC_TYPE_TGA8 || type==PIC_TYPE_BMP8)
|
|
{
|
|
dst=8;
|
|
}
|
|
if (type==PIC_TYPE_TGA16)
|
|
{
|
|
dst=16;
|
|
}
|
|
if (type==PIC_TYPE_JPG || type==PIC_TYPE_TGA24 || type==PIC_TYPE_BMP24)
|
|
{
|
|
dst=24;
|
|
}
|
|
// ---
|
|
if (src==dst)
|
|
{
|
|
return(NULL);
|
|
}
|
|
// ---
|
|
if (src==8 && dst==24)
|
|
{
|
|
buf=Conv8To24(pic->ID);
|
|
if (!buf)
|
|
{
|
|
*pErr=1;
|
|
}
|
|
return(buf);
|
|
}
|
|
if (src==8 && dst==16)
|
|
{
|
|
buf=Conv8To16(pic->ID);
|
|
if (!buf)
|
|
{
|
|
*pErr=1;
|
|
}
|
|
return(buf);
|
|
}
|
|
// ---
|
|
if (src==16 && dst==24)
|
|
{
|
|
buf=Conv16To24(pic->ID);
|
|
if (!buf)
|
|
{
|
|
*pErr=1;
|
|
}
|
|
return(buf);
|
|
}
|
|
// ---
|
|
if (src==24 && dst==16)
|
|
{
|
|
buf=Conv24To16(pic->ID);
|
|
if (!buf)
|
|
{
|
|
*pErr=1;
|
|
}
|
|
return buf;
|
|
}
|
|
// ---
|
|
if (src==24 && dst==8)
|
|
{
|
|
Pic_SetError("ConvPic, downsampling 24 to 8 bits unsupported");
|
|
*pErr=1;
|
|
return(NULL);
|
|
}
|
|
Pic_SetError("ConvPic, conversion %d to %d unsupported",src,dst);
|
|
*pErr=1;
|
|
return(NULL);
|
|
}
|
|
|
|
// ----------------------------------------
|
|
|
|
unsigned long PIC_Save(unsigned long id, char* FileName, unsigned long type, unsigned long qual)
|
|
{
|
|
PIC_PICTURE *pic;
|
|
char err;
|
|
char *buf;
|
|
char *freeit;
|
|
unsigned long depth;
|
|
|
|
freeit=NULL;
|
|
pic=GetPic(id);
|
|
if (!pic)
|
|
{
|
|
Pic_SetError("Save %s, picture internal structure not found",FileName);
|
|
return(0);
|
|
}
|
|
freeit = ConvPic(pic,type,&err);
|
|
if (err)
|
|
{
|
|
Pic_SetError("Save %s, error while converting picture",FileName);
|
|
return(0);
|
|
}
|
|
if (!freeit)
|
|
{
|
|
buf=pic->pDatas;
|
|
}
|
|
else
|
|
{
|
|
buf=freeit;
|
|
}
|
|
err=0;
|
|
switch(type)
|
|
{
|
|
// ---
|
|
case PIC_TYPE_JPG:
|
|
if ( !Pic_JPG_Write(FileName,qual,buf,pic->Width,pic->Height) )
|
|
{
|
|
if (freeit)
|
|
{
|
|
Pic_free(buf);
|
|
}
|
|
Pic_SetError("Save %s, error while saving JPG file",FileName);
|
|
err=1;
|
|
}
|
|
break;
|
|
// ---
|
|
case PIC_TYPE_TGA8:
|
|
case PIC_TYPE_TGA16:
|
|
case PIC_TYPE_TGA24:
|
|
if (type==PIC_TYPE_TGA8)
|
|
{
|
|
depth=8;
|
|
}
|
|
if (type==PIC_TYPE_TGA16)
|
|
{
|
|
depth=16;
|
|
}
|
|
if (type==PIC_TYPE_TGA24)
|
|
{
|
|
depth=24;
|
|
}
|
|
if ( !Pic_TGA_Write(FileName,pic->pPal,buf,pic->Width,pic->Height,depth) )
|
|
{
|
|
if (freeit)
|
|
{
|
|
Pic_free(freeit);
|
|
}
|
|
Pic_SetError("Save %s, error while saving TGA file",FileName);
|
|
err=1;
|
|
}
|
|
break;
|
|
// ---
|
|
case PIC_TYPE_BMP8:
|
|
case PIC_TYPE_BMP24:
|
|
if (type==PIC_TYPE_BMP8)
|
|
{
|
|
depth=8;
|
|
}
|
|
if (type==PIC_TYPE_BMP24)
|
|
{
|
|
depth=24;
|
|
}
|
|
if ( !Pic_BMP_Write(FileName,pic->pPal,buf,pic->Width,pic->Height,depth) )
|
|
{
|
|
if (freeit)
|
|
{
|
|
Pic_free(freeit);
|
|
}
|
|
Pic_SetError("Save %s, error while saving BMP file",FileName);
|
|
err=1;
|
|
}
|
|
break;
|
|
// ---
|
|
default:
|
|
Pic_SetError("Save %s, unknow save format/type",FileName);
|
|
err=1;
|
|
break;
|
|
}
|
|
if (freeit)
|
|
{
|
|
Pic_free(freeit);
|
|
}
|
|
return(err-1);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
unsigned long PIC_Destroy(unsigned long id)
|
|
{
|
|
PIC_PICTURE *prevpic,*pic;
|
|
unsigned long found;
|
|
|
|
prevpic=NULL;
|
|
found=0;
|
|
for(pic=HeadPic ; pic ; pic=pic->Next)
|
|
{
|
|
if (pic->ID==id)
|
|
{
|
|
found=1;
|
|
break;
|
|
}
|
|
prevpic=pic;
|
|
}
|
|
if (!found)
|
|
{
|
|
Pic_SetError("Destroy, picture internal structure not found");
|
|
return(0);
|
|
}
|
|
if (prevpic)
|
|
{
|
|
prevpic->Next=pic->Next;
|
|
}
|
|
if (pic->pDatas)
|
|
{
|
|
Pic_free(pic->pDatas);
|
|
}
|
|
if (pic->pPal)
|
|
{
|
|
Pic_free(pic->pPal);
|
|
}
|
|
if (pic==HeadPic)
|
|
{
|
|
HeadPic=pic->Next;
|
|
}
|
|
Pic_free(pic);
|
|
return(1);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|