add support for reading HP-48 Grob format

This commit is contained in:
Thomas BERNARD 2019-07-13 19:10:45 +02:00 committed by Thomas Bernard
parent 911ad97646
commit 0cea439da9
No known key found for this signature in database
GPG Key ID: 0FF11B67A5C0863C
4 changed files with 150 additions and 6 deletions

View File

@ -155,6 +155,7 @@ enum FILE_FORMATS
FORMAT_MOTO, ///< Thomson MO/TO computers pictures FORMAT_MOTO, ///< Thomson MO/TO computers pictures
FORMAT_HGR, ///< Apple II HGR and DHGR FORMAT_HGR, ///< Apple II HGR and DHGR
FORMAT_TIFF, ///< Tagged Image File Format FORMAT_TIFF, ///< Tagged Image File Format
FORMAT_GRB, ///< HP-48 Grob
FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image (or recoil) FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image (or recoil)
FORMAT_CLIPBOARD ///< To load/save from/to Clipboard FORMAT_CLIPBOARD ///< To load/save from/to Clipboard
}; };

View File

@ -2,7 +2,7 @@
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2018 Thomas Bernard Copyright 2018-2019 Thomas Bernard
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
Grafx2 is free software; you can redistribute it and/or Grafx2 is free software; you can redistribute it and/or
@ -175,5 +175,9 @@ void Load_TIFF_from_memory(T_IO_Context *, const void *, unsigned long);
void Save_TIFF_to_memory(T_IO_Context *, void * *, unsigned long *); void Save_TIFF_to_memory(T_IO_Context *, void * *, unsigned long *);
#endif #endif
// -- HP-48 Grob ------------------------------------------------------------
void Test_GRB(T_IO_Context *, FILE *);
void Load_GRB(T_IO_Context *);
/// @} /// @}
#endif #endif

View File

@ -119,6 +119,7 @@ const T_Format File_formats[] = {
"gpx;" "gpx;"
"cpc;scr;win;" "cpc;scr;win;"
"hgr;dhgr;" "hgr;dhgr;"
"grb;grob;"
"tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;cm5;pph;info;flc;bin;map"}, "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;cm5;pph;info;flc;bin;map"},
{FORMAT_ALL_PALETTES, "(pal)", NULL, NULL, NULL, 1, 0, 0, "", "kcf;pal;gpl"}, {FORMAT_ALL_PALETTES, "(pal)", NULL, NULL, NULL, 1, 0, 0, "", "kcf;pal;gpl"},
{FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"}, {FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"},
@ -156,6 +157,7 @@ const T_Format File_formats[] = {
#ifndef __no_tifflib__ #ifndef __no_tifflib__
{FORMAT_TIFF," tiff",Test_TIFF,Load_TIFF,Save_TIFF,0, 1, 1, "tif", "tif;tiff"}, {FORMAT_TIFF," tiff",Test_TIFF,Load_TIFF,Save_TIFF,0, 1, 1, "tif", "tif;tiff"},
#endif #endif
{FORMAT_GRB, " grb", Test_GRB, Load_GRB, NULL, 0, 0, 0, "grb", "grb;grob"},
{FORMAT_MISC,"misc.",NULL, NULL, NULL, 0, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff"}, {FORMAT_MISC,"misc.",NULL, NULL, NULL, 0, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff"},
}; };

View File

@ -2,7 +2,7 @@
*/ */
/* Grafx2 - The Ultimate 256-color bitmap paint program /* Grafx2 - The Ultimate 256-color bitmap paint program
Copyright 2018 Thomas Bernard Copyright 2018-2019 Thomas Bernard
Copyright 2011 Pawel Góralski Copyright 2011 Pawel Góralski
Copyright 2009 Petter Lindquist Copyright 2009 Petter Lindquist
Copyright 2008 Yves Rizoud Copyright 2008 Yves Rizoud
@ -7322,3 +7322,140 @@ void Save_HGR(T_IO_Context * context)
free(vram[1]); free(vram[1]);
fclose(file); fclose(file);
} }
///////////////////////////// HP-48 Grob Files ////////////////////////////
/**
* HP48 addresses are 20bits (5 nibbles)
* offset is in nibble (half byte)
*/
static dword Read_HP48Address(const byte * buffer, int offset)
{
dword data = 0;
int i = 4;
do
{
byte nibble;
nibble = buffer[(offset + i) >> 1];
if ((offset + i) & 1)
nibble >>= 4;
nibble &= 15;
data = (data << 4) | nibble;
}
while (i-- > 0);
return data;
}
/**
* Test for a HP-48 Grob file
*/
void Test_GRB(T_IO_Context * context, FILE * file)
{
byte buffer[18];
unsigned long file_size;
dword prologue, size, width, height;
(void)context;
File_error = 1;
file_size = File_length_file(file);
if (!Read_bytes(file, buffer, 18))
return;
if(memcmp(buffer, "HPHP48-R", 8) != 0)
return;
prologue = Read_HP48Address(buffer+8, 0);
size = Read_HP48Address(buffer+8, 5);
GFX2_Log(GFX2_DEBUG, "HP48 File detected. %lu bytes prologue %05x %u nibbles\n",
file_size, prologue, size);
if (prologue != 0x02b1e)
return;
height = Read_HP48Address(buffer+8, 10);
width = Read_HP48Address(buffer+8, 15);
GFX2_Log(GFX2_DEBUG, " Grob dimensions : %ux%u\n", width, height);
if ((file_size - 8) < ((size + 5) / 2))
return;
if (file_size < (18 + ((width + 7) >> 3) * height))
return;
File_error = 0;
}
void Load_GRB(T_IO_Context * context)
{
byte buffer[18];
byte * bitplane[4];
unsigned long file_size;
dword prologue, size, width, height;
byte bp, bpp;
FILE * file;
unsigned x, y;
File_error = 1;
file = Open_file_read(context);
if (file == NULL)
return;
file_size = File_length_file(file);
if (!Read_bytes(file, buffer, 18))
{
fclose(file);
return;
}
prologue = Read_HP48Address(buffer+8, 0);
size = Read_HP48Address(buffer+8, 5);
height = Read_HP48Address(buffer+8, 10);
width = Read_HP48Address(buffer+8, 15);
if (height >= 256)
bpp = 4;
else if (height >= 192)
bpp = 3;
else if (height >= 128)
bpp = 2;
else
bpp = 1;
File_error = 0;
Pre_load(context, width, height/bpp, file_size, FORMAT_GRB, PIXEL_SIMPLE, bpp);
if (File_error == 0)
{
dword bytes_per_plane = ((width + 7) >> 3) * (height/bpp);
dword offset = 0;
if (Config.Clear_palette)
memset(context->Palette, 0, sizeof(T_Palette));
for (x = 0; x < ((unsigned)1 << bpp); x++)
{
context->Palette[x].R = context->Palette[x].G = (x * 255) / ((1 << bpp) - 1);
context->Palette[x].B = 127;
}
// Load all bit planes
for (bp = 0; bp < bpp; bp++)
{
bitplane[bp] = GFX2_malloc(bytes_per_plane);
if (bitplane[bp])
{
if (!Read_bytes(file, bitplane[bp], bytes_per_plane))
File_error = 1;
}
}
// set pixels
for (y = 0; y < (height/bpp) && File_error == 0; y++)
{
for (x = 0; x < width; x++)
{
byte b = 0;
for (bp = 0; bp < bpp; bp++)
b |= ((bitplane[bp][offset] >> (x & 7)) & 1) << bp;
// invert because 1 is a black pixel on HP-48 LCD display
Set_pixel(context, x, y, b ^ ((1 << bpp) - 1));
if ((x & 7) == 7)
offset++;
}
if ((x & 7) != 7)
offset++;
}
// Free bit planes
for (bp = 0; bp < bpp; bp++)
free(bitplane[bp]);
}
fclose(file);
}