1 /* equaliz0r.cpp 2 * Copyright (C) 2005 Jean-Sebastien Senecal (js@drone.ws) 3 * This file is a Frei0r plugin. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20 #include "frei0r.hpp" 21 #include "frei0r_math.h" 22 #include <string.h> 23 24 #include <cstring> 25 26 class equaliz0r : public frei0r::filter 27 { 28 // Look-up tables for equaliz0r values. 29 unsigned char rlut[256]; 30 unsigned char glut[256]; 31 unsigned char blut[256]; 32 33 // Intensity histograms. 34 unsigned int rhist[256]; 35 unsigned int ghist[256]; 36 unsigned int bhist[256]; 37 updateLookUpTables(const uint32_t * in)38 void updateLookUpTables(const uint32_t* in) 39 { 40 unsigned int size = width*height; 41 42 // First pass : build histograms. 43 44 // Reset histograms. 45 memset(rhist, 0, 256*sizeof(unsigned int)); 46 memset(ghist, 0, 256*sizeof(unsigned int)); 47 memset(bhist, 0, 256*sizeof(unsigned int)); 48 49 // Update histograms. 50 const unsigned char *in_ptr = (const unsigned char*) in; 51 for (unsigned int i=0; i<size; ++i) 52 { 53 // update 'em 54 rhist[*in_ptr++]++; 55 ghist[*in_ptr++]++; 56 bhist[*in_ptr++]++; 57 in_ptr++; // skip alpha 58 } 59 60 // Second pass : update look-up tables. 61 in_ptr = (const unsigned char*) in; 62 63 // Cumulative intensities of histograms. 64 unsigned int 65 rcum = 0, 66 gcum = 0, 67 bcum = 0; 68 69 for (int i=0; i<256; ++i) 70 { 71 // update cumulatives 72 rcum += rhist[i]; 73 gcum += ghist[i]; 74 bcum += bhist[i]; 75 76 // update 'em 77 rlut[i] = CLAMP0255( (rcum << 8) / size ); // = 256 * rcum / size 78 glut[i] = CLAMP0255( (gcum << 8) / size ); // = 256 * gcum / size 79 blut[i] = CLAMP0255( (bcum << 8) / size ); // = 256 * bcum / size 80 81 in_ptr++; // skip alpha 82 } 83 84 } 85 86 public: equaliz0r(unsigned int width,unsigned int height)87 equaliz0r(unsigned int width, unsigned int height) 88 { 89 } 90 update(double time,uint32_t * out,const uint32_t * in)91 virtual void update(double time, 92 uint32_t* out, 93 const uint32_t* in) 94 { 95 std::copy(in, in + width*height, out); 96 updateLookUpTables(in); 97 unsigned int size = width*height; 98 const unsigned char *in_ptr = (const unsigned char*) in; 99 unsigned char *out_ptr = (unsigned char*) out; 100 for (unsigned int i=0; i<size; ++i) 101 { 102 *out_ptr++ = rlut[*in_ptr++]; 103 *out_ptr++ = glut[*in_ptr++]; 104 *out_ptr++ = blut[*in_ptr++]; 105 *out_ptr++ = *in_ptr++; // copy alpha 106 } 107 } 108 }; 109 110 111 frei0r::construct<equaliz0r> plugin("Equaliz0r", 112 "Equalizes the intensity histograms", 113 "Jean-Sebastien Senecal (Drone)", 114 0,2, 115 F0R_COLOR_MODEL_RGBA8888); 116 117