static RGBSpectrum *ReadImageTGA(const std::string &name, int *width, int *height) { tga_image img; tga_result result; if ((result = tga_read(&img, name.c_str())) != TGA_NOERR) { Error("Unable to read from TGA file \"%s\" (%s)", name.c_str(), tga_error(result)); return nullptr; } if (tga_is_right_to_left(&img)) tga_flip_horiz(&img); if (!tga_is_top_to_bottom(&img)) tga_flip_vert(&img); if (tga_is_colormapped(&img)) tga_color_unmap(&img); *width = img.width; *height = img.height; // "Unpack" the pixels (origin in the lower left corner). // TGA pixels are in BGRA format. RGBSpectrum *ret = new RGBSpectrum[*width * *height]; RGBSpectrum *dst = ret; for (int y = *height - 1; y >= 0; y--) for (int x = 0; x < *width; x++) { uint8_t *src = tga_find_pixel(&img, x, y); if (tga_is_mono(&img)) *dst++ = RGBSpectrum(*src / 255.f); else { Float c[3]; c[2] = src[0] / 255.f; c[1] = src[1] / 255.f; c[0] = src[2] / 255.f; *dst++ = RGBSpectrum::FromRGB(c); } } tga_free_buffers(&img); Info("Read TGA image %s (%d x %d)", name.c_str(), *width, *height); return ret; }
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; }