]> bicyclesonthemoon.info Git - ott/enhance/commitdiff
perform action on multiple pictures at once. NOT FINISHED!
authorb <rowerynaksiezycu@gmail.com>
Mon, 14 Nov 2022 23:13:00 +0000 (23:13 +0000)
committerb <rowerynaksiezycu@gmail.com>
Mon, 14 Nov 2022 23:13:00 +0000 (23:13 +0000)
core.c
core.h

diff --git a/core.c b/core.c
index c8ac6930bccf3889fd8fc4e99c008988567cc340..71d514db74a7455c50296b95bf56443e710ee478 100644 (file)
--- a/core.c
+++ b/core.c
@@ -1,7 +1,7 @@
 /*
 core.c
 The tool with multiple enhancements and manipulations of pictures
-13.11.2022
+14.11.2022
 
 Copyright (C) 2014, 2015, 2022  Balthasar Szczepański
 
@@ -1026,6 +1026,496 @@ int action_1picture (
        return r;
 }
 
+int perform_action (
+       uint_fast16_t n,
+       uint_fast16_t *id,
+       ILint *x0, ILint *y0, *ILint f0, ILint width, ILint height, ILint frames,
+       ACTION_F *function,
+       FLAG_TYPE *flags,
+       void *data
+)
+{
+       uint_fast16_t i, j;
+       uint_fast8_t palette_only = 1;
+       uint_fast8_t skip_frame;
+       uint_fast8_t skip_line;
+       uint_fast8_t skip_pixel;
+       ILint actual_frames = 0xFFFFFFFF;
+       ILint actual_width  = 0xFFFFFFFF;
+       ILint actual_height = 0xFFFFFFFF;
+       ILint actual_colours= 0xFFFFFFFF;
+       ILint x, y, f;
+       struct PixelInfo *p;
+       int r = 0;
+       
+       if (n==0)
+               return 0;
+       
+       p = malloc((sizeof (struct PixelInfo)) * n);
+       if (p == NULL)
+       {
+               perror("perform_action(): malloc():");
+               return (r=errno);
+       }
+       
+       for (i=0; i<n; ++i)
+       {
+               p[i].flags = flags[i] & ~(IS_MULTIPLE);
+               
+               if (id[i] >= n_pictures)
+               {
+                       free(p);
+                       return EINVAL;
+               }
+               if (!(picture[id].open))
+               {
+                       free(p);
+                       return EINVAL;
+               }
+               
+               get_info(id[i], &(p[i].info), 0);
+       
+               if (p[i].info.num_images > 0)
+                       p[i].flags |= IS_MULTIPLE;
+               if (p[i].flags & CAN_BE_MULTIPLE)
+               {
+                       if (p[i].num_images+1 < actual_frames)
+                               actual_frames = p[i].num_images+1;
+               }
+               else
+                       actual_frames = 1;
+               
+               if (p[i].info.image_width < actual_width)
+                       actual_width = p[i].info.image_width;
+               if (p[i].info.image_height < actual_height)
+                       actual_height = p[i].info.image_height;
+               
+               if (*flags & IN_WINDOW) /* check first flags only! */
+               {
+                       p[i].f0 = f0[i];
+                       p[i].x0 = x0[i];
+                       p[i].y0 = y0[i];
+               }
+               else
+               {
+                       p[i].f0 = 0;
+                       p[i].x0 = 0;
+                       p[i].y0 = 0;
+               }
+               
+               if ((p[i].info.image_format != IL_COLOUR_INDEX) || (!(p[i].flags & OK_PALETTE_ONLY)))
+                       palette_only = 0;
+       }
+       
+       if (!(*flags & IN_WINDOW)) /* check first flags only! */
+       {
+               width = actual_width;
+               height = actual_height;
+               frames = actual_frames;
+       }
+       
+       for (f = 0; (f < frames) && (r == 0); ++f)
+       {
+               skip_frame = 0;
+               for (i=0; i<n; ++n)
+               {
+                       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;
+                       }
+                       
+                       ilBindImage(picture[id[i]].handle);
+                       ilActiveImage(p[i].f_pict);
+                       p[i].data = ilGetData();
+                       p[i].flags &= ~(IS_GRAY|IS_INDEXED|IS_OVER_8BIT|IS_PALETTE_ONLY);
+                       if (palette_only)
+                               p[i].flags |= IS_PALETTE_ONLY;
+                       
+                       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;
+                       
+                       if (palette_only)
+                       {
+                               if (p[i].palette_num_cols < actual_colours)
+                                       actual_colours = p[i].palette_num_cols;
+                       }
+                       
+                       switch (p[i].info.image_format)
+                       {
+                       case IL_COLOUR_INDEX:
+                               p[i].flags |= IS_INDEXED;
+                               p[i].palette = ilGetPalette();
+                               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;
+                               }
+                               break;
+                       case IL_LUMINANCE_ALPHA:
+                               p[i].flags |= HAS_ALPHA;
+                               p[i].alpha_offset = 1 * p[i].info.image_bpc;
+                       case IL_LUMINANCE:
+                               p[i].flags |= IS_GRAY;
+                               p[i].value_offset = 0 * p[i].info.image_bpc;
+                               break;
+                       case IL_BGRA:
+                               p[i].flags |= HAS_ALPHA;
+                               p[i].alpha_offset = 3 * p[i].info.image_bpc;
+                       case IL_BGR:
+                               p[i].red_offset   = 2 * p[i].info.image_bpc;
+                               p[i].green_offset = 1 * p[i].info.image_bpc;
+                               p[i].blue_offset  = 0 * p[i].info.image_bpc;
+                               break;
+                       case IL_RGBA:
+                               p[i].flags |= HAS_ALPHA;
+                               p[i].alpha_offset = 3 * p[i].info.image_bpc;
+                       case IL_RGB:
+                       default:
+                               p[i].red_offset   = 0 * p[i].info.image_bpc;
+                               p[i].green_offset = 1 * p[i].info.image_bpc;
+                               p[i].blue_offset  = 2 * p[i].info.image_bpc;
+                               break;
+                       }
+                       if (p[i].info.image_bpc > 1)
+                               p[i].flags |= IS_OVER_8BIT;
+               }
+               if (!skip_frame)
+               {
+                       if (palette_only)
+                       {
+                               for (i=0; i<n; ++i)
+                               {
+                                       p[i].index = 0;
+                                       p[i].pal_offset = 0;
+                                       flags[i] |= IS_PALETE_ONLY;
+                               }
+                               for (j=0; (j<actual_colours) && (r==0); ++j)
+                               {
+                                       for (i=0; i<n; ++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(n, p, data);
+                                       if (r)
+                                               break;
+                                       
+                                       for (i=0; i<n; ++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[i].index);
+                                               p[i].pal_offset += p[i].info.palette_bpp;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               for (i=0; i<n; ++i)
+                               {
+                                       p[i].line_bytes = p[i].info.image_bytes_per_pixel * p[i].info.image_width;
+                                       p[i].frame_bytes = p[i].line_bytes * p[i].info.image_height;
+                                       
+                                       if (p[i].info.image_origin == IL_ORIGIN_LOWER_LEFT)
+                                       {
+                                               p[i].line_start = p[i].frame_bytes - p[i].line_bytes;
+                                               p[i].line_bytes = 0 - p[i].line_bytes;
+                                       }
+                                       else
+                                               p[i].line_start = 0;
+                                       
+                                       p[i].y_window = 0;
+                                       p[i].y_pict = p[i].y0;
+                                       p[i].line_offset = p[i].line_start + (p[i].y_pict * p[i].line_bytes);
+                               }
+                               for (y=0; (y<height)  && (r == 0); ++y)
+                               {
+                                       skip_line = 0;
+                                       for (i=0; i<n; ++i)
+                                       {
+                                               if ((p[i].y_pict < 0) || (p[i].y_pict >= p[i]info.image_height))
+                                               {
+                                                       skip_line = 1;
+                                                       break;
+                                               }
+                                               
+                                               p[i].x_window = 0;
+                                               p[i].x_pict = p[i].x0;
+                                               p[i].pixel_offset = p[i].line_offset + (p[i].x_pict * p[i].info.image_bytes_per_pixel);                                         
+                                       }
+                                       if (!skip_line)
+                                       {
+                                               for (x=0; x<width; ++x)
+                                               {
+                                                       skip_pixel = 0;
+                                                       for (i=0; i<n; ++i)
+                                                       {
+                                                               if ((p[i].x_pict < 0) || (p[i].x_pict >= p[i]info.image_width))
+                                                               {
+                                                                       skip_pixel = 1;
+                                                                       break;
+                                                               }
+                                                       }
+                                                       if (!skip_pixel)
+                                                       {
+                                                               for (i=0; i<n; ++i)
+                                                               {
+                                                                       if (!(p[i].flags & NOT_READABLE))
+                                                                       {
+                                                                               /* can this be done better? think about it */
+                                                                               switch (p[i].info.image_type)
+                                                                               {
+                                                                               case IL_INT:
+                                                                               case IL_UNSIGNED_INT:
+                                                                                       if (p[i].flags & IS_INDEXED)
+                                                                                               p[i].index = *((ILuint*)(p[i].data + p[i].pixel_offset + p[i].index_offset));
+                                                                                       else
+                                                                                       {
+                                                                                               if (p[i].flags & IS_GRAY)
+                                                                                                       p[i].value = *((ILuint*)(p[i].data + p[i].pixel_offset + p[i].value_offset));
+                                                                                               else
+                                                                                               {
+                                                                                                       p[i].red   = *((ILuint*)(p[i].data + p[i].pixel_offset + p[i].red_offset));
+                                                                                                       p[i].green = *((ILuint*)(p[i].data + p[i].pixel_offset + p[i].green_offset));
+                                                                                                       p[i].blue  = *((ILuint*)(p[i].data + p[i].pixel_offset + p[i].blue_offset));
+                                                                                               }
+                                                                                               if (p.flags & HAS_ALPHA)
+                                                                                                       p[i].alpha = *((ILuint*)(p[i].data + p[i].pixel_offset + p[i].alpha_offset));
+                                                                                       }
+                                                                                       break;
+                                                                               case IL_SHORT:
+                                                                               case IL_UNSIGNED_SHORT:
+                                                                                       if (p[i].flags & IS_INDEXED)
+                                                                                               p[i].index = (ILuint)(*((ILushort*)(p[i].data + p[i].pixel_offset + p[i].index_offset)));
+                                                                                       else
+                                                                                       {
+                                                                                               if(p.flags & IS_GRAY)
+                                                                                                       p[i].value = (ILuint)(*((ILushort*)(p[i].data + p[i].pixel_offset + p[i].value_offset)));
+                                                                                               else
+                                                                                               {
+                                                                                                       p[i].red   = (ILuint)(*((ILushort*)(p[i].data + p[i].pixel_offset + p[i].red_offset)));
+                                                                                                       p[i].green = (ILuint)(*((ILushort*)(p[i].data + p[i].pixel_offset + p[i].green_offset)));
+                                                                                                       p[i].blue  = (ILuint)(*((ILushort*)(p[i].data + p[i].pixel_offset + p[i].blue_offset)));
+                                                                                               }
+                                                                                               if(p.flags & HAS_ALPHA)
+                                                                                                       p[i].alpha = (ILuint)(*((ILushort*)(p[i].data + p[i].pixel_offset + p[i].alpha_offset)));
+                                                                                       }
+                                                                                       break;
+                                                                               case IL_BYTE:
+                                                                               case IL_UNSIGNED_BYTE:
+                                                                                       if(p.flags & IS_INDEXED)
+                                                                                               p[i].index = (ILuint)(*((ILubyte*)(p[i].data + p[i].pixel_offset + p[i].index_offset)));
+                                                                                       else
+                                                                                       {
+                                                                                               if(p.flags & IS_GRAY)
+                                                                                                       p[i].value = (ILuint)(*((ILubyte*)(p[i].data + p[i].pixel_offset + p[i].value_offset)));
+                                                                                               else
+                                                                                               {
+                                                                                                       p[i].red   = (ILuint)(*((ILubyte*)(p[i].data + p[i].pixel_offset + p[i].red_offset)));
+                                                                                                       p[i].green = (ILuint)(*((ILubyte*)(p[i].data + p[i].pixel_offset + p[i].green_offset)));
+                                                                                                       p[i].blue  = (ILuint)(*((ILubyte*)(p[i].data + p[i].pixel_offset + p[i].blue_offset)));
+                                                                                               }
+                                                                                               if(p.flags & HAS_ALPHA)
+                                                                                                       p[i].alpha = (ILuint)(*((ILubyte*)(p[i].data + p[i].pixel_offset + p[i].alpha_offset)));
+                                                                                       }
+                                                                                       break;
+                                                                               default:
+                                                                                       break;
+                                                                               }
+                                                                       
+                                                                               if ((p[i].flags & IS_INDEXED) && (p[i].flags & CANNOT_BE_INDEXED))
+                                                                               {
+                                                                                       if (p[i].index < p[i].info.palette_num_cols)
+                                                                                       {
+                                                                                               p[i].pal_offset = p[i].index * p[i].info.palette_bpp;
+                                                                                               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)
+                                                                                                       p[i].alpha = (ILuint)(*((ILubyte*)(p[i].palette + p[i].pal_offset + p[i].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;
+}
+
+
 ILuint upscale_value (ILubyte x, ILint bytes)
 {
        ILint i;
diff --git a/core.h b/core.h
index a97c98e9a8a831450c7251d1de954cf00c05f21d..750f84f5f92786b88b968242cf2a7d442e9df707 100644 (file)
--- a/core.h
+++ b/core.h
@@ -1,7 +1,7 @@
  /*
 core.h
 The tool with multiple enhancements and manipulations of pictures
-13.11.2022
+14.11.2022
 
 Copyright (C) 2022  Balthasar Szczepański
 
@@ -117,6 +117,10 @@ struct IL_full_info {
 
 struct PixelInfo
 {
+       ILint x0;
+       ILint y0;
+       ILint f0;
+       
        ILint x_window;
        ILint y_window;
        ILint f_window;