示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
/* ---------------------------------------------------------------------------
 * Convert a color-mapped image to unmapped BGR.  Reallocates image_data to a
 * bigger size, then converts the image backwards to avoid using a secondary
 * buffer.  Alters the necessary header fields and deallocates the color map.
 */
tga_result tga_color_unmap(tga_image *img)
{
    uint8_t bpp = img->color_map_depth / 8; /* bytes per pixel */
    int pos;
    void *tmp;

    if (!tga_is_colormapped(img)) return TGAERR_NOT_CMAP;
    if (img->pixel_depth != 8) return TGAERR_PIXEL_DEPTH;
    if (!SANE_DEPTH(img->color_map_depth)) return TGAERR_CMAP_DEPTH;

    tmp = realloc(img->image_data, img->width * img->height * bpp);
    if (tmp == NULL) return TGAERR_NO_MEM;
    img->image_data = (uint8_t*) tmp;

    for (pos = img->width * img->height - 1; pos >= 0; pos--)
    {
        uint8_t c_index = img->image_data[pos];
        uint8_t *c_bgr = img->color_map_data + (c_index * bpp);

        if (c_index >= img->color_map_origin + img->color_map_length)
            return TGAERR_INDEX_RANGE;

        memcpy(img->image_data + (pos*bpp), c_bgr, (size_t)bpp);
    }

    /* clean up */
    img->image_type = TGA_IMAGE_TYPE_BGR;
    img->pixel_depth = img->color_map_depth;

    free(img->color_map_data);
    img->color_map_data = NULL;
    img->color_map_type = TGA_COLOR_MAP_ABSENT;
    img->color_map_origin = 0;
    img->color_map_length = 0;
    img->color_map_depth = 0;

    return TGA_NOERR;
}
示例#4
0
/* ---------------------------------------------------------------------------
 * 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;
}
示例#5
0
/* ---------------------------------------------------------------------------
 * Writes a Targa image to <fp> from <src>.
 *
 * Returns: TGA_NOERR on success, or a TGAERR_* code on failure.
 *          On failure, the contents of the file are not guaranteed
 *          to be valid.
 */
tga_result tga_write_to_FILE(FILE *fp, const tga_image *src)
{
    #define WRITE(srcptr, size) \
        if (fwrite(srcptr, size, 1, fp) != 1) return TGAERR_WRITE

    #define WRITE16(src) \
        { uint16_t _temp = htole16(src); \
          if (fwrite(&_temp, 2, 1, fp) != 1) return TGAERR_WRITE; }

    WRITE(&src->image_id_length, 1);

    if (src->color_map_type != TGA_COLOR_MAP_ABSENT &&
        src->color_map_type != TGA_COLOR_MAP_PRESENT)
            return TGAERR_CMAP_TYPE;
    WRITE(&src->color_map_type, 1);

    if (src->image_type == TGA_IMAGE_TYPE_NONE)
            return TGAERR_NO_IMG;
    if (src->image_type != TGA_IMAGE_TYPE_COLORMAP &&
        src->image_type != TGA_IMAGE_TYPE_BGR &&
        src->image_type != TGA_IMAGE_TYPE_MONO &&
        src->image_type != TGA_IMAGE_TYPE_COLORMAP_RLE &&
        src->image_type != TGA_IMAGE_TYPE_BGR_RLE &&
        src->image_type != TGA_IMAGE_TYPE_MONO_RLE)
            return TGAERR_IMG_TYPE;
    WRITE(&src->image_type, 1);

    if (tga_is_colormapped(src) &&
        src->color_map_type == TGA_COLOR_MAP_ABSENT)
            return TGAERR_CMAP_MISSING;
    if (!tga_is_colormapped(src) &&
        src->color_map_type == TGA_COLOR_MAP_PRESENT)
            return TGAERR_CMAP_PRESENT;
    if (src->color_map_type == TGA_COLOR_MAP_PRESENT)
    {
        if (src->color_map_length == 0)
            return TGAERR_CMAP_LENGTH;

        if (!UNMAP_DEPTH(src->color_map_depth))
            return TGAERR_CMAP_DEPTH;
    }
    WRITE16(src->color_map_origin);
    WRITE16(src->color_map_length);
    WRITE(&src->color_map_depth, 1);

    WRITE16(src->origin_x);
    WRITE16(src->origin_y);

    if (src->width == 0 || src->height == 0)
            return TGAERR_ZERO_SIZE;
    WRITE16(src->width);
    WRITE16(src->height);

    if (!SANE_DEPTH(src->pixel_depth) ||
       (src->pixel_depth != 8 && tga_is_colormapped(src)) )
            return TGAERR_PIXEL_DEPTH;
    WRITE(&src->pixel_depth, 1);

    WRITE(&src->image_descriptor, 1);

    if (src->image_id_length > 0)
        WRITE(&src->image_id, src->image_id_length);

    if (src->color_map_type == TGA_COLOR_MAP_PRESENT)
        WRITE(src->color_map_data +
             (src->color_map_origin * src->color_map_depth / 8),
              src->color_map_length * src->color_map_depth / 8);

    if (tga_is_rle(src))
    {
        uint16_t row;
        for (row=0; row<src->height; row++)
        {
            tga_result result = tga_write_row_RLE(fp, src,
                src->image_data + row*src->width*src->pixel_depth/8);
            if (result != TGA_NOERR) return result;
        }
    }
    else
    {
        /* uncompressed */
        WRITE(src->image_data,
              src->width * src->height * src->pixel_depth / 8);
    }

    WRITE(tga_id, tga_id_length);

    return TGA_NOERR;
    #undef WRITE
    #undef WRITE16
}
示例#6
0
/* ---------------------------------------------------------------------------
 * Read a Targa image from <fp> to <dest>.
 *
 * Returns: TGA_NOERR on success, or a TGAERR_* code on failure.  In the
 *          case of failure, the contents of dest are not guaranteed to be
 *          valid.
 */
tga_result tga_read_from_FILE(tga_image *dest, FILE *fp)
{
    #define BARF(errcode) \
        { tga_free_buffers(dest);  return errcode; }

    #define READ(destptr, size) \
        if (fread(destptr, size, 1, fp) != 1) BARF(TGAERR_EOF)

    #define READ16(dest) \
        { if (fread(&(dest), 2, 1, fp) != 1) BARF(TGAERR_EOF); \
          dest = letoh16(dest); }

    dest->image_id = NULL;
    dest->color_map_data = NULL;
    dest->image_data = NULL;

    READ(&dest->image_id_length,1);
    READ(&dest->color_map_type,1);
    if (dest->color_map_type != TGA_COLOR_MAP_ABSENT &&
        dest->color_map_type != TGA_COLOR_MAP_PRESENT)
            BARF(TGAERR_CMAP_TYPE);

    READ(&dest->image_type, 1);
    if (dest->image_type == TGA_IMAGE_TYPE_NONE)
            BARF(TGAERR_NO_IMG);

    if (dest->image_type != TGA_IMAGE_TYPE_COLORMAP &&
        dest->image_type != TGA_IMAGE_TYPE_BGR &&
        dest->image_type != TGA_IMAGE_TYPE_MONO &&
        dest->image_type != TGA_IMAGE_TYPE_COLORMAP_RLE &&
        dest->image_type != TGA_IMAGE_TYPE_BGR_RLE &&
        dest->image_type != TGA_IMAGE_TYPE_MONO_RLE)
            BARF(TGAERR_IMG_TYPE);

    if (tga_is_colormapped(dest) &&
        dest->color_map_type == TGA_COLOR_MAP_ABSENT)
            BARF(TGAERR_CMAP_MISSING);

    if (!tga_is_colormapped(dest) &&
        dest->color_map_type == TGA_COLOR_MAP_PRESENT)
            BARF(TGAERR_CMAP_PRESENT);

    READ16(dest->color_map_origin);
    READ16(dest->color_map_length);
    READ(&dest->color_map_depth, 1);
    if (dest->color_map_type == TGA_COLOR_MAP_PRESENT)
    {
        if (dest->color_map_length == 0)
            BARF(TGAERR_CMAP_LENGTH);

        if (!UNMAP_DEPTH(dest->color_map_depth))
            BARF(TGAERR_CMAP_DEPTH);
    }

    READ16(dest->origin_x);
    READ16(dest->origin_y);
    READ16(dest->width);
    READ16(dest->height);

    if (dest->width == 0 || dest->height == 0)
            BARF(TGAERR_ZERO_SIZE);

    READ(&dest->pixel_depth, 1);
    if (!SANE_DEPTH(dest->pixel_depth) ||
       (dest->pixel_depth != 8 && tga_is_colormapped(dest)) )
            BARF(TGAERR_PIXEL_DEPTH);

    READ(&dest->image_descriptor, 1);

    if (dest->image_id_length > 0)
    {
        dest->image_id = (uint8_t*)malloc(dest->image_id_length);
        if (dest->image_id == NULL) BARF(TGAERR_NO_MEM);
        READ(dest->image_id, dest->image_id_length);
    }

    if (dest->color_map_type == TGA_COLOR_MAP_PRESENT)
    {
        dest->color_map_data = (uint8_t*)malloc(
            (dest->color_map_origin + dest->color_map_length) *
            dest->color_map_depth / 8);
        if (dest->color_map_data == NULL) BARF(TGAERR_NO_MEM);
        READ(dest->color_map_data +
            (dest->color_map_origin * dest->color_map_depth / 8),
            dest->color_map_length * dest->color_map_depth / 8);
    }

    dest->image_data = (uint8_t*) malloc(
        dest->width * dest->height * dest->pixel_depth / 8);
    if (dest->image_data == NULL)
            BARF(TGAERR_NO_MEM);

    if (tga_is_rle(dest))
    {
        /* read RLE */
        tga_result result = tga_read_rle(dest, fp);
        if (result != TGA_NOERR) BARF(result);
    }
    else
    {
        /* uncompressed */
        READ(dest->image_data,
            dest->width * dest->height * dest->pixel_depth / 8);
    }

    return TGA_NOERR;
    #undef BARF
    #undef READ
    #undef READ16
}
示例#7
0
/* ---------------------------------------------------------------------------
 * 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;
}
示例#8
0
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;
}