aboutsummaryrefslogtreecommitdiff
path: root/project/src/lib-image2.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--project/src/lib-image2.c260
1 files changed, 211 insertions, 49 deletions
diff --git a/project/src/lib-image2.c b/project/src/lib-image2.c
index ae4f75c..d005ec5 100644
--- a/project/src/lib-image2.c
+++ b/project/src/lib-image2.c
@@ -134,11 +134,14 @@ enumError AssignIMG
switch (fform)
{
+// [[tpl-ex+]]
+ //case FF_CUPICON: never defined by magic
case FF_TPL:
+ case FF_TPLX:
{
- const tpl_header_t * tpl;
- const tpl_pal_header_t * tp;
- const tpl_img_header_t * ti;
+ const tpl_header_t *tpl;
+ const tpl_pal_header_t *tp;
+ const tpl_img_header_t *ti;
if (SetupPointerTPL( data, data_size, img_index,
&tpl, 0, &tp, &ti,
@@ -149,6 +152,14 @@ enumError AssignIMG
height = be16(&ti->height);
n_img = be32(&tpl->n_image);
+// [[tpl-ex+]]
+ if ( fform == FF_TPLX )
+ {
+ tpl_header_ex_t *tplx = (tpl_header_ex_t*)tpl;
+ width = be32(&tplx->ex_width);
+ height = be32(&tplx->ex_height);
+ }
+
if (tp)
{
pform = be32(&tp->pform);
@@ -684,6 +695,13 @@ static enumError CreateGenericCupIconIMG
{
par->force_width = str2ul(text.ptr+1,0,10);
PRINT0(">>>>> width %u\n",par->force_width);
+ continue;
+ }
+
+ if (!memcmp(text.ptr,":test",5))
+ {
+ par->test_mode = true;
+ continue;
}
Image_t cupicon;
@@ -748,6 +766,7 @@ static enumError CreateGenericCupIconIMG
}
img->is_cup_icon = true;
+ img->test_mode = par->test_mode;
return err;
}
@@ -895,6 +914,7 @@ void SetupMipmapOptions ( MipmapOptions_t *mmo )
//memset(mmo,0,sizeof(*mmo));
mmo->valid = true;
+ mmo->is_tpl = false;
if (opt_n_images)
{
@@ -916,13 +936,14 @@ void SetupMipmapOptions ( MipmapOptions_t *mmo )
///////////////////////////////////////////////////////////////////////////////
-void SetupMipmapOptions1 ( MipmapOptions_t *mmo )
+void SetupMipmapOptionsTPL ( MipmapOptions_t *mmo )
{
DASSERT(mmo);
//memset(mmo,0,sizeof(*mmo));
mmo->valid = true;
mmo->force = true;
+ mmo->is_tpl = true;
mmo->n_mipmap = 0;
mmo->n_image = 1;
mmo->min_size = 1;
@@ -1083,10 +1104,14 @@ static enumError PrepareImages
//--- copy & convert images
CopyIMG(&mmi->img,true,src_img,false);
- Transform2InternIMG(&mmi->img);
- enumError err = ExecTransformIMG(&mmi->img);
- if (err)
- return err;
+ const bool is_tpl = mmi->mmo.is_tpl;
+ if (!is_tpl)
+ {
+ Transform2InternIMG(&mmi->img);
+ enumError err = ExecTransformIMG(&mmi->img);
+ if (err)
+ return err;
+ }
//--- calculate image size
@@ -1095,24 +1120,27 @@ static enumError PrepareImages
if ( !geo || geo->is_x )
return ERROR0(ERR_INTERNAL,0);
- uint ni, size = 0;
- uint wd = mmi->img.width;
- uint ht = mmi->img.height;
- uint n_image = mmi->mmo.n_image;
+ uint size = 0;
+ uint wd = mmi->img.width;
+ uint ht = mmi->img.height;
+ uint n_image = mmi->mmo.n_image;
- for ( ni = 0; ni < n_image; ni++ )
+ for ( int ni = 0; ni < n_image; ni++ )
{
size += CalcImageSize( wd, ht, geo->bits_per_pixel,
geo->block_width, geo->block_height, 0,0,0,0 );
if (!ni)
mmi->img.info_size = size;
- wd /= 2;
- ht /= 2;
- DASSERT( opt_min_mipmap_size >= 1 );
- if ( wd < mmi->mmo.min_size || ht < mmi->mmo.min_size )
+ if (!is_tpl)
{
- n_image = ni + 1;
- break;
+ wd /= 2;
+ ht /= 2;
+ DASSERT( opt_min_mipmap_size >= 1 );
+ if ( wd < mmi->mmo.min_size || ht < mmi->mmo.min_size )
+ {
+ n_image = ni + 1;
+ break;
+ }
}
}
@@ -1126,7 +1154,7 @@ static enumError PrepareImages
///////////////////////////////////////////////////////////////////////////////
-static enumError PrepareImages1
+static enumError PrepareImagesTPL
(
mipmap_info_t * mmi, // valid mipmap info
const Image_t * src_img // pointer to source image
@@ -1141,7 +1169,7 @@ static enumError PrepareImages1
DASSERT(src_img);
MipmapOptions_t mmo;
- SetupMipmapOptions1(&mmo);
+ SetupMipmapOptionsTPL(&mmo);
return PrepareImages(mmi,src_img,&mmo);
}
@@ -1150,7 +1178,8 @@ static enumError PrepareImages1
static enumError WriteImageData
(
mipmap_info_t * mmi, // valid mipmap info
- u8 * data // destination buffer
+ u8 * data, // destination buffer
+ u8 ** p_dest // not NULL: store next destination
)
{
DASSERT(mmi);
@@ -1158,6 +1187,8 @@ static enumError WriteImageData
const Image_t *img = &mmi->img;
memcpy(data,img->data,img->info_size);
+ if (p_dest)
+ *p_dest = data + img->info_size;
if (!mmi->n_mipmap)
return ERR_OK;
@@ -1198,6 +1229,8 @@ static enumError WriteImageData
memcpy(dest,temp.data,temp.data_size);
dest += temp.data_size;
}
+ if (p_dest)
+ *p_dest = dest;
ResetIMG(&temp);
ResetIMG(&mmi->img);
@@ -1229,7 +1262,10 @@ enumError SaveIMG
switch(fform)
{
- case FF_TPL: return SaveTPL(img,f,fname,overwrite);
+// [[tpl-ex+]]
+ case FF_CUPICON:
+ case FF_TPL:
+ case FF_TPLX: return SaveTPL(img,fform,f,fname,overwrite);
case FF_BTI: return SaveBTI(img,mmo,f,fname,overwrite);
case FF_TEX: return SaveTEX(img,mmo,f,fname,overwrite,false);
case FF_TEX_CT: return SaveTEX(img,mmo,f,fname,overwrite,true);
@@ -1260,10 +1296,20 @@ void ResetRawTPL ( tpl_raw_t *raw )
//-----------------------------------------------------------------------------
+const tpl_signature_t TPLSignature0 =
+{
+ "LE-CODE\0",
+ 0, 0, 0, 0, 0,
+ "Cup Icon"
+};
+
+//-----------------------------------------------------------------------------
+
enumError CreateRawTPL
(
- tpl_raw_t * raw, // results with alloced data
- Image_t * src_img // pointer to valid source img
+ tpl_raw_t * raw, // results with alloced data
+ Image_t * src_img, // pointer to valid source img
+ file_format_t fform // FF_TPL or FF_TPLX
)
{
DASSERT(src_img);
@@ -1273,8 +1319,59 @@ enumError CreateRawTPL
//--- special handling for cup icons
- if ( src_img->is_cup_icon && !n_transform )
+ bool create_tplx = fform == FF_TPLX;
+ if ( fform == FF_CUPICON || src_img->is_cup_icon && !n_transform ) // no forced transformation
+ {
ConvertIMG(src_img,false,0,IMG_CMPR,PAL_INVALID);
+ create_tplx = true;
+ }
+ else
+ {
+ Transform2InternIMG(src_img);
+ const enumError err = ExecTransformIMG(src_img);
+ if (err)
+ return err;
+ }
+
+ PRINT("is_cup_icon=%d, test_mode=%d, ff=%s\n",
+ src_img->is_cup_icon,src_img->test_mode,GetImageFormatName(src_img->iform,"?"));
+
+ if (create_tplx)
+ FreeMipmapsIMG(src_img);
+
+
+ //--- TPLx calculations
+
+ const ImageGeometry_t *geo = GetImageGeometry(src_img->iform);
+ if (!geo)
+ return ERROR0(ERR_INTERNAL,0);
+
+ int ex_width, ex_height, ex_fill;
+ if (create_tplx)
+ {
+ // add 1 for special line
+ uint max_lines = MAX_IMAGE_HEIGHT / geo->block_height;
+ const uint n_lines = ( src_img->height + 2*geo->block_height - 1 ) / geo->block_height;
+ if ( src_img->test_mode && max_lines >= n_lines )
+ max_lines = (n_lines-1) / geo->block_height * geo->block_height;
+ const uint n_cols = ( n_lines + max_lines - 1 ) / max_lines;
+
+ ex_width = src_img->width * n_cols;
+ ex_height = ( n_lines + n_cols - 1 ) / n_cols * geo->block_height;
+ ex_fill = ( ex_width * ex_height - src_img->width * src_img->height )
+ * geo->bits_per_pixel / 8;
+
+ PRINT("TPLx: %u*%u, cols=%d, lines=%d/%d, geo=%d*%d => %d*%d, fill:%x\n",
+ src_img->width, src_img->height,
+ n_cols, n_lines, max_lines, geo->block_width, geo->block_height,
+ ex_width, ex_height, ex_fill );
+ }
+ else
+ {
+ ex_width = src_img->width < MAX_IMAGE_WIDTH ? src_img->width : MAX_IMAGE_WIDTH;
+ ex_height = src_img->height < MAX_IMAGE_HEIGHT ? src_img->height : MAX_IMAGE_HEIGHT;
+ ex_fill = 0;
+ }
//--- setup images
@@ -1287,7 +1384,8 @@ enumError CreateRawTPL
enumError err = ERR_OK;
const uint align = 0x20;
- const uint tab_off = sizeof(tpl_header_t);
+// [[tpl-ex+]]
+ const uint tab_off = create_tplx ? sizeof(tpl_header_ex_t) : sizeof(tpl_header_t);
uint data_off = tab_off + n_image * sizeof(tpl_imgtab_t);
mipmap_info_t *m = mmi;
@@ -1300,7 +1398,7 @@ enumError CreateRawTPL
for ( i = 0; i < n_image; i++, m++, img = img->mipmap )
{
DASSERT(img);
- err = PrepareImages1(m,img);
+ err = PrepareImagesTPL(m,img);
if (err)
return err;
@@ -1324,10 +1422,13 @@ enumError CreateRawTPL
for ( i = 0, m = mmi; i < n_image; i++, m++ )
{
m->img_data_off = data_off;
- m->img_data_size = m->image_size;
- data_off = ALIGN32( m->img_data_off + m->img_data_size, align );
+ uint data_size = m->image_size;
+ m->img_data_size = data_size;
+ if (!i)
+ data_size += ex_fill;
+ data_off = ALIGN32( m->img_data_off + data_size, align );
- PRINT("%6x %6x %6x | %6x %6x %6x | %6x = %6u\n",
+ PRINT0("%6x %6x %6x | %6x %6x %6x | %6x = %6u\n",
m->pal_head_off, m->pal_data_off, m->pal_data_size,
m->img_head_off, m->img_data_off, m->img_data_size,
data_off, data_off );
@@ -1342,11 +1443,21 @@ enumError CreateRawTPL
const endian_func_t * endian = src_img->endian;
raw->endian = endian;
- tpl_header_t * tpl = (tpl_header_t*)data;
+// [[tpl-ex+]]
+ tpl_header_ex_t *tpl = (tpl_header_ex_t*)data;
endian->wr32(tpl->magic,TPL_MAGIC_NUM);
endian->wr32(&tpl->n_image,n_image);
endian->wr32(&tpl->imgtab_off,tab_off);
+// [[tpl-ex+]]
+ if (create_tplx)
+ {
+ endian->wr32(&tpl->ex_magic,TPL_EX_MAGIC_NUM);
+ endian->wr32(&tpl->ex_width,src_img->width);
+ endian->wr32(&tpl->ex_height,src_img->height);
+ endian->wr32(&tpl->ex_n_icon,src_img->height/src_img->width);
+ }
+
tpl_imgtab_t * tab = (tpl_imgtab_t*)( data + tab_off );
@@ -1366,17 +1477,35 @@ enumError CreateRawTPL
memcpy( data + m->pal_data_off, m->img.pal, 2*m->img.n_pal );
}
+// [[tpl-ex+]]
tpl_img_header_t * ti = (tpl_img_header_t*)( data + m->img_head_off );
- endian->wr16( &ti->width, m->img.width );
- endian->wr16( &ti->height, m->img.height );
+ endian->wr16( &ti->width, ex_width );
+ endian->wr16( &ti->height, ex_height );
endian->wr32( &ti->iform, m->img.iform );
endian->wr32( &ti->data_off, m->img_data_off );
endian->wr32( &ti->min_filter, 1 );
endian->wr32( &ti->mag_filter, 1 );
- err = WriteImageData( m, data + m->img_data_off );
+ u8 *dest;
+ err = WriteImageData( m, data + m->img_data_off, &dest );
if (err)
return err;
+ PRINT0("DEST: %p - %p = %zx\n", dest, data + m->img_data_off, dest - (data + m->img_data_off) );
+
+ if ( !i && ex_fill )
+ {
+ memset(dest,0,ex_fill);
+ if ( ex_fill >= sizeof(tpl_signature_t) )
+ {
+ tpl_signature_t *sig = (tpl_signature_t*)( dest + ex_fill ) -1;
+ *sig = TPLSignature0;
+ endian->wr32(&sig->width,src_img->width);
+ endian->wr32(&sig->height,src_img->height);
+ endian->wr32(&sig->n_icon,src_img->height/src_img->width);
+ endian->wr16(&sig->iform,src_img->iform);
+ endian->wr16(&sig->pform,src_img->pform);
+ }
+ }
}
raw->valid = true;
@@ -1385,9 +1514,29 @@ enumError CreateRawTPL
//-----------------------------------------------------------------------------
+enumError SaveRawTPL
+(
+ tpl_raw_t *raw, // raw data created by CreateRawTPL()
+ FILE *f, // output file, if NULL then use fname+overwrite
+ ccp fname, // filename of source
+ bool overwrite // true: allow overwriting
+)
+{
+ DASSERT(raw);
+ DASSERT(fname);
+ PRINT("SaveRawTPL(o=%d) %s\n", overwrite, fname );
+
+ return raw->valid
+ ? SaveFILE2(f,fname,0,overwrite,raw->data.ptr,raw->data.len,0)
+ : ERR_ERROR;
+}
+
+//-----------------------------------------------------------------------------
+
enumError SaveTPL
(
Image_t *src_img, // pointer to valid source img
+ file_format_t fform, // FF_TPL or FF_TPLX
FILE *f, // output file, if NULL then use fname+overwrite
ccp fname, // filename of source
bool overwrite // true: allow overwriting
@@ -1396,12 +1545,13 @@ enumError SaveTPL
DASSERT(src_img);
DASSERT(fname);
- PRINT("SaveTPL(o=%d) %s\n", overwrite, fname );
+ PRINT("SaveTPL(ff=%s,o=%d) %s\n", GetNameFF(fform,fform), overwrite, fname );
tpl_raw_t raw;
- enumError err = CreateRawTPL(&raw,src_img);
+ enumError err = CreateRawTPL(&raw,src_img,fform);
if (raw.valid)
- err = SaveFILE2(f,fname,0,overwrite,raw.data.ptr,raw.data.len,0);
+ err = SaveRawTPL(&raw,f,fname,overwrite);
+// err = SaveFILE2(f,fname,0,overwrite,raw.data.ptr,raw.data.len,0);
ResetRawTPL(&raw);
return err;
}
@@ -1478,7 +1628,7 @@ enumError SaveBTI
bti->wrap_t = 1;
}
- err = WriteImageData(&mmi,data+data_off);
+ err = WriteImageData(&mmi,data+data_off,0);
if (!err)
err = SaveFILE2(f,fname,0,overwrite,data,total_size,0);
@@ -1564,7 +1714,7 @@ enumError SaveTEX
endian->wr32(&ti->n_image,mmi.n_mipmap+1);
endian->wrf4(&ti->image_val,mmi.n_mipmap);
- err = WriteImageData(&mmi,data+grp_off);
+ err = WriteImageData(&mmi,data+grp_off,0);
if (!err)
err = SaveFILE2(f,fname,0,overwrite,data,total_size,0);
@@ -1635,7 +1785,7 @@ enumError SaveBREFTIMG
bi->iform = mmi.img.iform;
bi->n_image = mmi.n_mipmap + 1;
- err = WriteImageData(&mmi,data+img_off);
+ err = WriteImageData(&mmi,data+img_off,0);
if (!err)
err = SaveFILE2(f,fname,0,overwrite,data,total_size,0);
@@ -2476,7 +2626,10 @@ const KeywordTab_t cmdtab_transform[] =
{
//--- file formats
+// [[tpl-ex+]]
{ FF_TPL, "TPL", 0, TM_IDX_FILE|TM_F_PAL },
+ { FF_TPLX, "TPLx", "TPLX", TM_IDX_FILE|TM_F_PAL },
+ { FF_CUPICON, "CUPICON", "CUP", TM_IDX_FILE },
{ FF_BTI, "BTI", 0, TM_IDX_FILE|TM_F_PAL },
{ FF_TEX, "TEX", "TEX0", TM_IDX_FILE },
{ FF_BREFT_IMG, "BREFT-IMG", "BREFTIMG", TM_IDX_FILE },
@@ -2535,14 +2688,15 @@ const KeywordTab_t cmdtab_transform[] =
};
///////////////////////////////////////////////////////////////////////////////
+// [[transform_term_t]]
typedef struct transform_term_t
{
ccp arg;
char res[TM_IDX_N];
uint opt[TM_IDX_N];
-
-} transform_term_t;
+}
+transform_term_t;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -2676,6 +2830,12 @@ int ScanOptTransform ( ccp arg )
memcpy(t->src,sterm.res,sizeof(t->src));
memcpy(t->dest,dterm.res,sizeof(t->dest));
+ // special case: destionation is FF_CUPICON
+ if ( t->src[TM_IDX_FILE] == FF_CUPICON )
+ t->src[TM_IDX_FILE] = FF_TPLX;
+ if ( t->dest[TM_IDX_FILE] == FF_CUPICON )
+ t->dest[TM_IDX_IMG] = IMG_CMPR;
+
src = sterm.arg;
if ( !src )
break;
@@ -2722,17 +2882,17 @@ void DumpTransformList ( FILE * f, int indent, bool force )
return;
fprintf(f,"\n"
- "%*s source formats -> destination formats\n"
- "%*s file image palette pal color alph -> file image palette pal color alph\n"
- "%*s--------------------------------------------------------------------------------\n",
+ "%*s file source formats -> file destination formats\n"
+ "%*s type image palette pal color alph -> type image palette pal color alph\n"
+ "%*s----------------------------------------------------------------------------------\n",
indent, "", indent, "", indent, "" );
uint i;
for ( i = 0; i < n_transform; i++ )
{
const transform_t *t = transform + i;
fprintf(f,
- "%*s %-6s %-6s %-7s %-4.4s %-5s %-4.4s"
- " -> %-6s %-6s %-7s %-4.4s %-5s %-4.4s\n",
+ "%*s %-7s %-6s %-7s %-4.4s %-5s %-4.4s"
+ " -> %-7s %-6s %-7s %-4.4s %-5s %-4.4s\n",
indent, "",
GetTransformName(0,t->src[0],"*"),
GetTransformName(1,t->src[1],"*"),
@@ -3372,7 +3532,8 @@ uint GetNImagesTPL
DASSERT(data);
DASSERT(endian);
- return data_size >= sizeof(tpl_header_t) && endian->rd32(data) == TPL_MAGIC_NUM
+// [[tpl-ex+]]
+ return data_size >= sizeof(tpl_header_t) && endian->rd32(data) == TPL_MAGIC_NUM
? endian->rd32(data+4)
: 0;
}
@@ -3396,6 +3557,7 @@ bool SetupPointerTPL
DASSERT(data);
DASSERT(endian);
+// [[tpl-ex+]]
if ( data_size >= sizeof(tpl_header_t) && endian->rd32(data) == TPL_MAGIC_NUM )
{
const tpl_header_t *tpl = (tpl_header_t*)data;