bool LoadTarga( CImage32* pImage, const char* pNameFile ) { if (!(pImage && pNameFile)) { return false; } tga_image tgaImage; tga_result result = tga_read( &tgaImage, pNameFile ); if (result != TGA_NOERR) { return false; } if (tga_is_colormapped( &tgaImage )) { tga_color_unmap( &tgaImage ); } UINT width = tgaImage.width; UINT height = tgaImage.height; UINT bitsPerPixel = tgaImage.pixel_depth; pImage->Resize( width, height ); for (UINT y = 0; y < height; y ++) { for (UINT x = 0; x < width; x ++) { BYTE* pPixel = tga_find_pixel( &tgaImage, x, y ); TARGB color; if (bitsPerPixel == 8) { tga_unpack_pixel( pPixel, tgaImage.pixel_depth, &color.B, NULL, NULL, NULL ); color.G = color.R = color.B; color.A = 255; } else if (bitsPerPixel == 16 || bitsPerPixel == 24) { tga_unpack_pixel( pPixel, tgaImage.pixel_depth, &color.B, &color.G, &color.R, NULL ); color.A = 255; } else { // bitsPerPixel == 32 tga_unpack_pixel( pPixel, tgaImage.pixel_depth, &color.B, &color.G, &color.R, &color.A ); } pImage->PixelSet( x, y, color.Value ); } } tga_free_buffers( &tgaImage ); return true; }
/* --------------------------------------------------------------------------- * Swap red and blue (RGB becomes BGR and vice verse). (in-place) */ tga_result tga_swap_red_blue(tga_image *img) { uint8_t *ptr; uint8_t bpp = img->pixel_depth / 8; if (!UNMAP_DEPTH(img->pixel_depth)) return TGAERR_PIXEL_DEPTH; for (ptr = img->image_data; ptr < img->image_data + (img->width * img->height - 1) * bpp; ptr += bpp) { uint8_t r,g,b,a; (void)tga_unpack_pixel(ptr, img->pixel_depth, &b,&g,&r,&a); (void)tga_pack_pixel(ptr, img->pixel_depth, r,g,b,a); } return TGA_NOERR; }
/* --------------------------------------------------------------------------- * Desaturate the specified Targa using the specified coefficients: * output = ( red * cr + green * cg + blue * cb ) / dv */ tga_result tga_desaturate(tga_image *img, const int cr, const int cg, const int cb, const int dv) { uint8_t bpp = img->pixel_depth / 8; /* bytes per pixel */ uint8_t *dest, *src, *tmp; if (tga_is_mono(img)) return TGAERR_MONO; if (tga_is_colormapped(img)) { tga_result result = tga_color_unmap(img); if (result != TGA_NOERR) return result; } if (!UNMAP_DEPTH(img->pixel_depth)) return TGAERR_PIXEL_DEPTH; dest = img->image_data; for (src = img->image_data; src < img->image_data + img->width*img->height*bpp; src += bpp) { uint8_t b, g, r; (void)tga_unpack_pixel(src, img->pixel_depth, &b, &g, &r, NULL); *dest = (uint8_t)( ( (int)b * cb + (int)g * cg + (int)r * cr ) / dv ); dest++; } /* shrink */ tmp = (uint8_t*)realloc(img->image_data, img->width * img->height); if (tmp == NULL) return TGAERR_NO_MEM; img->image_data = (uint8_t*)tmp; img->pixel_depth = 8; img->image_type = TGA_IMAGE_TYPE_MONO; return TGA_NOERR; }
/* --------------------------------------------------------------------------- * Convert an image to the given pixel depth. (one of 32, 24, 16) Avoids * using a secondary buffer to do the conversion. */ tga_result tga_convert_depth(tga_image *img, const uint8_t bits) { size_t src_size, dest_size; uint8_t src_bpp, dest_bpp; uint8_t *src, *dest; if (!UNMAP_DEPTH(bits) || !SANE_DEPTH(img->pixel_depth) ) return TGAERR_PIXEL_DEPTH; if (tga_is_colormapped(img)) { tga_result result = tga_color_unmap(img); if (result != TGA_NOERR) return result; } if (img->pixel_depth == bits) return TGA_NOERR; /* no op, no err */ src_bpp = img->pixel_depth / 8; dest_bpp = bits / 8; src_size = (size_t)( img->width * img->height * src_bpp ); dest_size = (size_t)( img->width * img->height * dest_bpp ); if (src_size > dest_size) { void *tmp; /* convert forwards */ dest = img->image_data; for (src = img->image_data; src < img->image_data + img->width * img->height * src_bpp; src += src_bpp) { uint8_t r,g,b,a; (void)tga_unpack_pixel(src, img->pixel_depth, &r, &g, &b, &a); (void)tga_pack_pixel(dest, bits, r, g, b, a); dest += dest_bpp; } /* shrink */ tmp = realloc(img->image_data, img->width * img->height * dest_bpp); if (tmp == NULL) return TGAERR_NO_MEM; img->image_data = (uint8_t*)tmp; } else { /* expand */ void *tmp = realloc(img->image_data, img->width * img->height * dest_bpp); if (tmp == NULL) return TGAERR_NO_MEM; img->image_data = (uint8_t*) tmp; /* convert backwards */ dest = img->image_data + (img->width*img->height - 1) * dest_bpp; for (src = img->image_data + (img->width*img->height - 1) * src_bpp; src >= img->image_data; src -= src_bpp) { uint8_t r,g,b,a; (void)tga_unpack_pixel(src, img->pixel_depth, &r, &g, &b, &a); (void)tga_pack_pixel(dest, bits, r, g, b, a); dest -= dest_bpp; } } img->pixel_depth = bits; return TGA_NOERR; }
bool loadDepth(const char* pNameFile, ImageBase** ppImage) { if (!pNameFile || !ppImage || *ppImage) return false; tga_image tgaImage; tga_result result = tga_read(&tgaImage, pNameFile); if (result != TGA_NOERR) return false; if (tga_is_colormapped(&tgaImage)) { tga_color_unmap(&tgaImage); } unsigned int width = tgaImage.width; unsigned int height = tgaImage.height; unsigned int bitsPerPixel = tgaImage.pixel_depth; if (bitsPerPixel != 32) return false; // depth の最大値・最小値を取得 unsigned long minValueDepth = ULONG_MAX; unsigned long maxValueDepth = 0; for (unsigned int y = 0; y < tgaImage.height; y ++) { for (unsigned int x = 0; x < tgaImage.width; x ++) { unsigned char* pPixel = tga_find_pixel(&tgaImage, x, y); unsigned char valueR = 0, valueG = 0, valueB = 0, valueA = 0; tga_unpack_pixel(pPixel, tgaImage.pixel_depth, &valueB, &valueG, &valueR, &valueA); unsigned long valueDepth = ((unsigned int)(valueA) << 24) | ((unsigned int)(valueR) << 16) | ((unsigned int)(valueG) << 8) | (unsigned int)(valueB); if (valueDepth < minValueDepth) minValueDepth = valueDepth; if (maxValueDepth < valueDepth) maxValueDepth = valueDepth; } } // 最大値・最小値をもとに正規化 unsigned char maxValueElement = ElementUtil::getMaxValue<ImageGray8::TypeElement>(); unsigned char minValueElement = ElementUtil::getMinValue<ImageGray8::TypeElement>(); ImageGray8 *pImage = ImageFactory::createImage<ImageGray8>(tgaImage.width, tgaImage.height); for (unsigned int y = 0; y < tgaImage.height; y ++) { for (unsigned int x = 0; x < tgaImage.width; x ++) { unsigned char* pPixel = tga_find_pixel(&tgaImage, x, y); unsigned char valueR = 0, valueG = 0, valueB = 0, valueA = 0; tga_unpack_pixel(pPixel, tgaImage.pixel_depth, &valueB, &valueG, &valueR, &valueA); unsigned long valueDepth = ((unsigned int)(valueA) << 24) | ((unsigned int)(valueR) << 16) | ((unsigned int)(valueG) << 8) | (unsigned int)(valueB); unsigned char valueNormalized = cropValue<unsigned char>((unsigned char)(float(maxValueElement) * float(valueDepth - minValueDepth) / float(maxValueDepth - minValueDepth)), minValueElement, maxValueElement); unsigned char value = maxValueElement - valueNormalized; pImage->setPixel(x, y, ImageGray8::TypePixel(value)); } } tga_free_buffers(&tgaImage); *ppImage = static_cast<ImageBase*>(pImage); return pImage ? true : false; }