// 矩形を塗りつぶす static void fill_rect16(struct GBUFFER *self, int x, int y, int w, int h, COLOR32 color) { if (w == 0 && h == 0) { w = self->w; h = self->h; } x = MAXMIN(0, x, self->w - 1); y = MAXMIN(0, y, self->h - 1); int max_w = self->w - x; int max_h = self->h - y; w = MAXMIN(0, w, max_w); h = MAXMIN(0, h, max_h); COLOR16 *buf = (COLOR16 *) self->buf; buf = &buf[y * self->w + x]; COLOR16 *buf1 = buf; // 1行目 COLOR16 col = RGB32_TO_16(color); /* 1行目を塗りつぶす */ for (int px = 0; px < w; px++) { buf1[px] = col; } buf += self->w; /* 2行目以降は1行目のコピー */ for (int line = 1; line < h; line++) { memcpy(buf, buf1, w * sizeof (COLOR16)); buf += self->w; } }
static void blit16(struct GBUFFER *self, int src_x, int src_y, int w, int h, struct GBUFFER *dst, int dst_x, int dst_y, int op) { // ---- 範囲チェック&修正 int src_max_w = self->w - src_x; int src_max_h = self->h - src_y; int dst_max_w = dst->w - dst_x; int dst_max_h = dst->h - dst_y; src_x = MAXMIN(0, src_x, self->w - 1); src_y = MAXMIN(0, src_y, self->h - 1); dst_x = MAXMIN(0, dst_x, dst->w - 1); dst_y = MAXMIN(0, dst_y, dst->h - 1); if (self == dst && src_x == dst_x && src_y == dst_y) { return; } w = MIN(w, MIN(src_max_w, dst_max_w)); h = MIN(h, MIN(src_max_h, dst_max_h)); // ---- 本体 switch (op) { case OP_SRC_COPY: blit_src_copy16(self, src_x, src_y, w, h, dst, dst_x, dst_y); break; case OP_SRC_INVERT: blit_src_invert16(self, src_x, src_y, w, h, dst, dst_x, dst_y); break; } }
// Red, Green and Blue are between 0 and 255 // Hue varies between 0 and 360 // Satuation between 0 and 1 // Value between 0 and 1 int DLL_CALLCONV FIA_RGBToHSV (unsigned char red, unsigned char green, unsigned char blue, double *hue, double *satuation, double *value) { unsigned char max, min, rgb[3]; *hue = 0; *satuation = 0; *value = 0; rgb[0] = red, rgb[1] = green, rgb[2] = blue; MAXMIN (rgb, 3, max, min); if (max != min) { if (red == max) { *hue = ((double) (green - blue) / (max - min)) * 60.0; } if (green == max) { *hue = (2 + (double) (blue - red) / (max - min)) * 60.0; } if (blue == max) { *hue = (4 + (double) (red - green) / (max - min)) * 60.0; } } *value = (double) max / 255.0; if (max != 0) { *satuation = ((double) (max - min) / max); } return FIA_SUCCESS; }
// Red, Green and Blue are between 0 and 255 // Hue varies between 0 and 360 // Satuation between 0 and 1 // Value between 0 and 1 int DLL_CALLCONV FIA_RGBToHSL (unsigned char red, unsigned char green, unsigned char blue, double *hue, double *satuation, double *luminosity) { unsigned char max, min, rgb[3]; *hue = 0; *satuation = 0; *luminosity = 0; rgb[0] = red, rgb[1] = green, rgb[2] = blue; MAXMIN (rgb, 3, max, min); if (max != min) { if (red == max) *hue = ((double) (green - blue) / (max - min)) * 60.0; if (green == max) *hue = (2 + (double) (blue - red) / (max - min)) * 60.0; if (blue == max) *hue = (4 + (double) (red - green) / (max - min)) * 60.0; } *luminosity = (double) (max + min) / (510.0); if (*luminosity < 0.5) { *satuation = ((double) (max - min) / (510.0 * *luminosity)); } else { *satuation = ((double) (max - min) / (510.0 * (2 - (2 * *luminosity)))); } return FIA_SUCCESS; }
template<class Tsrc> FIBITMAP* CONVERT_TO_BYTE<Tsrc>::convert(FIBITMAP *src, BOOL scale_linear) { FIBITMAP *dst = NULL; unsigned x, y; unsigned width = FreeImage_GetWidth(src); unsigned height = FreeImage_GetHeight(src); // allocate a 8-bit dib dst = FreeImage_AllocateT(FIT_BITMAP, width, height, 8, 0, 0, 0); if(!dst) return NULL; // build a greyscale palette RGBQUAD *pal = FreeImage_GetPalette(dst); for(int i = 0; i < 256; i++) { pal[i].rgbRed = (BYTE)i; pal[i].rgbGreen = (BYTE)i; pal[i].rgbBlue = (BYTE)i; } // convert the src image to dst // (FIBITMAP are stored upside down) if(scale_linear) { Tsrc max, min; double scale; // find the min and max value of the image Tsrc l_min, l_max; min = 255, max = 0; for(y = 0; y < height; y++) { Tsrc *bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y)); MAXMIN(bits, width, l_max, l_min); if(l_max > max) max = l_max; if(l_min < min) min = l_min; } if(max == min) { max = 255; min = 0; } // compute the scaling factor scale = 255 / (double)(max - min); // scale to 8-bit for(y = 0; y < height; y++) { Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y)); BYTE *dst_bits = FreeImage_GetScanLine(dst, y); for(x = 0; x < width; x++) { dst_bits[x] = (BYTE)( scale * (src_bits[x] - min) + 0.5); } } } else { for(y = 0; y < height; y++) { Tsrc *src_bits = reinterpret_cast<Tsrc*>(FreeImage_GetScanLine(src, y)); BYTE *dst_bits = FreeImage_GetScanLine(dst, y); for(x = 0; x < width; x++) { // rounding int q = int(src_bits[x] + 0.5); dst_bits[x] = (BYTE) MIN(255, MAX(0, q)); } } } return dst; }