From 9bb459224e3d9fa5149727f72f022e5e3bb0c305 Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Fri, 2 Feb 2018 15:07:05 +0100 Subject: [PATCH] Load_IFF() Fixed support of HAM pictures. Loading HAM6 and HAM8 ast true color pictures --- src/fileformats.c | 317 ++++++++++++++++------------------------------ src/loadsave.c | 6 +- 2 files changed, 113 insertions(+), 210 deletions(-) diff --git a/src/fileformats.c b/src/fileformats.c index bd22dce5..a41505da 100644 --- a/src/fileformats.c +++ b/src/fileformats.c @@ -331,112 +331,6 @@ void Test_LBM(T_IO_Context * context) // -- Lire un fichier au format IFF ----------------------------------------- - byte Image_HAM; - - // ---------------- Adapter la palette pour les images HAM ---------------- - void Adapt_palette_HAM(T_IO_Context * context) - { - short i,j,temp; - byte color; - - if (Image_HAM==6) - { - for (i=1; i<=14; i++) - { - // On recopie a palette de base - memcpy(context->Palette+(i<<4),context->Palette,48); - // On modifie les teintes de cette palette - for (j=0; j<16; j++) - { - color=(i<<4)+j; - if (i<=7) - { - if (i&1) - { - temp=context->Palette[j].R+16; - context->Palette[color].R=(temp<63)?temp:63; - } - if (i&2) - { - temp=context->Palette[j].G+16; - context->Palette[color].G=(temp<63)?temp:63; - } - if (i&4) - { - temp=context->Palette[j].B+16; - context->Palette[color].B=(temp<63)?temp:63; - } - } - else - { - if ((i-7)&1) - { - temp=context->Palette[j].R-16; - context->Palette[color].R=(temp>=0)?temp:0; - } - if ((i-7)&2) - { - temp=context->Palette[j].G-16; - context->Palette[color].G=(temp>=0)?temp:0; - } - if ((i-7)&4) - { - temp=context->Palette[j].B-16; - context->Palette[color].B=(temp>=0)?temp:0; - } - } - } - } - // Ici, il reste les 16 dernières couleurs à modifier - for (i=240,j=0; j<16; i++,j++) - { - temp=context->Palette[j].R+8; - context->Palette[i].R=(temp<63)?temp:63; - temp=context->Palette[j].G+8; - context->Palette[i].G=(temp<63)?temp:63; - temp=context->Palette[j].B+8; - context->Palette[i].B=(temp<63)?temp:63; - } - } - else if (Image_HAM==8) - { - for (i=1; i<=3; i++) - { - // On recopie la palette de base - memcpy(context->Palette+(i<<6),context->Palette,192); - // On modifie les teintes de cette palette - for (j=0; j<64; j++) - { - color=(i<<6)+j; - switch (i) - { - case 1 : - temp=context->Palette[j].R+16; - context->Palette[color].R=(temp<63)?temp:63; - break; - case 2 : - temp=context->Palette[j].G+16; - context->Palette[color].G=(temp<63)?temp:63; - break; - default: - temp=context->Palette[j].B+16; - context->Palette[color].B=(temp<63)?temp:63; - } - } - } - } - else // Image 64 couleurs sauvée en 32. - { - for (i=0; i<32; i++) - { - j=i+32; - context->Palette[j].R=context->Palette[i].R>>1; - context->Palette[j].G=context->Palette[i].G>>1; - context->Palette[j].B=context->Palette[i].B>>1; - } - } - } - // Inspired by Allegro: storing a 4-character identifier as a 32bit litteral #define ID4(a,b,c,d) ((((a)&255)<<24) | (((b)&255)<<16) | (((c)&255)<<8) | (((d)&255))) @@ -514,89 +408,92 @@ void Set_IFF_color(byte * buffer, word x_pos, byte color, word real_line_size, b } } - // ----------------------- Afficher une ligne ILBM ------------------------ - void Draw_IFF_line(T_IO_Context *context, const byte * buffer, short y_pos, short real_line_size, byte bitplanes) - { - byte color; - byte red,green,blue; - byte temp; - short x_pos; +// ----------------------- Afficher une ligne ILBM ------------------------ +static void Draw_IFF_line(T_IO_Context *context, const byte * buffer, short y_pos, short real_line_size, byte bitplanes) +{ + short x_pos; - if (Image_HAM<=1) // ILBM + if (bitplanes > 8) + { + for (x_pos=0; x_posWidth; x_pos++) { - if (bitplanes > 8) - { - for (x_pos=0; x_posWidth; x_pos++) - { - dword rgb = Get_IFF_color(buffer, x_pos,real_line_size, bitplanes); - Set_pixel_24b(context, x_pos,y_pos, rgb >> 16, rgb >> 8, rgb); - } - } - else for (x_pos=0; x_posWidth; x_pos++) - { - Set_pixel(context, x_pos,y_pos,Get_IFF_color(buffer, x_pos,real_line_size, bitplanes)); - } - } - else - { - color=0; - red=context->Palette[0].R; - green =context->Palette[0].G; - blue =context->Palette[0].B; - if (Image_HAM==6) - for (x_pos=0; x_posWidth; x_pos++) // HAM6 - { - temp=Get_IFF_color(buffer, x_pos,real_line_size, bitplanes); - switch (temp & 0xF0) - { - case 0x10: // blue - blue=(temp&0x0F)<<2; - color=Best_color(red,green,blue); - break; - case 0x20: // red - red=(temp&0x0F)<<2; - color=Best_color(red,green,blue); - break; - case 0x30: // green - green=(temp&0x0F)<<2; - color=Best_color(red,green,blue); - break; - default: // Nouvelle couleur - color=temp; - red=context->Palette[color].R; - green =context->Palette[color].G; - blue =context->Palette[color].B; - } - Set_pixel(context, x_pos,y_pos,color); - } - else - for (x_pos=0; x_posWidth; x_pos++) // HAM8 - { - temp=Get_IFF_color(buffer,x_pos,real_line_size, bitplanes); - switch (temp & 0x03) - { - case 0x01: // blue - blue=temp>>2; - color=Best_color(red,green,blue); - break; - case 0x02: // red - red=temp>>2; - color=Best_color(red,green,blue); - break; - case 0x03: // green - green=temp>>2; - color=Best_color(red,green,blue); - break; - default: // Nouvelle couleur - color=temp; - red=context->Palette[color].R; - green =context->Palette[color].G; - blue =context->Palette[color].B; - } - Set_pixel(context, x_pos,y_pos,color); - } + dword rgb = Get_IFF_color(buffer, x_pos,real_line_size, bitplanes); + Set_pixel_24b(context, x_pos,y_pos, rgb >> 16, rgb >> 8, rgb); } } + else for (x_pos=0; x_posWidth; x_pos++) + { + Set_pixel(context, x_pos,y_pos,Get_IFF_color(buffer, x_pos,real_line_size, bitplanes)); + } +} + +static void Draw_IFF_line_HAM(T_IO_Context *context, const byte * buffer, short y_pos, short real_line_size, byte bitplanes, const T_Components * SHAM_palettes, int SHAM_palette_count) +{ + short x_pos; + byte red, green, blue, temp; + const T_Components * palette; + + if (SHAM_palettes == NULL) + palette = context->Palette; + else + { + if (SHAM_palette_count >= context->Height) + palette = SHAM_palettes + 16*y_pos; + else + palette = SHAM_palettes + 16*(y_pos >> 1); + } + red = palette[0].R; + green = palette[0].G; + blue = palette[0].B; + if (bitplanes == 6) + { + for (x_pos=0; x_posWidth; x_pos++) // HAM6 + { + temp=Get_IFF_color(buffer, x_pos,real_line_size, bitplanes); + switch (temp & 0x30) + { + case 0x10: // blue + blue=(temp&0x0F)*0x11; + break; + case 0x20: // red + red=(temp&0x0F)*0x11; + break; + case 0x30: // green + green=(temp&0x0F)*0x11; + break; + default: // Nouvelle couleur + red=palette[temp].R; + green =palette[temp].G; + blue =palette[temp].B; + } + Set_pixel_24b(context, x_pos,y_pos,red,green,blue); + } + } + else + { + for (x_pos=0; x_posWidth; x_pos++) // HAM8 + { + temp=Get_IFF_color(buffer,x_pos,real_line_size, bitplanes); + switch (temp >> 6) + { + case 0x01: // blue + blue= (temp << 2) | ((temp & 0x30) >> 4); + break; + case 0x02: // red + red= (temp << 2) | ((temp & 0x30) >> 4); + break; + case 0x03: // green + green= (temp << 2) | ((temp & 0x30) >> 4); + break; + default: // Nouvelle couleur + red=palette[temp].R; + green =palette[temp].G; + blue =palette[temp].B; + } + Set_pixel_24b(context, x_pos,y_pos,red,green,blue); + } + } +} static void PBM_Decode(T_IO_Context * context, FILE * file, byte compression, word width, word height) { @@ -689,6 +586,7 @@ void Load_IFF(T_IO_Context * context) T_Components * SHAM_palettes = NULL; unsigned SHAM_palette_count = 0; byte truecolor = 0; + byte Image_HAM = 0; Get_full_filename(filename, context->File_name, context->File_directory); @@ -778,31 +676,26 @@ void Load_IFF(T_IO_Context * context) { nb_colors = section_size/3; - if (((dword)1<Palette,0,sizeof(T_Palette)); if (Read_bytes(IFF_file,context->Palette,3*nb_colors)) { - if (Image_HAM) - { - Palette_256_to_64(context->Palette); - Adapt_palette_HAM(context); - Palette_64_to_256(context->Palette); + if ((nb_colors==32) && (header.BitPlanes==6)) + { // This is a Extra Half-Brite (EHB) 64 color image. + int i, j; // 32 colors in the palette. + for (i=0; i<32; i++) // The next 32 colors are the same with values divided by 2 + { + j=i+32; + context->Palette[j].R=context->Palette[i].R>>1; + context->Palette[j].G=context->Palette[i].G>>1; + context->Palette[j].B=context->Palette[i].B>>1; + } } section_size -= 3*nb_colors; @@ -860,6 +753,8 @@ void Load_IFF(T_IO_Context * context) { word version; + Image_HAM = header.BitPlanes; + truecolor = 1; Read_word_be(IFF_file, &version); // always 0 section_size -= 2; SHAM_palette_count = section_size >> 5; // 32 bytes per palette (16 colors * 2 bytes) @@ -935,7 +830,12 @@ printf("%d x %d = %d %d\n", tiny_width, tiny_height, tiny_width*tiny_height, s for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) { if (Read_bytes(IFF_file,buffer,line_size)) - Draw_IFF_line(context, buffer, y_pos,real_line_size, header.BitPlanes); + { + if (Image_HAM <= 1) + Draw_IFF_line(context, buffer, y_pos,real_line_size, header.BitPlanes); + else + Draw_IFF_line_HAM(context, buffer, y_pos,real_line_size, header.BitPlanes, SHAM_palettes, SHAM_palette_count); + } else File_error=21; } @@ -974,7 +874,12 @@ printf("%d x %d = %d %d\n", tiny_width, tiny_height, tiny_width*tiny_height, s File_error=25; } if (!File_error) - Draw_IFF_line(context, buffer, y_pos,real_line_size,header.BitPlanes); + { + if (Image_HAM <= 1) + Draw_IFF_line(context, buffer, y_pos,real_line_size,header.BitPlanes); + else + Draw_IFF_line_HAM(context, buffer, y_pos,real_line_size, header.BitPlanes, SHAM_palettes, SHAM_palette_count); + } } free(buffer); break; @@ -3900,7 +3805,6 @@ void Load_PCX(T_IO_Context * context) real_line_size=(short)PCX_header.Bytes_per_plane_line<<3; // On se sert de données ILBM car le dessin de ligne en moins de 256 // couleurs se fait comme avec la structure ILBM. - Image_HAM=0; buffer=(byte *)malloc(line_size); // Chargement de l'image @@ -4317,7 +4221,6 @@ void Load_SCx(T_IO_Context * context) size=((context->Width+7)>>3)*SCx_header.Planes; real_size=(size/SCx_header.Planes)<<3; buffer=(byte *)malloc(size); - Image_HAM=0; for (y_pos=0;(y_posHeight) && (!File_error);y_pos++) { diff --git a/src/loadsave.c b/src/loadsave.c index b04b183c..dfac6471 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -163,7 +163,7 @@ void Load_SDL_Image(T_IO_Context *); // ENUM Name TestFunc LoadFunc SaveFunc PalOnly Comment Layers Ext Exts const T_Format File_formats[] = { - {FORMAT_ALL_IMAGES, "(all)", NULL, NULL, NULL, 0, 0, 0, "", "gif;png;bmp;2bp;pcx;pkm;iff;lbm;ilbm;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;c64;koa;koala;fli;bml;cdu;prg;tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;cm5;pph"}, + {FORMAT_ALL_IMAGES, "(all)", NULL, NULL, NULL, 0, 0, 0, "", "gif;png;bmp;2bp;pcx;pkm;iff;lbm;ilbm;sham;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;c64;koa;koala;fli;bml;cdu;prg;tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico;ic2;cur;cm5;pph"}, {FORMAT_ALL_PALETTES, "(pal)", NULL, NULL, NULL, 1, 0, 0, "", "kcf;pal;gpl"}, {FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"}, {FORMAT_GIF, " gif", Test_GIF, Load_GIF, Save_GIF, 0, 1, 1, "gif", "gif"}, @@ -173,8 +173,8 @@ const T_Format File_formats[] = { {FORMAT_BMP, " bmp", Test_BMP, Load_BMP, Save_BMP, 0, 0, 0, "bmp", "bmp;2bp"}, {FORMAT_PCX, " pcx", Test_PCX, Load_PCX, Save_PCX, 0, 0, 0, "pcx", "pcx"}, {FORMAT_PKM, " pkm", Test_PKM, Load_PKM, Save_PKM, 0, 1, 0, "pkm", "pkm"}, - {FORMAT_LBM, " lbm", Test_LBM, Load_IFF, Save_IFF, 0, 0, 0, "iff", "iff;lbm;ilbm"}, - {FORMAT_PBM, " pbm", Test_PBM, Load_IFF, Save_IFF, 0, 0, 0, "iff", "iff;pbm"}, + {FORMAT_LBM, " lbm", Test_LBM, Load_IFF, Save_IFF, 0, 0, 0, "iff", "iff;lbm;ilbm;sham"}, + {FORMAT_PBM, " pbm", Test_PBM, Load_IFF, Save_IFF, 0, 0, 0, "iff", "iff;pbm;lbm"}, {FORMAT_IMG, " img", Test_IMG, Load_IMG, Save_IMG, 0, 0, 0, "img", "img"}, {FORMAT_SCx, " sc?", Test_SCx, Load_SCx, Save_SCx, 0, 0, 0, "sc?", "sci;scq;scf;scn;sco"}, {FORMAT_PI1, " pi1", Test_PI1, Load_PI1, Save_PI1, 0, 0, 0, "pi1", "pi1"},