home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / modules / cdisplay_highcontrast.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-17  |  9.2 KB  |  366 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1999 Manish Singh <yosh@gimp.org>
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18. #include "config.h"
  19.  
  20. #include <string.h>
  21.  
  22. #include <gtk/gtk.h>
  23.  
  24. #include "app/dialog_handler.h"
  25.  
  26. #include "gimpmodregister.h"
  27.  
  28. #include <libgimp/gimpcolordisplay.h>
  29. #include <libgimp/gimpmodule.h>
  30. #include <libgimp/gimpparasite.h>
  31. #include <libgimp/gimpui.h>
  32. #include <libgimp/gimpmath.h>
  33.  
  34. #include "libgimp/gimpintl.h"
  35.  
  36.  
  37. #define COLOR_DISPLAY_NAME _("High Contrast")
  38.  
  39. typedef struct _ContrastContext ContrastContext;
  40.  
  41. struct _ContrastContext
  42. {
  43.   GFunc    ok_func;
  44.   gpointer ok_data;
  45.   GFunc    cancel_func;
  46.   gpointer cancel_data;
  47.  
  48.   gdouble  contrast;
  49.   guchar  *lookup;
  50.  
  51.   GtkWidget *shell;
  52.   GtkWidget *spinner;
  53. };
  54.  
  55. static gpointer       contrast_new                   (gint             type);
  56. static gpointer       contrast_clone                 (gpointer         cd_ID);
  57. static void           contrast_create_lookup_table   (ContrastContext *context);
  58. static void           contrast_destroy               (gpointer         cd_ID);
  59. static void           contrast_convert               (gpointer         cd_ID,
  60.                               guchar          *buf,
  61.                               gint             w,
  62.                               gint             h,
  63.                               gint             bpp,
  64.                               gint             bpl);
  65. static void           contrast_load                  (gpointer         cd_ID,
  66.                               GimpParasite    *state);
  67. static GimpParasite * contrast_save                  (gpointer         cd_ID);
  68. static void           contrast_configure_ok_callback (GtkWidget       *widget,
  69.                               gpointer         data);
  70. static void       contrast_configure_cancel_callback (GtkWidget       *widget,
  71.                               gpointer         data);
  72. static void           contrast_configure             (gpointer         cd_ID,
  73.                               GFunc            ok_func,
  74.                               gpointer         ok_data,
  75.                               GFunc            cancel_func,
  76.                               gpointer         cancel_data);
  77. static void           contrast_configure_cancel      (gpointer         cd_ID);
  78.  
  79. static GimpColorDisplayMethods methods = 
  80. {
  81.   NULL,
  82.   contrast_new,
  83.   contrast_clone,
  84.   contrast_convert,
  85.   contrast_destroy,
  86.   NULL,
  87.   contrast_load,
  88.   contrast_save,
  89.   contrast_configure,
  90.   contrast_configure_cancel
  91. };
  92.  
  93. static GimpModuleInfo info = 
  94. {
  95.   NULL,
  96.   N_("High Contrast color display filter"),
  97.   "Jay Cox <jaycox@earthlink.net>",
  98.   "v0.2",
  99.   "(c) 2000, released under the GPL",
  100.   "October 14, 2000"
  101. };
  102.  
  103. G_MODULE_EXPORT GimpModuleStatus
  104. module_init (GimpModuleInfo **inforet)
  105. {
  106. #ifndef __EMX__
  107.   if (gimp_color_display_register (COLOR_DISPLAY_NAME, &methods))
  108. #else
  109.   if (mod_color_display_register (COLOR_DISPLAY_NAME, &methods))
  110. #endif
  111.     {
  112.       *inforet = &info;
  113.       return GIMP_MODULE_OK;
  114.     }
  115.   else
  116.     return GIMP_MODULE_UNLOAD;
  117. }
  118.  
  119. G_MODULE_EXPORT void
  120. module_unload (void  *shutdown_data,
  121.            void (*completed_cb) (void *),
  122.            void  *completed_data)
  123. {
  124. #ifndef __EMX__
  125.   gimp_color_display_unregister (COLOR_DISPLAY_NAME);
  126. #else
  127.   mod_color_display_unregister (COLOR_DISPLAY_NAME);
  128. #endif
  129. }
  130.  
  131.  
  132. static gpointer
  133. contrast_new (gint type)
  134. {
  135.   ContrastContext *context;
  136.  
  137.   context = g_new0 (ContrastContext, 1);
  138.   context->contrast = 4.0;
  139.   context->lookup = g_new (guchar, 256);
  140.  
  141.   contrast_create_lookup_table (context);
  142.  
  143.   return context;
  144. }
  145.  
  146. static gpointer
  147. contrast_clone (gpointer cd_ID)
  148. {
  149.   ContrastContext *src_context = cd_ID;
  150.   ContrastContext *context;
  151.  
  152.   context = contrast_new (0);
  153.   context->contrast = src_context->contrast;
  154.   
  155.   memcpy (context->lookup, src_context->lookup, sizeof (guchar) * 256);
  156.  
  157.   return context;
  158. }
  159.  
  160. static void
  161. contrast_create_lookup_table (ContrastContext *context)
  162. {
  163.   gint i;
  164.  
  165.   if (context->contrast == 0.0)
  166.     context->contrast = 1.0;
  167.  
  168.   for (i = 0; i < 256; i++)
  169.     {
  170.       context->lookup[i] 
  171.     = (guchar) (int)(255 * .5 * (1 + sin(context->contrast*2*G_PI*i/255.0)));
  172.     }
  173. }
  174.  
  175. static void
  176. contrast_destroy (gpointer cd_ID)
  177. {
  178.   ContrastContext *context = cd_ID;
  179.  
  180.   if (context->shell)
  181.     {
  182.       dialog_unregister (context->shell);
  183.       gtk_widget_destroy (context->shell);
  184.     }
  185.  
  186.   g_free (context->lookup);
  187.   g_free (context);
  188. }
  189.  
  190. static void
  191. contrast_convert (gpointer  cd_ID,
  192.           guchar   *buf,
  193.           gint      width,
  194.           gint      height,
  195.           gint      bpp,
  196.           gint      bpl)
  197. {
  198.   guchar *lookup = ((ContrastContext *) cd_ID)->lookup;
  199.   gint    i, j = height;
  200.  
  201.   /* You will not be using the entire buffer most of the time. 
  202.    * Hence, the simplistic code for this is as follows:
  203.    *
  204.    * for (j = 0; j < height; j++)
  205.    *   {
  206.    *     for (i = 0; i < width * bpp; i++)
  207.    *       buf[i] = lookup[buf[i]];
  208.    *     buf += bpl;
  209.    *   }
  210.    */
  211.  
  212.   width *= bpp;
  213.   bpl -= width;
  214.  
  215.   while (j--)
  216.     {
  217.       i = width;
  218.       while (i--)
  219.     {
  220.       *buf = lookup[*buf];
  221.       buf++;
  222.     }
  223.       buf += bpl;
  224.     }
  225. }
  226.  
  227. static void
  228. contrast_load (gpointer      cd_ID,
  229.            GimpParasite *state)
  230. {
  231.   ContrastContext *context = cd_ID;
  232.  
  233. #if G_BYTE_ORDER == G_BIG_ENDIAN
  234.   memcpy (&context->contrast, gimp_parasite_data (state), sizeof (gdouble));
  235. #else
  236.   guint32 buf[2], *data = gimp_parasite_data (state);
  237.  
  238.   buf[0] = g_ntohl (data[1]);
  239.   buf[1] = g_ntohl (data[0]);
  240.  
  241.   memcpy (&context->contrast, buf, sizeof (gdouble));
  242. #endif
  243.  
  244.   contrast_create_lookup_table (context);
  245. }
  246.  
  247. static GimpParasite *
  248. contrast_save (gpointer cd_ID)
  249. {
  250.   ContrastContext *context = cd_ID;
  251.   guint32 buf[2];
  252.  
  253.   memcpy (buf, &context->contrast, sizeof (gdouble));
  254.  
  255. #if G_BYTE_ORDER == G_LITTLE_ENDIAN
  256.   {
  257.     guint32 tmp = g_htonl (buf[0]);
  258.     buf[0] = g_htonl (buf[1]);
  259.     buf[1] = tmp;
  260.   }
  261. #endif
  262.  
  263.   return gimp_parasite_new ("Display/Contrast", GIMP_PARASITE_PERSISTENT,
  264.                 sizeof (gdouble), &buf);
  265. }
  266.  
  267. static void
  268. contrast_configure_ok_callback (GtkWidget *widget,
  269.                 gpointer   data)
  270. {
  271.   ContrastContext *context = data;
  272.  
  273.   context->contrast = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (context->spinner));
  274.   contrast_create_lookup_table (context);
  275.  
  276.   dialog_unregister (context->shell);
  277.   gtk_widget_destroy (GTK_WIDGET (context->shell));
  278.   context->shell = NULL;
  279.  
  280.   if (context->ok_func)
  281.     context->ok_func (context, context->ok_data);
  282. }
  283.  
  284. static void
  285. contrast_configure_cancel_callback (GtkWidget *widget,
  286.                     gpointer   data)
  287. {
  288.   ContrastContext *context = data;
  289.  
  290.   dialog_unregister (context->shell);
  291.   gtk_widget_destroy (GTK_WIDGET (context->shell));
  292.   context->shell = NULL;
  293.  
  294.   if (context->cancel_func)
  295.     context->cancel_func (context, context->cancel_data);
  296. }
  297.  
  298. static void
  299. contrast_configure (gpointer cd_ID,
  300.             GFunc    ok_func,
  301.             gpointer ok_data,
  302.             GFunc    cancel_func,
  303.             gpointer cancel_data)
  304. {
  305.   ContrastContext *context = cd_ID;
  306.   GtkWidget *hbox;
  307.   GtkWidget *label;
  308.   GtkObject *adjustment;
  309.  
  310.   if (!context->shell)
  311.     {
  312.       context->ok_func = ok_func;
  313.       context->ok_data = ok_data;
  314.       context->cancel_func = cancel_func;
  315.       context->cancel_data = cancel_data;
  316.  
  317.       context->shell =
  318.     gimp_dialog_new (_("High Contrast"), "high contrast",
  319.              gimp_standard_help_func, "modules/highcontrast.html",
  320.              GTK_WIN_POS_MOUSE,
  321.              FALSE, TRUE, FALSE,
  322.  
  323.              _("OK"), contrast_configure_ok_callback,
  324.              cd_ID, NULL, NULL, TRUE, FALSE,
  325.              _("Cancel"), contrast_configure_cancel_callback,
  326.              cd_ID, NULL, NULL, FALSE, TRUE,
  327.  
  328.              NULL);
  329.  
  330.       dialog_register (context->shell);
  331.  
  332.       hbox = gtk_hbox_new (FALSE, 2);
  333.       gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
  334.       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (context->shell)->vbox),
  335.               hbox, FALSE, FALSE, 0);
  336.  
  337.       label = gtk_label_new ( _("Contrast Cycles:"));
  338.       gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
  339.       gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
  340.  
  341.       adjustment = gtk_adjustment_new (context->contrast, 1.0, 20.0, 0.5, 1.0, 0.0);
  342.       context->spinner = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment),
  343.                           0.1, 3);
  344.       gtk_widget_set_usize (context->spinner, 100, 0);
  345.       gtk_box_pack_start (GTK_BOX (hbox), context->spinner, FALSE, FALSE, 0); 
  346.     }
  347.  
  348.   gtk_widget_show_all (context->shell);
  349. }
  350.  
  351. static void
  352. contrast_configure_cancel (gpointer cd_ID)
  353. {
  354.   ContrastContext *context = cd_ID;
  355.  
  356.   if (context->shell)
  357.     {
  358.       dialog_unregister (context->shell);
  359.       gtk_widget_destroy (context->shell);
  360.       context->shell = NULL;
  361.     }
  362.  
  363.   if (context->cancel_func)
  364.     context->cancel_func (context, context->cancel_data);
  365. }
  366.