]> bicyclesonthemoon.info Git - ott/enhance/commitdiff
action on palette mix (3p)
authorb <rowerynaksiezycu@gmail.com>
Mon, 28 Nov 2022 22:32:51 +0000 (22:32 +0000)
committerb <rowerynaksiezycu@gmail.com>
Mon, 28 Nov 2022 22:32:51 +0000 (22:32 +0000)
bluenh.c
core.c
core.h

index 323f24c81491daa99941eb191816c0e7006e1808..f053a499e89fabd2d068eafc1a1d21273a611b63 100644 (file)
--- a/bluenh.c
+++ b/bluenh.c
@@ -1,7 +1,7 @@
 /*
 bluenh.c
 ENHANCE the bluepix!
-15.11.2022
+28.11.2022
 
 Copyright (C) 2015, 2022  Balthasar Szczepański
 
@@ -48,7 +48,7 @@ struct bluenh_data
        ILint64 r_low;
        ILint64 s_low;
        ILint64 t_low;
-       ILint64 max;
+       ILuint max;
 };
 
 int bluenhance (ILuint n, struct PixelInfo *p, void *data);
diff --git a/core.c b/core.c
index efa86917e1bf7072a8bf4254fd7a2890033ae465..a6408cfa1a0850e408319fa8ea50b3a96dd3d99b 100644 (file)
--- a/core.c
+++ b/core.c
@@ -1,7 +1,7 @@
 /*
 core.c
 The tool with multiple enhancements and manipulations of pictures
-15.11.2022
+28.11.2022
 
 Copyright (C) 2014, 2015, 2022  Balthasar Szczepański
 
@@ -36,12 +36,16 @@ on Pentium III libdevil must be recompiled with
 uint_fast16_t n_pictures = 0;
 struct Picture * picture;
 
-char INIT_FAILED[]   = "Failae to set up library.\n";
-char LOAD_FAILED[]   = "Failed to load picture.\n";
-char SAVE_FAILED[]   = "Failed to save picture.\n";
-char CREATE_FAILED[] = "Failed to create picture(s).\n";
-char CONVERT_FAILED[]= "Failed to convert picture.\n";
-char SIZE_MISMATCH[] = "Pictures have different sizes.\n";
+char INIT_FAILED[]          = "Failed to set up library.\n";
+char LOAD_FAILED[]          = "Failed to load picture.\n";
+char SAVE_FAILED[]          = "Failed to save picture.\n";
+char CREATE_FAILED[]        = "Failed to create picture(s).\n";
+char CONVERT_FAILED[]       = "Failed to convert picture.\n";
+char SIZE_MISMATCH[]        = "Pictures have different sizes.\n";
+char MULTIPLE_FORBIDDEN[]   = "Picture is not allowed to have multiple frames.\n";
+char INDEXED_REQUIRED[]     = "Picture must be indexed.\n";
+char PALETTE_ONLY_REQUIRED[]= "Palette-only operation must be allowed.\n";
+char BAD_PALETTE_SIZE[]     = "Palette has wrong number of colours.\n";
 char NO_STR[] = "";
 
 int init (void)
@@ -71,6 +75,36 @@ ILuint get_handle (uint_fast16_t id)
                return -1;
 }
 
+int get_data (uint_fast16_t id, void **data, ILuint frame)
+{
+       if (id >= n_pictures)
+               return EINVAL;
+       if (!(picture[id].open))
+               return EIO;
+       ilBindImage(picture[id].handle);
+       if (frame > ilGetInteger(IL_NUM_IMAGES))
+               return EINVAL;
+       ilActiveImage(frame);
+       *data = ilGetData();
+       return 0;
+}
+
+int get_palette (uint_fast16_t id, void **palette, ILuint frame)
+{
+       if (id >= n_pictures)
+               return EINVAL;
+       if (!(picture[id].open))
+               return EIO;
+       ilBindImage(picture[id].handle);
+       if (frame > ilGetInteger(IL_NUM_IMAGES))
+               return EINVAL;
+       ilActiveImage(frame);
+       if (ilGetInteger(IL_IMAGE_FORMAT) != IL_COLOUR_INDEX)
+               return EINVAL;
+       *palette = ilGetPalette();
+       return 0;
+}
+
 void create_picture (uint_fast16_t id)
 {
        if (id<n_pictures)
@@ -225,7 +259,7 @@ int convert_picture (uint_fast16_t id, struct IL_full_info *info, FLAG_TYPE *fla
        {
                if (ilGetInteger(IL_NUM_IMAGES) > 0)
                {
-                       fputs("Picture is not allowed to have multiple frames.\n", stderr);
+                       fputs(MULTIPLE_FORBIDDEN, stderr);
                        return EINVAL;
                }
        }
@@ -330,7 +364,7 @@ int convert_picture (uint_fast16_t id, struct IL_full_info *info, FLAG_TYPE *fla
        {
                if (*flags & MUST_BE_INDEXED)
                {
-                       fputs("Picture must be indexed.\n", stderr);
+                       fputs(INDEXED_REQUIRED, stderr);
                        return EINVAL;
                }
                
@@ -520,7 +554,6 @@ int build_picture (uint_fast16_t id, ILint width, ILint height, ILint frames, st
 int build_picture_from_info (uint_fast16_t id, struct IL_full_info *reference_info, struct IL_full_info *info, FLAG_TYPE *flags)
 {
        ILint i;
-       int r;
        
        if (id >= n_pictures)
                return EINVAL;
@@ -651,389 +684,6 @@ int perform_action_1picture (
                &flags,
                data
        );
-       
-       
-       // ILint actual_frames;
-       // struct PixelInfo p;
-       // int r = 0;
-       
-       // p.flags = flags & ~(IS_MULTIPLE);
-       
-       // if (id >= n_pictures)
-               // return EINVAL;
-       
-       // if (!(picture[id].open))
-               // return EINVAL;
-       
-       // ilBindImage(picture[id].handle);
-       // get_info(id, &(p.info), 0);
-       
-       // if (p.info.num_images > 0)
-               // p.flags |= IS_MULTIPLE;
-       // actual_frames = (p.flags & CAN_BE_MULTIPLE) ? (p.info.num_images+1) : 1;
-       
-       // if (!(flags & IN_WINDOW))
-       // {
-               // f0 = 0;
-               // frames = actual_frames;
-       // }
-       
-       // for (
-               // p.f_window = 0, p.f_pict = f0;
-               // (p.f_window  < frames) && (r == 0);
-               // ++(p.f_window), ++(p.f_pict)
-       // ){
-               // if ((p.f_pict >= 0) && (p.f_pict <= p.info.num_images))
-               // {
-                       // ilBindImage(picture[id].handle);
-                       // ilActiveImage(p.f_pict);
-                       // p.data = ilGetData();
-                       // p.flags &= ~(IS_GRAY|IS_INDEXED|IS_OVER_8BIT|IS_PALETTE_ONLY);
-                       
-                       // p.alpha_offset = 0;
-                       // p.value_offset = 0;
-                       // p.index_offset = 0;
-                       // p.red_offset = 0;
-                       // p.green_offset = 0;
-                       // p.blue_offset = 0;
-                       
-                       // switch (p.info.image_format)
-                       // {
-                       // case IL_COLOUR_INDEX:
-                               // p.flags |= IS_INDEXED;
-                               // p.palette = ilGetPalette();
-                               // switch (p.info.palette_type)
-                               // {
-                               // case IL_PAL_BGR32:
-                               // case IL_PAL_RGB32:
-                                       // p.flags |= IS_OVER_8BIT;
-                                       // break;
-                               // case IL_PAL_BGRA32:
-                                       // p.flags |= HAS_ALPHA;
-                                       // p.alpha_offset = 3;
-                               // case IL_PAL_BGR24:
-                                       // p.red_offset = 2;
-                                       // p.green_offset = 1;
-                                       // p.blue_offset = 0;
-                                       // break;
-                               // case IL_PAL_RGBA32:
-                                       // p.flags |= HAS_ALPHA;
-                                       // p.alpha_offset = 3;
-                               // case IL_PAL_RGB24:
-                               // default:
-                                       // p.red_offset = 0;
-                                       // p.green_offset = 1;
-                                       // p.blue_offset = 2;
-                                       // break;
-                               // }
-                               // break;
-                       // case IL_LUMINANCE_ALPHA:
-                               // p.flags |= HAS_ALPHA;
-                               // p.alpha_offset = 1 * p.info.image_bpc;
-                       // case IL_LUMINANCE:
-                               // p.flags |= IS_GRAY;
-                               // p.value_offset = 0 * p.info.image_bpc;
-                               // break;
-                       // case IL_BGRA:
-                               // p.flags |= HAS_ALPHA;
-                               // p.alpha_offset = 3 * p.info.image_bpc;
-                       // case IL_BGR:
-                               // p.red_offset = 2 * p.info.image_bpc;
-                               // p.green_offset = 1 * p.info.image_bpc;
-                               // p.blue_offset = 0 * p.info.image_bpc;
-                               // break;
-                       // case IL_RGBA:
-                               // p.flags |= HAS_ALPHA;
-                               // p.alpha_offset = 3 * p.info.image_bpc;
-                       // case IL_RGB:
-                       // default:
-                               // p.red_offset = 0 * p.info.image_bpc;
-                               // p.green_offset = 1 * p.info.image_bpc;
-                               // p.blue_offset = 2 * p.info.image_bpc;
-                               // break;
-                       // }
-                       // if (p.info.image_bpc > 1)
-                               // p.flags |= IS_OVER_8BIT;
-                       
-                       // if ((p.flags & IS_INDEXED) && (p.flags & OK_PALETTE_ONLY))
-                       // {
-                               // p.flags |= IS_PALETTE_ONLY;
-                               // for (
-                                       // p.index = 0, p.pal_offset=0;
-                                       // (p.index < p.info.palette_num_cols) && (r == 0);
-                                       // ++p.index, p.pal_offset += p.info.palette_bpp
-                               // ){
-                                       // if (!(p.flags & NOT_READABLE))
-                                       // {
-                                               // p.red   = (ILuint)(*((ILubyte*)(p.palette + p.pal_offset + p.red_offset)));
-                                               // p.green = (ILuint)(*((ILubyte*)(p.palette + p.pal_offset + p.green_offset)));
-                                               // p.blue  = (ILuint)(*((ILubyte*)(p.palette + p.pal_offset + p.blue_offset)));
-                                               // if (p.flags & HAS_ALPHA)
-                                               // {
-                                                       // if (p.flags & CANNOT_HAVE_ALPHA)
-                                                               // p.alpha = 0xFF;
-                                                       // else
-                                                               // p.alpha = (ILuint)(*((ILubyte*)(p.palette + p.pal_offset + p.alpha_offset)));
-                                               // }
-                                               // else if (p.flags & MUST_HAVE_ALPHA)
-                                                       // p.alpha = 0xFF;
-                                               // if (p.flags & MUST_BE_GRAY)
-                                                       // p.value = (p.red + p.green + p.blue) / 3;
-                                       // }
-                                       
-                                       // r = function(1, &p, data);
-                                       // if (r)
-                                               // break;
-                                       
-                                       // if (!(p.flags & NOT_READABLE))
-                                       // {
-                                               // if (p.flags & MUST_BE_GRAY)
-                                               // {
-                                                       // p.red   = p.value;
-                                                       // p.green = p.value;
-                                                       // p.blue  = p.value;
-                                               // }
-                                               // if (p.flags & HAS_ALPHA)
-                                               // {
-                                                       // if (p.flags & CANNOT_HAVE_ALPHA)
-                                                               // p.alpha = 0xFF;
-                                                       // *((ILubyte*)(p.palette + p.pal_offset + p.alpha_offset)) = (ILubyte)p.alpha;
-                                               // }
-                                               // *((ILubyte*)(p.palette + p.pal_offset + p.red_offset))   = (ILubyte)p.red;
-                                               // *((ILubyte*)(p.palette + p.pal_offset + p.green_offset)) = (ILubyte)p.green;
-                                               // *((ILubyte*)(p.palette + p.pal_offset + p.blue_offset))  = (ILubyte)p.blue;
-                                       // }
-                               // }
-                       // }
-                       // else
-                       // {
-                               // p.line_bytes = p.info.image_bytes_per_pixel * p.info.image_width;
-                               // p.frame_bytes = p.line_bytes * p.info.image_height;
-                               
-                               // if (p.info.image_origin == IL_ORIGIN_LOWER_LEFT)
-                               // {
-                                       // p.line_start = p.frame_bytes - p.line_bytes;
-                                       // p.line_bytes = 0 - p.line_bytes;
-                               // }
-                               // else
-                                       // p.line_start = 0;
-                               
-                               // if (!(flags & IN_WINDOW))
-                               // {
-                                       // x0 = 0;
-                                       // y0 = 0;
-                                       // width = p.info.image_width;
-                                       // height = p.info.image_height;
-                               // }
-
-                               // for (
-                                       // p.y_window = 0, p.y_pict = y0, p.line_offset = p.line_start + (p.y_pict * p.line_bytes);
-                                       // (p.y_window < height) && (r == 0);
-                                       // ++p.y_window, ++p.y_pict, p.line_offset += p.line_bytes
-                               // ){
-                                       // if ((p.y_pict >= 0) && (p.y_pict < p.info.image_height))
-                                       // {
-                                               // for (
-                                                       // p.x_window = 0, p.x_pict = x0, p.pixel_offset = p.line_offset + (p.x_pict * p.info.image_bytes_per_pixel);
-                                                       // (p.x_window < width) && (r == 0);
-                                                       // ++p.x_window, ++p.x_pict, p.pixel_offset += p.info.image_bytes_per_pixel
-                                               // ){
-                                                       // if ((p.x_pict >=0) && (p.x_pict < p.info.image_width))
-                                                       // {
-                                                               // if (!(p.flags & NOT_READABLE))
-                                                               // {
-                                                                       // /* can this be done better? think about it */
-                                                                       // switch (p.info.image_type)
-                                                                       // {
-                                                                       // case IL_INT:
-                                                                       // case IL_UNSIGNED_INT:
-                                                                               // if(p.flags & IS_INDEXED)
-                                                                                       // p.index = *((ILuint*)(p.data + p.pixel_offset + p.index_offset));
-                                                                               // else
-                                                                               // {
-                                                                                       // if(p.flags & IS_GRAY)
-                                                                                               // p.value = *((ILuint*)(p.data + p.pixel_offset + p.value_offset));
-                                                                                       // else
-                                                                                       // {
-                                                                                               // p.red   = *((ILuint*)(p.data + p.pixel_offset + p.red_offset));
-                                                                                               // p.green = *((ILuint*)(p.data + p.pixel_offset + p.green_offset));
-                                                                                               // p.blue  = *((ILuint*)(p.data + p.pixel_offset + p.blue_offset));
-                                                                                       // }
-                                                                                       // if(p.flags & HAS_ALPHA)
-                                                                                               // p.alpha = *((ILuint*)(p.data + p.pixel_offset + p.alpha_offset));
-                                                                               // }
-                                                                               // break;
-                                                                       // case IL_SHORT:
-                                                                       // case IL_UNSIGNED_SHORT:
-                                                                               // if(p.flags & IS_INDEXED)
-                                                                                       // p.index = (ILuint)(*((ILushort*)(p.data + p.pixel_offset + p.index_offset)));
-                                                                               // else
-                                                                               // {
-                                                                                       // if(p.flags & IS_GRAY)
-                                                                                               // p.value = (ILuint)(*((ILushort*)(p.data + p.pixel_offset + p.value_offset)));
-                                                                                       // else
-                                                                                       // {
-                                                                                               // p.red   = (ILuint)(*((ILushort*)(p.data + p.pixel_offset + p.red_offset)));
-                                                                                               // p.green = (ILuint)(*((ILushort*)(p.data + p.pixel_offset + p.green_offset)));
-                                                                                               // p.blue  = (ILuint)(*((ILushort*)(p.data + p.pixel_offset + p.blue_offset)));
-                                                                                       // }
-                                                                                       // if(p.flags & HAS_ALPHA)
-                                                                                               // p.alpha = (ILuint)(*((ILushort*)(p.data + p.pixel_offset + p.alpha_offset)));
-                                                                               // }
-                                                                               // break;
-                                                                       // case IL_BYTE:
-                                                                       // case IL_UNSIGNED_BYTE:
-                                                                               // if(p.flags & IS_INDEXED)
-                                                                                       // p.index = (ILuint)(*((ILubyte*)(p.data + p.pixel_offset + p.index_offset)));
-                                                                               // else
-                                                                               // {
-                                                                                       // if(p.flags & IS_GRAY)
-                                                                                               // p.value = (ILuint)(*((ILubyte*)(p.data + p.pixel_offset + p.value_offset)));
-                                                                                       // else
-                                                                                       // {
-                                                                                               // p.red   = (ILuint)(*((ILubyte*)(p.data + p.pixel_offset + p.red_offset)));
-                                                                                               // p.green = (ILuint)(*((ILubyte*)(p.data + p.pixel_offset + p.green_offset)));
-                                                                                               // p.blue  = (ILuint)(*((ILubyte*)(p.data + p.pixel_offset + p.blue_offset)));
-                                                                                       // }
-                                                                                       // if(p.flags & HAS_ALPHA)
-                                                                                               // p.alpha = (ILuint)(*((ILubyte*)(p.data + p.pixel_offset + p.alpha_offset)));
-                                                                               // }
-                                                                               // break;
-                                                                       // default:
-                                                                               // break;
-                                                                       // }
-                                                                       
-                                                                       // if ((p.flags & IS_INDEXED) && (p.flags & CANNOT_BE_INDEXED))
-                                                                       // {
-                                                                               // if (p.index < p.info.palette_num_cols)
-                                                                               // {
-                                                                                       // p.pal_offset = p.index * p.info.palette_bpp;
-                                                                                       // p.red   = (ILuint)(*((ILubyte*)(p.palette + p.pal_offset + p.red_offset)));
-                                                                                       // p.green = (ILuint)(*((ILubyte*)(p.palette + p.pal_offset + p.green_offset)));
-                                                                                       // p.blue  = (ILuint)(*((ILubyte*)(p.palette + p.pal_offset + p.blue_offset)));
-                                                                                       // if (p.flags & HAS_ALPHA)
-                                                                                               // p.alpha = (ILuint)(*((ILubyte*)(p.palette + p.pal_offset + p.alpha_offset)));
-                                                                               // }
-                                                                       // }
-                                                                       
-                                                                       // if ((p.flags & IS_GRAY) && (p.flags & CANNOT_BE_GRAY))
-                                                                       // {
-                                                                               // p.red   = p.value;
-                                                                               // p.green = p.value;
-                                                                               // p.blue  = p.value;
-                                                                       // }
-                                                                       // else if (!(p.flags & IS_GRAY) && (p.flags & MUST_BE_GRAY))
-                                                                               // p.value = (p.red + p.green + p.blue) / 3;
-                                                                       
-                                                                       // if (((!(p.flags & HAS_ALPHA)) && (p.flags & MUST_HAVE_ALPHA)) || ((p.flags & HAS_ALPHA) && (p.flags & CANNOT_HAVE_ALPHA)))
-                                                                       // {
-                                                                               // switch (p.info.image_type)
-                                                                               // {
-                                                                               // case IL_INT:
-                                                                               // case IL_UNSIGNED_INT:
-                                                                                       // p.alpha = 0xFFFFFFFF;
-                                                                                       // break;
-                                                                               // case IL_SHORT:
-                                                                               // case IL_UNSIGNED_SHORT:
-                                                                                       // p.alpha = 0xFFFF;
-                                                                                       // break;
-                                                                               // case IL_BYTE:
-                                                                               // case IL_UNSIGNED_BYTE:
-                                                                                       // p.alpha = 0xFF;
-                                                                                       // break;
-                                                                               // default:
-                                                                                       // break;
-                                                                               // }
-                                                                       // }
-                                                               // }
-                                                               
-                                                               // r = function(1, &p, data);
-                                                               // if (r)
-                                                                       // break;
-                                                               
-                                                               // if (!(p.flags & NOT_WRITABLE))
-                                                               // {
-                                                                       // if ((p.flags & HAS_ALPHA) && (p.flags & CANNOT_HAVE_ALPHA))
-                                                                               // p.alpha = 0xFFFFFFFF;
-                                                                       
-                                                                       // else if (!(p.flags & IS_GRAY) && (p.flags & MUST_BE_GRAY))
-                                                                       // {
-                                                                               // p.red   = p.value;
-                                                                               // p.green = p.value;
-                                                                               // p.blue  = p.value;
-                                                                       // }
-                                                                       // else if ((p.flags & IS_GRAY) && (p.flags & CANNOT_BE_GRAY))
-                                                                               // p.value = (p.red + p.green + p.blue) / 3;
-                                                                       
-                                                                       // switch (p.info.image_type)
-                                                                       // {
-                                                                       // case IL_INT:
-                                                                       // case IL_UNSIGNED_INT:
-                                                                               // if(p.flags & IS_INDEXED)
-                                                                                       // *((ILuint*)(p.data + p.pixel_offset + p.index_offset)) = p.index;
-                                                                               // else
-                                                                               // {
-                                                                                       // if(p.flags & IS_GRAY)
-                                                                                               // *((ILuint*)(p.data + p.pixel_offset + p.value_offset)) = p.value;
-                                                                                       // else
-                                                                                       // {
-                                                                                               // *((ILuint*)(p.data + p.pixel_offset + p.red_offset))   = p.red;
-                                                                                               // *((ILuint*)(p.data + p.pixel_offset + p.green_offset)) = p.green;
-                                                                                               // *((ILuint*)(p.data + p.pixel_offset + p.blue_offset))  = p.blue;
-                                                                                       // }
-                                                                                       // if(p.flags & HAS_ALPHA)
-                                                                                               // *((ILuint*)(p.data + p.pixel_offset + p.alpha_offset)) = (ILubyte)p.alpha;
-                                                                               // }
-                                                                               // break;
-                                                                       // case IL_SHORT:
-                                                                       // case IL_UNSIGNED_SHORT:
-                                                                               // if(p.flags & IS_INDEXED)
-                                                                                       // *((ILushort*)(p.data + p.pixel_offset + p.index_offset)) = (ILushort)p.index;
-                                                                               // else
-                                                                               // {
-                                                                                       // if(p.flags & IS_GRAY)
-                                                                                               // *((ILushort*)(p.data + p.pixel_offset + p.value_offset)) = (ILushort)p.value;
-                                                                                       // else
-                                                                                       // {
-                                                                                               // *((ILushort*)(p.data + p.pixel_offset + p.red_offset))   = (ILushort)p.red;
-                                                                                               // *((ILushort*)(p.data + p.pixel_offset + p.green_offset)) = (ILushort)p.green;
-                                                                                               // *((ILushort*)(p.data + p.pixel_offset + p.blue_offset))  = (ILushort)p.blue;
-                                                                                       // }
-                                                                                       // if(p.flags & HAS_ALPHA)
-                                                                                               // *((ILushort*)(p.data + p.pixel_offset + p.alpha_offset)) = (ILushort)p.alpha;
-                                                                               // }
-                                                                               // break;
-                                                                       // case IL_BYTE:
-                                                                       // case IL_UNSIGNED_BYTE:
-                                                                               // if(p.flags & IS_INDEXED)
-                                                                                       // *((ILubyte*)(p.data + p.pixel_offset + p.index_offset)) = (ILubyte)p.index;
-                                                                               // else
-                                                                               // {
-                                                                                       // if(p.flags & IS_GRAY)
-                                                                                               // *((ILubyte*)(p.data + p.pixel_offset + p.value_offset)) = (ILubyte)p.value;
-                                                                                       // else
-                                                                                       // {
-                                                                                               // *((ILubyte*)(p.data + p.pixel_offset + p.red_offset))   = (ILubyte)p.red;
-                                                                                               // *((ILubyte*)(p.data + p.pixel_offset + p.green_offset)) = (ILubyte)p.green;
-                                                                                               // *((ILubyte*)(p.data + p.pixel_offset + p.blue_offset))  = (ILubyte)p.blue;
-                                                                                       // }
-                                                                                       // if(p.flags & HAS_ALPHA)
-                                                                                               // *((ILubyte*)(p.data + p.pixel_offset + p.alpha_offset)) = (ILubyte)p.alpha;
-                                                                               // }
-                                                                               // break;
-                                                                       // default:
-                                                                               // break;
-                                                                       // }
-                                                               // }
-                                                       // }
-                                               // }
-                                       // }
-                               // }
-                       // }
-               // }
-       // }
-       
-       // return r;
 }
 
 int perform_action (
@@ -1071,27 +721,32 @@ int perform_action (
        
        for (i=0; i<n; ++i)
        {
+               p[i].id = id[i];
+               p[i].handle = get_handle(p[i].id);
                p[i].flags = flags[i] & ~(IS_MULTIPLE);
                
-               if (id[i] >= n_pictures)
+               if (p[i].id >= n_pictures)
                {
                        free(p);
                        return EINVAL;
                }
-               if (!(picture[id[i]].open))
+               if (!(picture[p[i].id].open))
                {
                        free(p);
                        return EINVAL;
                }
                
-               get_info(id[i], &(p[i].info), 0);
+               r = get_info(p[i].id, &(p[i].info), 0);
+               if (r!=0)
+                       return r;
+               p[i].frames = p[i].info.num_images + 1;
        
-               if (p[i].info.num_images > 0)
+               if (p[i].frames > 0)
                        p[i].flags |= IS_MULTIPLE;
                if (p[i].flags & CAN_BE_MULTIPLE)
                {
-                       if (p[i].info.num_images+1 < actual_frames)
-                               actual_frames = p[i].info.num_images+1;
+                       if (p[i].frames < actual_frames)
+                               actual_frames = p[i].frames;
                }
                else
                        actual_frames = 1;
@@ -1132,15 +787,20 @@ int perform_action (
                {
                        p[i].f_window = f;
                        p[i].f_pict = p[i].f0 + f;
-                       if ((p[i].f_pict < 0) || (p[i].f_pict > p[i].info.num_images))
+                       if ((p[i].f_pict < 0) || (p[i].f_pict >= p[i].frames))
                        {
                                skip_frame = 1;
                                break;
                        }
                        
-                       ilBindImage(picture[id[i]].handle);
-                       ilActiveImage(p[i].f_pict);
-                       p[i].data = ilGetData();
+                       r = get_info(p[i].id, &(p[i].info), p[i].f_pict);
+                       if (r!=0)
+                               break;
+                       
+                       r = get_data(p[i].id, &(p[i].data),  p[i].f_pict);
+                       if (r!=0)
+                               break;
+                       
                        p[i].flags &= ~(IS_GRAY|IS_INDEXED|IS_OVER_8BIT|IS_PALETTE_ONLY);
                        if (palette_only)
                                p[i].flags |= IS_PALETTE_ONLY;
@@ -1162,7 +822,9 @@ int perform_action (
                        {
                        case IL_COLOUR_INDEX:
                                p[i].flags |= IS_INDEXED;
-                               p[i].palette = ilGetPalette();
+                               r = get_palette(p[i].id, &(p[i].palette),  p[i].f_pict);
+                               if (r!=0)
+                                       break;
                                switch (p[i].info.palette_type)
                                {
                                case IL_PAL_BGR32:
@@ -1526,6 +1188,208 @@ int perform_action (
 }
 
 
+int perform_action_palette_mix (
+       uint_fast16_t *id,
+       ILint *f0,
+       ILint frames,
+       ACTION_F *function,
+       FLAG_TYPE *flags,
+       void *data
+)
+{
+       uint_fast16_t i;
+       int r = 0;
+       struct PixelInfo p[3];
+       ILuint n_colors;
+       ILint actual_frames = 0x7FFFFFFF;
+       ILint f;
+       uint_fast8_t skip_frame;
+       ILuint j, k;
+       
+       
+       for (i=0; i<3; ++i)
+       {
+               p[i].id = id[i];
+               p[i].handle = get_handle(p[i].id);
+               p[i].flags = flags[i];
+               r = get_info(p[i].id, &(p[i].info), 0);
+               if (r!=0)
+                       return r;
+               get_flags(&(p[i].info), &(p[i].flags));
+               
+               if (!(p[i].flags & IS_INDEXED))
+               {
+                       fputs(INDEXED_REQUIRED, stderr);
+                       return EINVAL;
+               }
+               if (!(p[i].flags & OK_PALETTE_ONLY))
+               {
+                       fputs(PALETTE_ONLY_REQUIRED, stderr);
+                       return EINVAL;
+               }
+               if (p[i].flags & CAN_BE_MULTIPLE)
+               {
+                       if (p[i].info.num_images+1 < actual_frames)
+                               actual_frames = p[i].info.num_images+1;
+               }
+               else
+                       actual_frames = 1;
+               
+               if (*flags & IN_WINDOW) /* check first flags only! */
+                       p[i].f0 = f0[i];
+               else
+                       p[i].f0 = f0[i];
+       }
+       
+       n_colors = p[0].info.palette_num_cols * p[1].info.palette_num_cols;
+       if (p[2].info.palette_num_cols < n_colors)
+       {
+               fputs(BAD_PALETTE_SIZE, stderr);
+               return EINVAL;
+       }
+       
+       if (!(*flags & IN_WINDOW)) /* check first flags only! */
+               frames = actual_frames;
+       
+       for (f = 0; (f < frames) && (r == 0); ++f)
+       {
+               skip_frame = 0;
+               for (i=0; i<3; ++i)
+               {
+                       p[i].f_window = f;
+                       p[i].f_pict = p[i].f0 + f;
+                       if ((p[i].f_pict < 0) || (p[i].f_pict > p[i].info.num_images))
+                       {
+                               skip_frame = 1;
+                               break;
+                       }
+                       
+                       r = get_info(p[i].id, &(p[i].info), p[i].f_pict);
+                       if (r!=0)
+                               return r;
+                       
+                       get_flags(&(p[i].info), &(p[i].flags));
+                       p[i].flags |= IS_PALETTE_ONLY;
+                       
+                       r = get_data(p[i].id, &(p[i].data),  p[i].f_pict);
+                       if (r!=0)
+                               return r;
+                       
+                       r = get_palette(p[i].id, &(p[i].palette),  p[i].f_pict);
+                       if (r!=0)
+                               return r;
+                       
+                       if (!(p[i].flags & IS_INDEXED))
+                       {
+                               fputs(INDEXED_REQUIRED, stderr);
+                               return EINVAL;
+                       }
+                       
+                       p[i].alpha_offset = 0;
+                       p[i].value_offset = 0;
+                       p[i].index_offset = 0;
+                       p[i].red_offset = 0;
+                       p[i].green_offset = 0;
+                       p[i].blue_offset = 0;
+                       
+                       switch (p[i].info.palette_type)
+                       {
+                       case IL_PAL_BGR32:
+                       case IL_PAL_RGB32:
+                               p[i].flags |= IS_OVER_8BIT;
+                               break;
+                       case IL_PAL_BGRA32:
+                               p[i].flags |= HAS_ALPHA;
+                               p[i].alpha_offset = 3;
+                       case IL_PAL_BGR24:
+                               p[i].red_offset = 2;
+                               p[i].green_offset = 1;
+                               p[i].blue_offset = 0;
+                               break;
+                       case IL_PAL_RGBA32:
+                               p[i].flags |= HAS_ALPHA;
+                               p[i].alpha_offset = 3;
+                       case IL_PAL_RGB24:
+                       default:
+                               p[i].red_offset = 0;
+                               p[i].green_offset = 1;
+                               p[i].blue_offset = 2;
+                               break;
+                       }
+               }
+               if (!skip_frame)
+               {
+                       p[0].index = 0;
+                       p[0].pal_offset = 0;
+                       p[2].index = 0;
+                       p[2].pal_offset = 0;
+                       for (j=0; j<p[0].info.palette_num_cols; ++j)
+                       {
+                               p[1].index = 0;
+                               p[1].pal_offset = 0;
+                               for (k=0; k<p[1].info.palette_num_cols; ++k)
+                               {
+                                       for (i=0; i<3; ++i)
+                                       {
+                                               if (!(p[i].flags & NOT_READABLE))
+                                               {
+                                                       p[i].red   = (ILuint)(*((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].red_offset)));
+                                                       p[i].green = (ILuint)(*((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].green_offset)));
+                                                       p[i].blue  = (ILuint)(*((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].blue_offset)));
+                                                       if (p[i].flags & HAS_ALPHA)
+                                                       {
+                                                               if (p[i].flags & CANNOT_HAVE_ALPHA)
+                                                                       p[i].alpha = 0xFF;
+                                                               else
+                                                                       p[i].alpha = (ILuint)(*((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].alpha_offset)));
+                                                       }
+                                                       else if (p[i].flags & MUST_HAVE_ALPHA)
+                                                               p[i].alpha = 0xFF;
+                                                       if (p[i].flags & MUST_BE_GRAY)
+                                                               p[i].value = (p[i].red + p[i].green + p[i].blue) / 3;
+                                               }
+                                       }
+                                       
+                                       r = function(3, p, data);
+                                       if (r)
+                                               break;
+                                       
+                                       for (i=0; i<3; ++i)
+                                       {
+                                               if (!(p[i].flags & NOT_WRITABLE))
+                                               {
+                                                       if (p[i].flags & MUST_BE_GRAY)
+                                                       {
+                                                               p[i].red   = p[i].value;
+                                                               p[i].green = p[i].value;
+                                                               p[i].blue  = p[i].value;
+                                                       }
+                                                       if (p[i].flags & HAS_ALPHA)
+                                                       {
+                                                               if (p[i].flags & CANNOT_HAVE_ALPHA)
+                                                                       p[i].alpha = 0xFF;
+                                                               *((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].alpha_offset)) = (ILubyte)(p[i].alpha);
+                                                       }
+                                                       *((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].red_offset))   = (ILubyte)(p[i].red);
+                                                       *((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].green_offset)) = (ILubyte)(p[i].green);
+                                                       *((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].blue_offset))  = (ILubyte)(p[i].blue);
+                                               }
+                                       }
+                                       
+                                       ++p[1].index;
+                                       p[1].pal_offset += p[1].info.palette_bpp;
+                                       ++p[2].index;
+                                       p[2].pal_offset += p[1].info.palette_bpp;
+                               }
+                               ++p[0].index;
+                               p[0].pal_offset += p[0].info.palette_bpp;
+                       }
+               }
+       }
+       
+       return r;
+}
+
 ILuint upscale_value (ILubyte x, ILint bytes)
 {
        ILint i;
diff --git a/core.h b/core.h
index 2a1d263e97521bc634b6ca07713b3e91ccc15475..09449ba83e2371d96a0b51bd334176e98fdf2caa 100644 (file)
--- a/core.h
+++ b/core.h
@@ -1,7 +1,7 @@
  /*
 core.h
 The tool with multiple enhancements and manipulations of pictures
-15.11.2022
+28.11.2022
 
 Copyright (C) 2022  Balthasar Szczepański
 
@@ -64,6 +64,10 @@ extern char SAVE_FAILED[];
 extern char CREATE_FAILED[];
 extern char CONVERT_FAILED[];
 extern char SIZE_MISMATCH[];
+extern char MULTIPLE_FORBIDDEN[];
+extern char INDEXED_REQUIRED[];
+extern char PALETTE_ONLY_REQUIRED[];
+extern char BAD_PALETTE_SIZE[];
 
 struct Picture {
        uint_fast8_t open;
@@ -118,6 +122,10 @@ struct IL_full_info {
 
 struct PixelInfo
 {
+       uint_fast16_t id;
+       ILuint handle;
+       ILuint frames;
+       
        ILint x0;
        ILint y0;
        ILint f0;
@@ -171,6 +179,7 @@ typedef int (SUBTOOL_F)(int argc, char **argv, int argi, char **err);
 void finish (int const returnvalue, char const * const returntext);
 int init (void);
 ILuint get_handle (uint_fast16_t id);
+int get_data (uint_fast16_t id, void **data, ILuint frame);
 void create_picture (uint_fast16_t id);
 int create_pictures (uint_fast16_t n);
 void close_picture (uint_fast16_t id);
@@ -207,5 +216,13 @@ int perform_action (
        void *data
 );
 
+int perform_action_palette_mix (
+       uint_fast16_t *id,
+       ILint *f0,
+       ILint frames,
+       ACTION_F *function,
+       FLAG_TYPE *flags,
+       void *data
+);
 
-ACTION_F action;
\ No newline at end of file
+//ACTION_F action;
\ No newline at end of file