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

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * gimplut.c: Copyright (C) 1999 Jay Cox <jaycox@earthlink.net>
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19.  */
  20.  
  21. #include "config.h"
  22.  
  23. #include <stdio.h>
  24.  
  25. #include <gtk/gtk.h>
  26.  
  27. #include "apptypes.h"
  28.  
  29. #include "gimplutP.h"
  30. #include "gimplut.h"
  31.  
  32.  
  33. GimpLut *
  34. gimp_lut_new ()
  35. {
  36.  GimpLut *lut;
  37.  lut = g_new(GimpLut, 1);
  38.  lut->luts = NULL;
  39.  lut->nchannels = 0;
  40.  return lut;
  41. }
  42.  
  43. void
  44. gimp_lut_free (GimpLut *lut)
  45. {
  46.   int i;
  47.   for (i = 0; i < lut->nchannels; i++)
  48.     g_free(lut->luts[i]);
  49.   if (lut->luts)
  50.     g_free(lut->luts);
  51. }
  52.  
  53. void
  54. gimp_lut_setup (GimpLut     *lut, 
  55.         GimpLutFunc  func,
  56.         void        *user_data, 
  57.         int          nchannels)
  58. {
  59.   int i, v;
  60.   double val;
  61.   if (lut->luts)
  62.   {
  63.     for (i = 0; i < lut->nchannels; i++)
  64.       g_free(lut->luts[i]);
  65.     g_free(lut->luts);
  66.   }
  67.   lut->nchannels = nchannels;
  68.   lut->luts = g_new(unsigned char*, lut->nchannels);
  69.   for (i = 0; i < lut->nchannels; i++)
  70.   {
  71.     lut->luts[i] = g_new(unsigned char, 256);
  72.     for (v = 0; v < 256; v++)
  73.     { /* to add gamma correction use func(v ^ g) ^ 1/g instead. */
  74.       val = 255.0 * func(user_data, lut->nchannels, i, v/255.0) + 0.5;
  75.       if (val < 0.0)
  76.     lut->luts[i][v] = 0;
  77.       else if (val >= 255.0)
  78.     lut->luts[i][v] = 255;
  79.       else
  80.     lut->luts[i][v] = val;
  81.     }
  82.   }
  83. }
  84.  
  85. void
  86. gimp_lut_setup_exact (GimpLut     *lut, 
  87.               GimpLutFunc  func,
  88.               void        *user_data, 
  89.               int          nchannels)
  90. {
  91.   gimp_lut_setup(lut, func, user_data, nchannels);
  92. }
  93.  
  94. void
  95. gimp_lut_process (GimpLut     *lut,
  96.           PixelRegion *srcPR,
  97.           PixelRegion *destPR)
  98. {
  99.   int h, width, src_r_i, dest_r_i;
  100.   unsigned char *src, *dest;
  101.   unsigned char *lut0 = NULL, *lut1 = NULL, *lut2 = NULL, *lut3 = NULL;
  102.  
  103.   if (lut->nchannels > 0)
  104.     lut0 = lut->luts[0];
  105.   if (lut->nchannels > 1)
  106.     lut1 = lut->luts[1];
  107.   if (lut->nchannels > 2)
  108.     lut2 = lut->luts[2];
  109.   if (lut->nchannels > 3)
  110.     lut3 = lut->luts[3];
  111.  
  112.   h = srcPR->h;
  113.   src  = srcPR->data;
  114.   dest = destPR->data;
  115.   width = srcPR->w;
  116.   src_r_i =  srcPR->rowstride  - (srcPR->bytes  * srcPR->w);
  117.   dest_r_i = destPR->rowstride - (destPR->bytes * srcPR->w);
  118.  
  119.   if (src_r_i == 0 && dest_r_i == 0)
  120.   {
  121.     width *= h;
  122.     h = 1;
  123.   }
  124.   while (h--)
  125.   {
  126.     switch (lut->nchannels)
  127.     {
  128.      case 1:
  129.        while (width--)
  130.        {
  131.      *dest = lut0[*src];
  132.      src++;
  133.      dest++;
  134.        }
  135.        break;
  136.      case 2:
  137.        while (width--)
  138.        {
  139.      dest[0] = lut0[src[0]];
  140.      dest[1] = lut1[src[1]];
  141.      src  += 2;
  142.      dest += 2;
  143.        }
  144.        break;
  145.      case 3:
  146.        while (width--)
  147.        {
  148.      dest[0] = lut0[src[0]];
  149.      dest[1] = lut1[src[1]];
  150.      dest[2] = lut2[src[2]];
  151.      src  += 3;
  152.      dest += 3;
  153.        }
  154.        break;
  155.      case 4:
  156.        while (width--)
  157.        {
  158.      dest[0] = lut0[src[0]];
  159.      dest[1] = lut1[src[1]];
  160.      dest[2] = lut2[src[2]];
  161.      dest[3] = lut3[src[3]];
  162.      src  += 4;
  163.      dest += 4;
  164.        }
  165.        break;
  166.      default:
  167.        fprintf(stderr, "gimplut: Error: nchannels = %d\n", lut->nchannels);
  168.     }
  169.     width = srcPR->w;
  170.     src  += src_r_i;
  171.     dest += dest_r_i;
  172.   }
  173. }
  174.  
  175. void
  176. gimp_lut_process_inline (GimpLut     *lut,
  177.              PixelRegion *srcPR)
  178. {
  179.   int h, width, src_r_i;
  180.   unsigned char *src;
  181.   unsigned char *lut0 = NULL, *lut1 = NULL, *lut2 = NULL, *lut3 = NULL;
  182.  
  183.   if (lut->nchannels > 0)
  184.     lut0 = lut->luts[0];
  185.   if (lut->nchannels > 1)
  186.     lut1 = lut->luts[1];
  187.   if (lut->nchannels > 2)
  188.     lut2 = lut->luts[2];
  189.   if (lut->nchannels > 3)
  190.     lut3 = lut->luts[3];
  191.  
  192.   h = srcPR->h;
  193.   src  = srcPR->data;
  194.   width = srcPR->w;
  195.   src_r_i =  srcPR->rowstride  - (srcPR->bytes  * srcPR->w);
  196.  
  197.   if (src_r_i == 0)
  198.   {
  199.     width *= h;
  200.     h = 1;
  201.   }
  202.   while (h--)
  203.   {
  204.     switch (lut->nchannels)
  205.     {
  206.      case 1:
  207.        while (width--)
  208.        {
  209.      *src = lut0[*src];
  210.      src++;
  211.        }
  212.        break;
  213.      case 2:
  214.        while (width--)
  215.        {
  216.      src[0] = lut0[src[0]];
  217.      src[1] = lut1[src[1]];
  218.      src  += 2;
  219.        }
  220.        break;
  221.      case 3:
  222.        while (width--)
  223.        {
  224.      src[0] = lut0[src[0]];
  225.      src[1] = lut1[src[1]];
  226.      src[2] = lut2[src[2]];
  227.      src  += 3;
  228.        }
  229.        break;
  230.      case 4:
  231.        while (width--)
  232.        {
  233.      src[0] = lut0[src[0]];
  234.      src[1] = lut1[src[1]];
  235.      src[2] = lut2[src[2]];
  236.      src[3] = lut3[src[3]];
  237.      src  += 4;
  238.        }
  239.        break;
  240.      default:
  241.        fprintf(stderr, "gimplut: Error: nchannels = %d\n", lut->nchannels);
  242.     }
  243.     width = srcPR->w;
  244.     src  += src_r_i;
  245.   }
  246. }
  247.  
  248. void
  249. gimp_lut_process_2 (PixelRegion *srcPR,
  250.             PixelRegion *destPR,
  251.             GimpLut     *lut)
  252. {
  253.   gimp_lut_process(lut, srcPR, destPR);
  254. }
  255.