void load_tga(tga_image *tga, const char *fn) { DONTFAIL( tga_read(tga, fn) ); printf("Loaded %dx%dx%dbpp targa (\"%s\").\n", tga->width, tga->height, tga->pixel_depth, fn); if (!tga_is_mono(tga)) DONTFAIL( tga_desaturate_rec_601_1(tga) ); if (!tga_is_top_to_bottom(tga)) DONTFAIL( tga_flip_vert(tga) ); if (tga_is_right_to_left(tga)) DONTFAIL( tga_flip_horiz(tga) ); if ((tga->width % 8 != 0) || (tga->height % 8 != 0)) { printf("Width and height must be multiples of 8\n"); exit(EXIT_FAILURE); } }
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; }
/* --------------------------------------------------------------------------- * 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; }