示例#1
0
unsigned char *readMemPngToBmpBuff(const unsigned char *memPng, long memPngLen, unsigned int *bmpWidth, unsigned int *bmpHeight)
{
    png_image image;
    png_bytep buffer = NULL;
    
    memset(&image, 0, (sizeof image));
    image.version = PNG_IMAGE_VERSION;
    
    if (!png_image_begin_read_from_memory(&image, memPng, memPngLen) != 0) {
        DEBUG_LOG("begin read mem png: error\n");
        return NULL;
    }
    
    image.format = PNG_FORMAT_RGBA;
    
    buffer = malloc(PNG_IMAGE_SIZE(image));
    
    if (buffer != NULL) {
        if (png_image_finish_read(&image, NULL, buffer, 0, NULL) != 0) {
            *bmpWidth = image.width;
            *bmpHeight = image.height;
            return buffer;
        }
    }
    if (buffer != NULL) {
        free(buffer);
        buffer = NULL;
    }
    
    DEBUG_LOG("read png: error: %s from mem png\n", image.message);
    
    return NULL;
}
示例#2
0
    PixelData decodePNGData(const Data &data, bool shouldPremultiplyAlpha) {
        png_image image;
        memset(&image, 0, (sizeof image));
        image.version = PNG_IMAGE_VERSION;

        if (!png_image_begin_read_from_memory(&image, (void *)data.getBytes(), data.getSize())) {
            throw std::runtime_error("Not PNG data");
        }

        /*
         * According to the example.c file for version 1.6 of libpng, converting 8 bit images to
         * 16 bit images is currently lossy. However, the reverse is hopelessly lossy.  It is
         * also useful to have linear RGB values to correctly premultiply the alpha channel.
         * Therefore all PNG data will be interpreted as 16 bit images, no exceptions.
         */
        image.format = PNG_FORMAT_LINEAR_RGB_ALPHA;

        png_size_t bufferSize = PNG_IMAGE_SIZE(image);
        png_byte *buffer = new png_byte[bufferSize];
        if (buffer == nullptr) {
            throw std::runtime_error("Out of memeory");
        }

        png_image_finish_read(&image, NULL/*background*/, buffer, 0/*row_stride*/, NULL/*colormap*/);

        /*
         * PNGs are internally stored with non-premultiplied alpha channels.  It is often more
         * useful for their values to be premultiplied.  Since the PNG data was interpreted as
         * a 16 bit image, the byte array must be reinterpreted as an array of 16 bit natural
         * numbers.
         */
        if (shouldPremultiplyAlpha) {
            natural_16bit *pixels = reinterpret_cast<natural_16bit *>(buffer);
            for (unsigned int i = 0; i < bufferSize / sizeof(natural_16bit); i += 4) {
                pixels[i + 0] *= pixels[i + 3] / float(0xFFFF);
				pixels[i + 1] *= pixels[i + 3] / float(0xFFFF);
				pixels[i + 2] *= pixels[i + 3] / float(0xFFFF);
            }
        }

        natural_8bit numberOfBitsPerChannel = 16;
        PixelChannel channels[] {
            {PixelChannelName::RED, PixelChannelType::UNSIGNED_INTEGER, numberOfBitsPerChannel},
            {PixelChannelName::GREEN, PixelChannelType::UNSIGNED_INTEGER, numberOfBitsPerChannel},
            {PixelChannelName::BLUE, PixelChannelType::UNSIGNED_INTEGER, numberOfBitsPerChannel},
            {PixelChannelName::ALPHA, PixelChannelType::UNSIGNED_INTEGER, numberOfBitsPerChannel},
        };
        PixelFormat format {sizeof(channels) / sizeof(PixelChannel), channels};
        PixelData imageData {image.width, image.height, format, Data(bufferSize, buffer)};
        
        delete [] buffer;
        
        return imageData;
    }
示例#3
0
文件: fmt.c 项目: HaxeFoundation/hl
HL_PRIM bool HL_NAME(png_decode)( vbyte *data, int dataLen, vbyte *out, int width, int height, int stride, int format, int flags ) {
#	ifdef PNG_IMAGE_VERSION
	png_image img;
	memset(&img, 0, sizeof(img));
	img.version = PNG_IMAGE_VERSION;
	if( png_image_begin_read_from_memory(&img,data,dataLen) == 0 ) {
		png_image_free(&img);
		return false;
	}
	switch( format ) {
	case 0:
		img.format = PNG_FORMAT_RGB;
		break;
	case 1:
		img.format = PNG_FORMAT_BGR;
		break;
	case 7:
		img.format = PNG_FORMAT_RGBA;
		break;
	case 8:
		img.format = PNG_FORMAT_BGRA;
		break;
	case 9:
		img.format = PNG_FORMAT_ABGR;
		break;
	case 10:
		img.format = PNG_FORMAT_ARGB;
		break;
	default:
		png_image_free(&img);
		hl_error("Unsupported format");
		break;
	}
	if( img.width != width || img.height != height ) {
		png_image_free(&img);
		return false;
	}
	if( png_image_finish_read(&img,NULL,out,stride * (flags & 1 ? -1 : 1),NULL) == 0 ) {
		png_image_free(&img);
		return false;
	}
	png_image_free(&img);
#	else
	hl_error("PNG support is missing for this libPNG version");
#	endif
	return true;
}
示例#4
0
bool Interface::load_tex(const char *buf, uint32_t sz, int idx)
{
    png_image image;
    memset(&image, 0, sizeof(png_image));
    image.version = PNG_IMAGE_VERSION;

    if (png_image_begin_read_from_memory(&image, buf, sz))
    {
        image.format = PNG_FORMAT_RGBA;

        png_bytep buffer = (png_bytep)malloc(PNG_IMAGE_SIZE(image));

        if (buffer != NULL)
        {
            if (png_image_finish_read(&image, NULL, buffer, 0, NULL))
            {
                if (idx == TEXTURE_BLACK_IDX)
                {
                    glGenTextures(1, &this->m_texture_black);
                    glBindTexture(GL_TEXTURE_2D, this->m_texture_black);
                }
                else if (idx == TEXTURE_WHITE_IDX)
                {
                    glGenTextures(1, &this->m_texture_white);
                    glBindTexture(GL_TEXTURE_2D, this->m_texture_white);
                }
                else
                {
                    glGenTextures(1, &this->m_textures[idx]);
                    glBindTexture(GL_TEXTURE_2D, this->m_textures[idx]);
                }
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width,
                             image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
            }
            free(buffer);
        }
    }
    else
    {
        ERROR_MESSAGE("Interface: Texture load error: %s\n", image.message);
        return false;
    }

    return true;
}