gimp_drawable_merge_shadow doesn't work

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



#include <libgimp/gimp.h>
#include <gegl.h>
#include <gegl-buffer.h>
#include <math.h> //for ceil and sin
#include <stdio.h>


static void query (void);
static void run   (const gchar      *name,
                   gint              nparams,
                   const GimpParam  *param,
                   gint             *nreturn_vals,
                   GimpParam       **return_vals);


static int draw_dimetric_projection_lines_7_42(GimpDrawable* drawable);

GimpPlugInInfo PLUG_IN_INFO =
{
  NULL,
  NULL,
  query,
  run
};

MAIN()

static void query (void)
{
    static GimpParamDef args[] =
     {
       {
         GIMP_PDB_INT32,
         "run-mode",
         "Run mode"
       },
       {
         GIMP_PDB_IMAGE,
         "image",
         "Input image"
       },
       {
         GIMP_PDB_DRAWABLE,
         "drawable",
         "Input drawable"
       }
     };

     gimp_install_procedure (
       "perspective_lines",
       "perspective_lines V1.1",
       "draws lines for isometric perspective",
       "David Suliga",
       "Copyright David Suliga",
       "2021",
       "_perspective_lines",
       "RGB*, GRAY*",
       GIMP_PLUGIN,
       G_N_ELEMENTS (args), 0,
       args, NULL);

     gimp_plugin_menu_register ("perspective_lines",
                                "<Image>/Filters/Misc");
}


static void run   (const gchar      *name,
                   gint              nparams,
                   const GimpParam  *param,
                   gint             *nreturn_vals,
                   GimpParam       **return_vals)
{
    static GimpParam  values[1];
    GimpPDBStatusType status = GIMP_PDB_SUCCESS;
    GimpRunMode       run_mode;
    GimpDrawable     *drawable;

    gint32 drawable_id;




    *nreturn_vals = 1;
    *return_vals  = values;

    values[0].type = GIMP_PDB_STATUS;
    values[0].data.d_status = status;


    run_mode = param[0].data.d_int32;

    /*  Get the specified drawable  */
    drawable = gimp_drawable_get(param[2].data.d_drawable);

    //INIT_I18N (); ???
    gegl_init (NULL, NULL);
    babl_init();

    drawable_id = param[2].data.d_drawable;



    if (run_mode != GIMP_RUN_NONINTERACTIVE)
    {
        if (draw_dimetric_projection_lines_7_42(drawable) == FALSE)
        {
            status = GIMP_PDB_EXECUTION_ERROR;
            values[0].data.d_status = status;

        }

    }

  //  gimp_displays_flush ();
  //  gimp_drawable_detach (drawable);

    return;



}
/************************************************************************************************************************
*                               draw_dimetric_projection_lines_7_42                                                     *
*************************************************************************************************************************
This function draws raster of horizontal lines with an angel of 7 degrees and vertical lines of 42 degrees.
Problems:
Either the pixels are not set  or not given back to the core correctly (see  Main Problem below).
Further Problems:
How can I add an alpha-channel ?
How can I draw the raster into a new layer ?
*/
static int draw_dimetric_projection_lines_7_42(GimpDrawable* drawable)
{
printf("perspective_lines: start draw_dimetric_projection_lines_7_42 \n" );
            gint         i, j, k, channels;
            gint         x1, y1, x2, y2;
           // GimpPixelRgn rgn_in, rgn_out;
            GeglBuffer* rgn_in;
            GeglBuffer* rgn_out;
            guchar       output[4];
            gint32 drawable_id = drawable->drawable_id;

//            GeglBuffer *drawable_buffer;
            //rgn_in = gimp_drawable_get_buffer(drawable_id);


            const Babl *format;
            format = babl_format ("R'G'B'A u8");
            gint32 image_id = gimp_item_get_image(drawable_id);


            /* Gets upper left and lower right coordinates,
             * and layers number in the image */
           gimp_drawable_mask_bounds (drawable_id,
                                       &x1, &y1,
                                       &x2, &y2);
            channels = gimp_drawable_bpp(drawable_id);

            if (gimp_drawable_has_alpha (drawable_id)==FALSE)
            {
               printf("perspective_lines: No Alpha_Channel \n");
               g_message("The plugin perspective lines needs an alpha channel in it's source-image\n");
               return FALSE;

               /*How can I create an alpha-channel ?
                gimp_image_insert_channel () needs a parent id. Where can I get one?
               Where is the term "channel" defined ? Is this the right command ?*/

            //this doesn'T work:
            /*   GimpRGB channel_color;
               channel_color.a = 0;channel_color.g = 0;channel_color.b = 0;channel_color.a = 0;
               gint32 channel_id = gimp_channel_new ( image_id,"alpha-channel",x2,y2,0,&channel_color);
               gint32 parent_id =  gimp_item_get_parent(channel_id);

               if(gimp_image_insert_channel(image_id,channel_id,parent_id,-1)== FALSE)
               {
                    g_message("The plugin perspective lines needs an alpha channel in it's source-image\n");
                    return FALSE;
               }
             */




            }



          // Okay this are the newer commands than gimp_drawable_mask_bounds
          //   x2  = gimp_drawable_width  (drawable_id);
          //   y2 = gimp_drawable_height (drawable_id);


            GeglRectangle pixel_to_set;//This rectangle describes a singel pixel and is used in the gegl_buffer_set command later.

            rgn_in = gimp_drawable_get_buffer(drawable_id);//The buffer with source image and its' tiles. Which is the image in the active layer before
                                                           //we called the plugin


            rgn_out = gimp_drawable_get_shadow_buffer(drawable_id);//The buffer with destination image and its' tiles.
                                                                   //The image in that we do our modifications and
                                                                   //which is plug in's result if merged with the source image
            // Are this definitions correct ? Where is the term shadow_buffer defined ?





             const int bitmap_size = x2 * y2;

             guchar pixel [bitmap_size] [4]; // array for the image data. Used as source in the gegl_buffer_set- command later.
             int new_line_distance =ceil(y2/40);
             int new_column_distance = ceil(x2/40);

             int xp_out = 0; //x-position for the pixel which is set by  the gegl_buffer_set- command later.
             int yp_out = 0; //y-position for the pixel which is set by the gegl_buffer_set- command later.
             int xp_multi_yp = 0;//The pixel's position in the array pixel[]

             int hypo_length = 0;
             double aspect_ratio = 2;

     printf("perspective_lines: start creating a layer\n");
             /*----------------------------------------------------------------------------------------------------------
              -                       Trying    to create a new layer                                                   -
             ------------------------------------------------------------------------------------------------------------*/
             /*Unsolved Problem:
              I want create a new layer and storing the plug in's result in it's image/drawable(?).
              I only found out how to create a new layer but how can I get access to it's image/drawable ?*/

             if(gimp_image_is_valid(image_id) == FALSE )
             {
               printf("perspective_lines: Image is invalid \n");
               return FALSE;
             }
/*
             if(gimp_drawable_set_image(drawable->drawable_id,image_id)==FALSE)
             {
                   printf("perspective_lines: Can't set image to drawable. Image_ID: %i \n",image_id);
                   return ;
             }
*/



/*            gint32 new_layer = gimp_layer_new(image_id,"lines",x2,y2,GIMP_RGBA_IMAGE,0,GIMP_NORMAL_MODE);
            // gint32 active_layer = gimp_image_get_active_layer(image_id);
           // gint32 new_layer = gimp_layer_new_from_drawable (drawable_id,image_id);
             if(gimp_image_insert_layer(image_id,new_layer,0,-1)==FALSE)
             {
                 printf("perspective_lines: Can't create layer. \n");
                 return ;
             }




             if(gimp_image_set_active_layer(image_id,new_layer)== FALSE)
             {
                 printf("perspective_lines: Can't set layer active. \n");
                 return ;
             }

//           --------------------------------------------------------------------------------------------------------------
*/



             //We want a transparent background.
             gimp_drawable_fill (drawable_id,GIMP_TRANSPARENT_FILL);

             // Print informations for debugging
             printf("perspective_lines: rgn_in width: %i rgn_in height: %i \n",gegl_buffer_get_width(rgn_in),gegl_buffer_get_height(rgn_in));
             printf("perspective_lines: rgn_out width: %i rgn_out height: %i \n",gegl_buffer_get_width(rgn_out),gegl_buffer_get_height(rgn_out));
             printf("perspective_lines: x2: %i y2: %i  drawable_bpp: %i \n",x2,y2,channels);
      //       printf("perspective_lines: rgn_in bpp: %i rgn_out bpp: %i \n",gimp_buffer_get_bytes(rgn_in), gimp_buffer_get_bytes(rgn_out));
               //  return ;


             printf("perspective_lines: start plotting\n");
            /*-------------------------------------------------------------------------------------------------------------
              -                                              Drawing the horizon lines with a 7 degree angle              -
              -------------------------------------------------------------------------------------------------------------*/

             for(j = y1; j < y2; j = j+new_line_distance)//go through y-positions
             {
                  for (i = x1; i < x2; ++i)//go through x-positions
                  {
                      printf("perspective_lines: start calculating rectangle\n");
                      xp_out = round(i * aspect_ratio);


                      hypo_length = round(i / sin(83));
                      yp_out = j + round(hypo_length * cos(83) );
                      printf("perspective_lines: stop calculating rectangle\n");


                      xp_multi_yp = xp_out * yp_out;

                      if((xp_multi_yp < bitmap_size)&&(xp_multi_yp > -1))//check if access to pixel[] array is in size
                      {

                          if((xp_out < x2-1)&&(yp_out < y2-1))// check if xp_out and yp_out are in limits.
                          {
                              if((xp_out > 0)&&(yp_out > 0))
                              {
                                  printf("perspective_lines: setting xp_multi_yp %i\n",xp_multi_yp);
                                  //sets the pixel black and intransparent.
                                  //pixel[xp_multi_yp][0] = R,pixel[xp_multi_yp][1] = G,pixel[xp_multi_yp][2] == B,pixel[xp_multi_yp][3]= Alpha
                                  pixel[xp_multi_yp][0] = 0,pixel[xp_multi_yp][1] = 0,pixel[xp_multi_yp][2] = 0,pixel[xp_multi_yp][3] = 255;

                                  printf("perspective_lines: setting x %i and y %i pos\n",i,j);
                                  //defining a rectangular for a single pixel:
                                  pixel_to_set.x = xp_out; pixel_to_set.y = yp_out; pixel_to_set.width = 1; pixel_to_set.height = 1;

                                  //setting the pixel:
                                 // gegl_buffer_set(rgn_out,&pixel_to_set,1,format,pixel[xp_multi_yp],GEGL_AUTO_ROWSTRIDE);//setting the pixel
                                  gegl_buffer_set(rgn_out,&pixel_to_set,1,format,pixel[xp_multi_yp],GEGL_AUTO_ROWSTRIDE);

                              }
                          }


                       }
                  }// end loop for x-positions











                  if (j % 10 == 0)
                  {
                  gimp_progress_update ((gdouble) (j - y1) / (gdouble) (y2 - y1));
                  }


             }

             printf("perspective_lines: start with y columns\n");
             /*------------------------------------------------------------------------------------------------------------------------
              * -                                              Drawing the vertical lines with a 42 degree angle                        -
             --------------------------------------------------------------------------------------------------------------------------*/

             for(i = x1; i < x2;i = i + new_column_distance)//go through x-positions
             {
                  for (j = y1; j < y2; j = ++j)//go through y-positions
                  {
                      printf("perspective_lines: start calculating rectangle\n");
                      yp_out = j;

                      hypo_length = round(j / cos(48));
                      xp_out = i - round(hypo_length * sin(48)) ;
                      printf("perspective_lines: stop calculating rectangle\n");


                      xp_multi_yp = xp_out * yp_out;

                      if((xp_multi_yp < bitmap_size)&&(xp_multi_yp > -1))
                      {

                          if((xp_out < x2-1)&&(yp_out < y2-1))
                          {
                              if((xp_out > 0)&&(yp_out > 0))
                              {
                                  printf("perspective_lines: setting xp_multi_yp %i\n",xp_multi_yp);
                                  //sets the pixel black and intransparent.
                                  //pixel[xp_multi_yp][0] = R,pixel[xp_multi_yp][1] = G,pixel[xp_multi_yp][2] = B,pixel[xp_multi_yp][3]= Alpha
                                  pixel[xp_multi_yp][0] = 0,pixel[xp_multi_yp][1] = 0,pixel[xp_multi_yp][2] = 0,pixel[xp_multi_yp][3] = 255;


                                  printf("perspective_lines: setting x %i and y %i pos\n",i,j);



                                  pixel_to_set.x = xp_out; pixel_to_set.y = yp_out; pixel_to_set.width = 1; pixel_to_set.height = 1;
                                  //gegl_buffer_set(rgn_out,&pixel_to_set,1,format,pixel[xp_multi_yp],GEGL_AUTO_ROWSTRIDE);
                                  gegl_buffer_set(rgn_out,&pixel_to_set,1,format,pixel[xp_multi_yp],GEGL_AUTO_ROWSTRIDE);


                              }
                          }
                      }
                    }


                  //printf("perspective_lines: new_line_distance is: %i \n",new_line_distance);


                  if (i % 10 == 0)
                  {
                  gimp_progress_update ((gdouble) (j - y1) / (gdouble) (y2 - y1));
                  }


             }









             /* Update the modified region */
               //gimp_drawable_flush (drawable);
            //   gegl_buffer_flush(rgn_out);

             //Writing the shadow buffer to disc for debugging reason's
             GeglRectangle buffer_save_rect;
             buffer_save_rect.x = x1;buffer_save_rect.y = y1; buffer_save_rect.width = x2; buffer_save_rect.height = y2;
             printf("perspective_lines: Try to save buffer\n");
             gegl_buffer_save(rgn_out,"/home/david/rgn_out_buffer.txt",&buffer_save_rect);


             /*******************************************************************************************************
               *                                     The main problem   !!!!                                        *
               ******************************************************************************************************/
               // It seems that gimp_drawable_merge_shadow command doesn't do it's job without error-message !
               // if I investigate the data which I saved with gegl_buffer_save command above than it seems that
               //   the pixel data is stored correctly into the buffer rgn_out.
               // But it is not updated to the core !
               /* The facts:
                * rgn_out contains the wished result.
                * After deployment of the plugin: The source image becomes completly transparent. There are no intransparent pixel lines
                * If I export it as a bmp file,the bmp file is after the header completly empty !!!
                *
               */




               printf("perspective_lines: pixel count rgn_out: %i \n",gegl_buffer_get_pixel_count(rgn_out));

               g_object_unref(rgn_in);
               g_object_unref(rgn_out);
               if(gimp_drawable_merge_shadow (drawable_id, TRUE)== FALSE)
               {
                   printf("perspective_lines: gimp_drawable_merge_shadow failed \n ");
                   return FALSE;
               }



               if(gimp_drawable_update (drawable_id,
                                     x1, y1,
                                     x2 - x1, y2 - y1)==FALSE)
               {
                    printf("perspective_lines: gimp_drawable_update failed \n ");
                    return FALSE;
               }
                   //gimp_drawable_detach()???
               gimp_displays_flush ();
               gimp_drawable_detach (drawable);

               printf("perspective_lines: perpespective lines finished\n");


             return TRUE;



}
_______________________________________________
gimp-developer-list mailing list
List address:    gimp-developer-list@xxxxxxxxx
List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
List archives:   https://mail.gnome.org/archives/gimp-developer-list



[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux