⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fl_draw_image.cxx

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//// "$Id: fl_draw_image.cxx,v 1.1.1.1 2003/08/07 21:18:41 jasonk Exp $"//// Image drawing routines for the Fast Light Tool Kit (FLTK).//// Copyright 1998-1999 by Bill Spitzak and others.//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA.//// Please report all bugs and problems to "fltk-bugs@easysw.com".//// I hope a simple and portable method of drawing color and monochrome// images.  To keep this simple, only a single storage type is// supported: 8 bit unsigned data, byte order RGB, and pixels are// stored packed into rows with the origin at the top-left.  It is// possible to alter the size of pixels with the "delta" argument, to// add alpha or other information per pixel.  It is also possible to// change the origin and direction of the image data by messing with// the "delta" and "linedelta", making them negative, though this may// defeat some of the shortcuts in translating the image for X.#ifdef WIN32#include "fl_draw_image_win32.cxx"#else// A list of assumptions made about the X display:// bits_per_pixel must be one of 8, 16, 24, 32.// scanline_pad must be a power of 2 and greater or equal to 8.// PsuedoColor visuals must have 8 bits_per_pixel (although the depth// may be less than 8).  This is the only limitation that affects any// modern X displays, you can't use 12 or 16 bit colormaps.// The mask bits in TrueColor visuals for each color are// contiguous and have at least one bit of each color.  This// is not checked for.// For 24 and 32 bit visuals there must be at least 8 bits of each color.////////////////////////////////////////////////////////////////#include <FL/Fl.H>#include <FL/fl_draw.H>#include <FL/x.H>#include "Fl_XColor.H"#include <string.h>#ifndef NANO_X //tanghaostatic XImage i;	// template used to pass info to Xstatic int bytes_per_pixel;static int scanline_add;static int scanline_mask;static void (*converter)(const uchar *from, uchar *to, int w, int delta);static void (*mono_converter)(const uchar *from, uchar *to, int w, int delta);static int dir;		// direction-alternatorstatic int ri,gi,bi;	// saved error-diffusion value#if USE_COLORMAP////////////////////////////////////////////////////////////////// 8-bit converter with error diffusion// I make a 16x16x16 cube of the closest colors in the fltk colormap// we could allocate to each of the colors in a 4-bit image.  This is// then used to find the pixel values and actual colors for error diffusion.static uchar cube[16*16*16];// calculate sum-of-squares error between 4-bit index and pixel colors:static int calc_error(int r, int g, int b, int i) {  int t; int s;  t = ((r<<4)+8)-fl_xmap[0][i].r; s = t*t;  t = ((g<<4)+8)-fl_xmap[0][i].g; s += t*t;  t = ((b<<4)+8)-fl_xmap[0][i].b; s += t*t;  return s;}// replace the color stored at a location with a better one:static void improve(uchar *p, int& e, int r, int g, int b, int i) {  if (i < FL_GRAY_RAMP || i > 255) return;  int e1 = calc_error(r,g,b,i);  if (e1 < e) {*p = i; e = e1;}}static int filled_color_cube;static void fill_color_cube() {  filled_color_cube = 1;  int i;  // allocate all the colors in the fltk color cube and gray ramp:  // allocate widely seperated values first so that the bad ones are  // distributed evenly through the colormap:  for (i=0;;) {    fl_xpixel((Fl_Color)(i+FL_COLOR_CUBE));    i = (i+109)%(FL_NUM_RED*FL_NUM_GREEN*FL_NUM_BLUE); if (!i) break;  }  for (i=0;;) {    fl_xpixel((Fl_Color)(i+FL_GRAY_RAMP));    i = (i+7)%FL_NUM_GRAY; if (!i) break;  }  // fill in the 16x16x16 cube:  uchar *p = cube;  for (int r = 0; r<16; r++) {    for (int g = 0; g<16; g++) {      for (int b = 0; b<16; b++, p++) {	// initial try is value from color cube:	Fl_Color i = fl_color_cube(r*FL_NUM_RED/16, g*FL_NUM_GREEN/16,				   b*FL_NUM_BLUE/16);	int e = calc_error(r,g,b,i);	*p = uchar(i);	// try neighbor pixels in the cube to see if they are better:	improve(p,e,r,g,b,i+FL_NUM_RED*FL_NUM_GREEN);	improve(p,e,r,g,b,i-FL_NUM_RED*FL_NUM_GREEN);	improve(p,e,r,g,b,i+FL_NUM_GREEN);	improve(p,e,r,g,b,i-FL_NUM_GREEN);	improve(p,e,r,g,b,i+1);	improve(p,e,r,g,b,i-1);	// try the gray ramp:	i = fl_gray_ramp(g*FL_NUM_GRAY/15);	improve(p,e,r,g,b,i);	improve(p,e,r,g,b,i+1);	improve(p,e,r,g,b,i-1);      }    }  }}static void color8_converter(const uchar *from, uchar *to, int w, int delta) {  if (!filled_color_cube) fill_color_cube();  int r=ri, g=gi, b=bi;  int d, td;  if (dir) {    dir = 0;    from = from+(w-1)*delta;    to = to+(w-1);    d = -delta;    td = -1;  } else {    dir = 1;    d = delta;    td = 1;  }  for (; w--; from += d, to += td) {    r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;    g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255;    b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255;    Fl_XColor* x = fl_xmap[0] + cube[((r<<4)&0xf00)+(g&0xf0)+(b>>4)];    r -= x->r;    g -= x->g;    b -= x->b;    *to = uchar(x->pixel);  }  ri = r; gi = g; bi = b;}static void mono8_converter(const uchar *from, uchar *to, int w, int delta) {  if (!filled_color_cube) fill_color_cube();  int r=ri;  int d, td;  if (dir) {    dir = 0;    from = from+(w-1)*delta;    to = to+(w-1);    d = -delta;    td = -1;  } else {    dir = 1;    d = delta;    td = 1;  }  for (; w--; from += d, to += td) {    r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;    Fl_XColor* x = fl_xmap[0] + cube[(r>>4)*0x111];    r -= x->g;    *to = uchar(x->pixel);  }  ri = r;}#endif////////////////////////////////////////////////////////////////// 16 bit TrueColor converters with error diffusion// Cray computers have no 16-bit type, so we use character pointers// (which may be slow)#ifdef U16#define OUTTYPE U16#define OUTSIZE 1#define OUTASSIGN(v) *t = v#else#define OUTTYPE uchar#define OUTSIZE 2#define OUTASSIGN(v) int tt=v; t[0] = uchar(tt>>8); t[1] = uchar(tt)#endifstatic void color16_converter(const uchar *from, uchar *to, int w, int delta) {  OUTTYPE *t = (OUTTYPE *)to;  int d, td;  if (dir) {    dir = 0;    from = from+(w-1)*delta;    t = t+(w-1)*OUTSIZE;    d = -delta;    td = -OUTSIZE;  } else {    dir = 1;    d = delta;    td = OUTSIZE;  }  int r=ri, g=gi, b=bi;  for (; w--; from += d, t += td) {    r = (r&~fl_redmask)  +from[0]; if (r>255) r = 255;    g = (g&~fl_greenmask)+from[1]; if (g>255) g = 255;    b = (b&~fl_bluemask) +from[2]; if (b>255) b = 255;    OUTASSIGN((      ((r&fl_redmask)<<fl_redshift)+      ((g&fl_greenmask)<<fl_greenshift)+      ((b&fl_bluemask)<<fl_blueshift)      ) >> fl_extrashift);  }  ri = r; gi = g; bi = b;}static void mono16_converter(const uchar *from,uchar *to,int w, int delta) {  OUTTYPE *t = (OUTTYPE *)to;  int d, td;  if (dir) {    dir = 0;    from = from+(w-1)*delta;    t = t+(w-1)*OUTSIZE;    d = -delta;    td = -OUTSIZE;  } else {    dir = 1;    d = delta;    td = OUTSIZE;  }  uchar mask = fl_redmask & fl_greenmask & fl_bluemask;  int r=ri;  for (; w--; from += d, t += td) {    r = (r&~mask) + *from; if (r > 255) r = 255;    uchar m = r&mask;    OUTASSIGN((      (m<<fl_redshift)+      (m<<fl_greenshift)+      (m<<fl_blueshift)      ) >> fl_extrashift);  }  ri = r;}// special-case the 5r6g5b layout used by XFree86:static void c565_converter(const uchar *from, uchar *to, int w, int delta) {  OUTTYPE *t = (OUTTYPE *)to;  int d, td;  if (dir) {    dir = 0;    from = from+(w-1)*delta;    t = t+(w-1)*OUTSIZE;    d = -delta;    td = -OUTSIZE;  } else {    dir = 1;    d = delta;    td = OUTSIZE;  }  int r=ri, g=gi, b=bi;  for (; w--; from += d, t += td) {    r = (r&7)+from[0]; if (r>255) r = 255;    g = (g&3)+from[1]; if (g>255) g = 255;    b = (b&7)+from[2]; if (b>255) b = 255;    OUTASSIGN(((r&0xf8)<<8) + ((g&0xfc)<<3) + (b>>3));  }  ri = r; gi = g; bi = b;}static void m565_converter(const uchar *from,uchar *to,int w, int delta) {  OUTTYPE *t = (OUTTYPE *)to;  int d, td;  if (dir) {    dir = 0;    from = from+(w-1)*delta;    t = t+(w-1)*OUTSIZE;    d = -delta;    td = -OUTSIZE;  } else {    dir = 1;    d = delta;    td = OUTSIZE;  }  int r=ri;  for (; w--; from += d, t += td) {    r = (r&7) + *from; if (r > 255) r = 255;    OUTASSIGN((r>>3) * 0x841);  }  ri = r;}////////////////////////////////////////////////////////////////// 24bit TrueColor converters:static void rgb_converter(const uchar *from, uchar *to, int w, int delta) {  int d = delta-3;  for (; w--; from += d) {    *to++ = *from++;    *to++ = *from++;    *to++ = *from++;  }}static void bgr_converter(const uchar *from, uchar *to, int w, int delta) {  for (; w--; from += delta) {    uchar r = from[0];    uchar g = from[1];    *to++ = from[2];    *to++ = g;    *to++ = r;  }}static void rrr_converter(const uchar *from, uchar *to, int w, int delta) {  for (; w--; from += delta) {    *to++ = *from;    *to++ = *from;    *to++ = *from;  }}////////////////////////////////////////////////////////////////// 32bit TrueColor converters on a 32 or 64-bit machine:#ifdef U64#define STORETYPE U64#if WORDS_BIGENDIAN#define INNARDS32(f) \  U64 *t = (U64*)to; \  int w1 = (w+1)/2; \  for (; w1--; from += delta) {U64 i = f; from += delta; *t++ = (i<<32)|(f);}#else#define INNARDS32(f) \  U64 *t = (U64*)to; \  int w1 = (w+1)/2; \  for (; w1--; from += delta) {U64 i=f; from+= delta; *t++ = ((U64)(f)<<32)|i;}#endif#else#define STORETYPE U32#define INNARDS32(f)   U32 *t = (U32*)to; for(; w--; from += delta) *t++ = f;#endifstatic void rgbx_converter(const uchar *from, uchar *to, int w, int delta) {  INNARDS32((unsigned(from[0])<<24)+(from[1]<<16)+(from[2]<<8));}static void xbgr_converter(const uchar *from, uchar *to, int w, int delta) {  INNARDS32((from[0])+(from[1]<<8)+(from[2]<<16));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -