コード例 #1
0
ファイル: VideoPlayerPipHd.c プロジェクト: suborb/reelvdr
// Copy of HdTrueColorOsd::OpenPngFile()
// expected image returned should be RGBA
bool png_file_2_rgb(char const         *path,
                   Byte **&rows,
                   int                &width,
                   int                &height)
{

    Byte header[8];

    FILE *fp = fopen(path, "rb");
    if (!fp || fread(header, 1, 8, fp) != 8) {
        if(fp)
            fclose(fp);
        return false;
    }

    if (png_sig_cmp(header, 0, 8)) {
        fclose(fp);
        return false;
    }

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr) {
        fclose(fp);
        return false;
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr,
                                NULL, NULL);
        fclose(fp);
        return false;
    }

    png_infop end_info = png_create_info_struct(png_ptr);
    if (!end_info) {
        png_destroy_read_struct(&png_ptr, &info_ptr,
                                (png_infopp)NULL);
        fclose(fp);
        return false;
    }

    png_init_io(png_ptr, fp);

    png_set_sig_bytes(png_ptr, 8);

    if (setjmp(png_jmpbuf(png_ptr))) {
        ::printf("setjmp err\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        fclose(fp);
        return false;
    }

    png_read_info(png_ptr, info_ptr);

    png_byte h = info_ptr->height;
    png_byte color_type = info_ptr->color_type;

#define PRINT_COLOR_TYPE 1
#ifdef PRINT_COLOR_TYPE
    png_byte w = info_ptr->width;
    png_byte bit_depth = info_ptr->bit_depth;
    printf("bit depth: %i - ", bit_depth);
    switch (color_type) {
            case PNG_COLOR_TYPE_GRAY: puts("color_type: PNG_COLOR_TYPE_GRAY"); break;
            case PNG_COLOR_TYPE_PALETTE: puts("color_type: PNG_COLOR_TYPE_PALETTE"); break;
            case PNG_COLOR_TYPE_RGB: puts("color_type: PNG_COLOR_TYPE_RGB"); break;
            case PNG_COLOR_TYPE_RGB_ALPHA: puts("color_type: PNG_COLOR_TYPE_RGB_ALPHA"); break;
            case PNG_COLOR_TYPE_GRAY_ALPHA: puts("color_type: PNG_COLOR_TYPE_GRAY_ALPHA"); break;
            default: puts("ERROR: unknown color_type"); break;
    }
#endif

    if (color_type == PNG_COLOR_TYPE_PALETTE) // Lets have RGB
    {
        png_set_expand(png_ptr);
        png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
    }

    if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      png_set_gray_to_rgb(png_ptr);

    if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY)
      png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);

    png_read_update_info(png_ptr, info_ptr);

    rows = (png_bytep*) malloc(sizeof(png_bytep) * h);
    int y;
    for (y=0; y<h; y++) {
        rows[y] = (png_byte*) malloc(info_ptr->rowbytes);
    }

    png_read_image(png_ptr, rows);

    width = png_get_image_width(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);

    fclose(fp);
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    return true;

} // png_file_2_rgb()
コード例 #2
0
ファイル: PNGReader.cpp プロジェクト: fescrb/octreeRenderer
Texture *PNGReader::readImage() {
    char header[8];
    
    FILE *fp = fopen(m_filename, "rb");
    if(!fp) {
        printf("PNGReader: Problem reading %s\n", m_filename); exit(1);
    }
    fread(header, 1, 8, fp);
    
    if(png_sig_cmp((unsigned char*)header, 0, 8)) {
        printf("PNGReader: %s not a png file\n", m_filename); exit(1);
    }
    
    // Initialization
    png_structp png_pointer = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    
    png_infop png_info_pointer = png_create_info_struct(png_pointer);
    
    png_init_io(png_pointer, fp);
    png_set_sig_bytes(png_pointer, 8);
    png_read_info(png_pointer, png_info_pointer);
    
    int width = png_get_image_width(png_pointer, png_info_pointer);
    int height = png_get_image_height(png_pointer, png_info_pointer);
    png_byte colour_type = png_get_color_type(png_pointer, png_info_pointer);
    png_byte bit_depth = png_get_bit_depth(png_pointer, png_info_pointer);
    
    printf("Image %s width %d height %d colour_type", m_filename, width, height);
    print_colour_type(colour_type);
    printf(" bit depth %d\n", bit_depth);
    
    
    int number_of_passes = png_set_interlace_handling(png_pointer);
    png_read_update_info(png_pointer, png_info_pointer);
    
    int image_channels;
    
    switch(colour_type) {
        case PNG_COLOR_TYPE_RGB:
            image_channels = 3;
            break;
        default:
            printf("PNGReader Error: Image not RGB\n");
            exit(1);
    }
    
    // Read
    unsigned char *data = (unsigned char*) malloc (sizeof(unsigned char)*height*width*image_channels+1);
    png_bytep row_pointers[height];
    
    unsigned int rowBytes = png_get_rowbytes(png_pointer, png_info_pointer);
    
    for(int i = 0; i < height; i ++) {
        row_pointers[i] = data + ((height-(i+1))*rowBytes);
    }
    
    png_read_image(png_pointer, row_pointers);
    png_read_end(png_pointer, NULL);
    
    /*
     * Image seems to get image upside-down. With RGB backwards.
     */
    
    Texture *input = new Texture(width, height, Image::RGB, (char*)data);
    input->toBMP("test_out.bmp");
    
    return input;
}
コード例 #3
0
ファイル: _png.cpp プロジェクト: Tillsten/matplotlib
static PyObject *_read_png(PyObject *filein, bool float_result)
{
    png_byte header[8]; // 8 is the maximum size that can be checked
    FILE *fp = NULL;
    mpl_off_t offset = 0;
    bool close_file = false;
    bool close_dup_file = false;
    PyObject *py_file = NULL;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    int num_dims;
    std::vector<png_bytep> row_pointers;
    png_uint_32 width = 0;
    png_uint_32 height = 0;
    int bit_depth;
    PyObject *result = NULL;

    // TODO: Remove direct calls to Numpy API here

    if (PyBytes_Check(filein) || PyUnicode_Check(filein)) {
        if ((py_file = mpl_PyFile_OpenFile(filein, (char *)"rb")) == NULL) {
            goto exit;
        }
        close_file = true;
    } else {
        py_file = filein;
    }

    if ((fp = mpl_PyFile_Dup(py_file, (char *)"rb", &offset))) {
        close_dup_file = true;
    } else {
        PyErr_Clear();
        PyObject *read_method = PyObject_GetAttrString(py_file, "read");
        if (!(read_method && PyCallable_Check(read_method))) {
            Py_XDECREF(read_method);
            PyErr_SetString(PyExc_TypeError,
                            "Object does not appear to be a 8-bit string path or "
                            "a Python file-like object");
            goto exit;
        }
        Py_XDECREF(read_method);
    }

    if (fp) {
        if (fread(header, 1, 8, fp) != 8) {
            PyErr_SetString(PyExc_IOError, "error reading PNG header");
            goto exit;
        }
    } else {
        _read_png_data(py_file, header, 8);
    }

    if (png_sig_cmp(header, 0, 8)) {
        PyErr_SetString(PyExc_ValueError, "invalid PNG header");
        goto exit;
    }

    /* initialize stuff */
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    if (!png_ptr) {
        PyErr_SetString(PyExc_RuntimeError, "png_create_read_struct failed");
        goto exit;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        PyErr_SetString(PyExc_RuntimeError, "png_create_info_struct failed");
        goto exit;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        PyErr_SetString(PyExc_RuntimeError, "Error setting jump");
        goto exit;
    }

    if (fp) {
        png_init_io(png_ptr, fp);
    } else {
        png_set_read_fn(png_ptr, (void *)py_file, &read_png_data);
    }
    png_set_sig_bytes(png_ptr, 8);
    png_read_info(png_ptr, info_ptr);

    width = png_get_image_width(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);

    bit_depth = png_get_bit_depth(png_ptr, info_ptr);

    // Unpack 1, 2, and 4-bit images
    if (bit_depth < 8) {
        png_set_packing(png_ptr);
    }

    // If sig bits are set, shift data
    png_color_8p sig_bit;
    if ((png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_PALETTE) &&
        png_get_sBIT(png_ptr, info_ptr, &sig_bit)) {
        png_set_shift(png_ptr, sig_bit);
    }

    // Convert big endian to little
    if (bit_depth == 16) {
        png_set_swap(png_ptr);
    }

    // Convert palletes to full RGB
    if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) {
        png_set_palette_to_rgb(png_ptr);
        bit_depth = 8;
    }

    // If there's an alpha channel convert gray to RGB
    if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) {
        png_set_gray_to_rgb(png_ptr);
    }

    png_set_interlace_handling(png_ptr);
    png_read_update_info(png_ptr, info_ptr);

    row_pointers.resize(height);
    for (png_uint_32 row = 0; row < height; row++) {
        row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
    }

    png_read_image(png_ptr, &row_pointers[0]);

    npy_intp dimensions[3];
    dimensions[0] = height; // numrows
    dimensions[1] = width; // numcols
    if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) {
        dimensions[2] = 4; // RGBA images
    } else if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) {
        dimensions[2] = 3; // RGB images
    } else {
        dimensions[2] = 1; // Greyscale images
    }

    if (float_result) {
        double max_value = (1 << bit_depth) - 1;

        numpy::array_view<float, 3> A(dimensions);

        for (png_uint_32 y = 0; y < height; y++) {
            png_byte *row = row_pointers[y];
            for (png_uint_32 x = 0; x < width; x++) {
                if (bit_depth == 16) {
                    png_uint_16 *ptr = &reinterpret_cast<png_uint_16 *>(row)[x * dimensions[2]];
                    for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
                        A(y, x, p) = (float)(ptr[p]) / max_value;
                    }
                } else {
                    png_byte *ptr = &(row[x * dimensions[2]]);
                    for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
                        A(y, x, p) = (float)(ptr[p]) / max_value;
                    }
                }
            }
        }

        result = A.pyobj();
    } else if (bit_depth == 16) {
        numpy::array_view<png_uint_16, 3> A(dimensions);

        for (png_uint_32 y = 0; y < height; y++) {
            png_byte *row = row_pointers[y];
            for (png_uint_32 x = 0; x < width; x++) {
                png_uint_16 *ptr = &reinterpret_cast<png_uint_16 *>(row)[x * dimensions[2]];
                for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
                    A(y, x, p) = ptr[p];
                }
            }
        }

        result = A.pyobj();
    } else if (bit_depth == 8) {
        numpy::array_view<png_byte, 3> A(dimensions);

        for (png_uint_32 y = 0; y < height; y++) {
            png_byte *row = row_pointers[y];
            for (png_uint_32 x = 0; x < width; x++) {
                png_byte *ptr = &(row[x * dimensions[2]]);
                for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
                    A(y, x, p) = ptr[p];
                }
            }
        }

        result = A.pyobj();
    } else {
        PyErr_SetString(PyExc_RuntimeError, "image has unknown bit depth");
        goto exit;
    }

    // free the png memory
    png_read_end(png_ptr, info_ptr);

    // For gray, return an x by y array, not an x by y by 1
    num_dims = (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) ? 3 : 2;

    if (num_dims == 2) {
        PyArray_Dims dims = {dimensions, 2};
        PyObject *reshaped = PyArray_Newshape((PyArrayObject *)result, &dims, NPY_CORDER);
        Py_DECREF(result);
        result = reshaped;
    }

exit:
    if (png_ptr && info_ptr) {
#ifndef png_infopp_NULL
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
#else
        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
#endif
    }

    if (close_dup_file) {
        mpl_PyFile_DupClose(py_file, fp, offset);
    }

    if (close_file) {
        mpl_PyFile_CloseFile(py_file);
        Py_DECREF(py_file);
    }

    for (png_uint_32 row = 0; row < height; row++) {
        delete[] row_pointers[row];
    }

    if (PyErr_Occurred()) {
        Py_XDECREF(result);
        return NULL;
    } else {
        return result;
    }
}
コード例 #4
0
ファイル: png_extractor.c プロジェクト: argent0/stega
int main ( int argc, char** argv) {

	FILE* fp;

	size_t width = 0;
	size_t height = 0;
	size_t depth = 0;
	size_t channels = 0;

	size_t r; /* counter for rows */

	PNGImage* image;

	if ( argc < 2 ) {
		usage( argv[0] );
		exit(1);
	}	

	image = readPNGfile(argv[1]);
	 
	if ( image == NULL ) {
		exit(1);
	}

	/* Retrive basic image information */
	width = png_get_image_width( image->png, image->info );
	height = png_get_image_height( image->png, image->info );
	depth = png_get_bit_depth( image->png, image->info );
	channels = png_get_channels( image->png, image->info );

	printf("Image Info:\nWidth :%d\nHeight :%d\nBit depth:%d\n", width, height, depth );
	printf("Channels :%u\n", channels);


	printf("Creating info file\n"); /*-------------------------------------------*/

	fp = fopen("info","wb");

	if (!fp) {
		printf("Could not create info file\n");
		png_destroy_read_struct( &image->png, &image->info, &image->end);
		exit(1);
	}

	fwrite(image->info, sizeof(png_info), 1,fp );

	fclose(fp);

	printf("Creating end file\n"); /*-------------------------------------------*/

	fp = fopen("end","wb");

	if (!fp) {
		printf("Could not create end file\n");
		png_destroy_read_struct( &image->png, &image->info, &image->end);
		exit(1);
	}

	fwrite(image->end, sizeof(png_info), 1,fp );

	fclose(fp);

	printf("Creating raw file\n"); /*-------------------------------------------*/
	fp = fopen("raw","wb");

	if (!fp) {
		printf("Could not create raw file\n");
		png_destroy_read_struct( &image->png, &image->info, &image->end);
		exit(1);
	}

	for ( r=0; r < height; r = r+1 )
		fwrite(image->row_pointers[r], sizeof(png_byte), width, fp );

	fclose(fp);

	printf("Releasing memory\n");	
	png_destroy_read_struct( &image->png, &image->info, &image->end);

	return 0;
}
コード例 #5
0
ファイル: image.cpp プロジェクト: ajasmin/lightspark
uint8_t* ImageDecoder::decodePNGImpl(png_structp pngPtr, uint32_t* width, uint32_t* height)
{
	png_bytep* rowPtrs = NULL;
	uint8_t* outData = NULL;
	png_infop infoPtr = png_create_info_struct(pngPtr);
	if (!infoPtr)
	{
		LOG(LOG_ERROR,"Couldn't initialize png info struct");
		png_destroy_read_struct(&pngPtr, (png_infopp)0, (png_infopp)0);
		return NULL;
	}

	if (setjmp(png_jmpbuf(pngPtr)))
	{
		png_destroy_read_struct(&pngPtr, &infoPtr,(png_infopp)0);
		if (rowPtrs != NULL) delete [] rowPtrs;
		if (outData != NULL) delete outData;

		LOG(LOG_ERROR,"error during reading of the png file");

		return NULL;
	}

	png_read_info(pngPtr, infoPtr);

	*width =  png_get_image_width(pngPtr, infoPtr);
	*height = png_get_image_height(pngPtr, infoPtr);

	//bits per CHANNEL! note: not per pixel!
	png_uint_32 bitdepth = png_get_bit_depth(pngPtr, infoPtr);
	//Number of channels
	png_uint_32 channels = png_get_channels(pngPtr, infoPtr);
	//Color type. (RGB, RGBA, Luminance, luminance alpha... palette... etc)
	png_uint_32 color_type = png_get_color_type(pngPtr, infoPtr);

	switch (color_type)
	{
		case PNG_COLOR_TYPE_PALETTE:
			png_set_palette_to_rgb(pngPtr);
			channels = 3;
			break;
		case PNG_COLOR_TYPE_GRAY:
			if (bitdepth < 8)
				png_set_gray_to_rgb(pngPtr);
			bitdepth = 8;
			break;
	}

	rowPtrs = new png_bytep[(*height)];

	outData = new uint8_t[(*width) * (*height) * bitdepth * channels / 8];
	const unsigned int stride = (*width) * bitdepth * channels / 8;

	for (size_t i = 0; i < (*height); i++)
	{
		rowPtrs[i] = (png_bytep)outData + i* stride;
	}

	png_read_image(pngPtr, rowPtrs);
	delete[] (png_bytep)rowPtrs;
	png_destroy_read_struct(&pngPtr, &infoPtr,(png_infopp)0);

	return outData;
}
コード例 #6
0
ファイル: pngio.cpp プロジェクト: pbhogan/pngio
static uint8_t png_read( png_structp readPtr, png_image * image, uint32_t flags )
{
//	png_set_error_fn( readPtr, NULL, png_user_error, NULL );

	png_infop infoPtr = png_create_info_struct( readPtr );
	if (!infoPtr) 
	{
		pngio_error( "Couldn't initialize PNG info struct." );
		png_destroy_read_struct( & readPtr, NULL, NULL );
		return 0;
	}
	
	if (setjmp( png_jmpbuf( readPtr ) ))
	{
		pngio_error( "An error occured while reading the PNG file." );
		png_destroy_read_struct( & readPtr, & infoPtr, NULL );
		png_image_free( image );
		return 0;
	}

	png_set_sig_bytes( readPtr, 8 );
	
	#ifdef PNG_APPLE_MODE_SUPPORTED 
	if (png_get_apple_mode())
	{
		png_set_keep_unknown_chunks( readPtr, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0 );
		png_set_read_user_chunk_fn( readPtr, NULL, png_read_user_chunk );
	}
	#endif
	
	png_read_info( readPtr, infoPtr );
	
	png_uint_32 w = png_get_image_width( readPtr, infoPtr );
	png_uint_32 h = png_get_image_height( readPtr, infoPtr );
	png_uint_32 bitDepth = png_get_bit_depth( readPtr, infoPtr );
	png_uint_32 channels = png_get_channels( readPtr, infoPtr );
	png_uint_32 interlaceType = png_get_interlace_type( readPtr, infoPtr );
	png_uint_32 colorType = png_get_color_type( readPtr, infoPtr );
	
	switch (colorType) 
	{
		case PNG_COLOR_TYPE_PALETTE:
			png_set_palette_to_rgb( readPtr );
			channels = 3;           
			break;
		case PNG_COLOR_TYPE_GRAY:
			if (bitDepth < 8)
			{
				png_set_expand_gray_1_2_4_to_8( readPtr );
				bitDepth = 8;
			}
			png_set_gray_to_rgb( readPtr );
			break;
	}
	
	if (png_get_valid( readPtr, infoPtr, PNG_INFO_tRNS )) 
	{
		png_set_tRNS_to_alpha( readPtr );
		channels += 1;
	}
	else if (!(colorType & PNG_COLOR_MASK_ALPHA)) 
	{
		png_set_add_alpha( readPtr, 0xff, PNG_FILLER_AFTER );
	}
	
	if (bitDepth == 16)
	{
		png_set_strip_16( readPtr );
	}

	#ifdef PNG_APPLE_MODE_SUPPORTED
	if (png_get_apple_mode())
	{
		if (flags & PNG_IMAGE_PREMULTIPLY_ALPHA)
		{
			png_set_read_user_transform_fn( readPtr, png_read_swap_transform );
		}
		else
		{
			png_set_read_user_transform_fn( readPtr, png_read_swap_and_unpremultiply_transform );
		}
		png_set_user_transform_info( readPtr, NULL, bitDepth, channels );
		png_read_update_info( readPtr, infoPtr );
	}
	else
	#endif
	{
		if (flags & PNG_IMAGE_PREMULTIPLY_ALPHA)
		{
			png_set_read_user_transform_fn( readPtr, png_read_premultiply_transform );
		}
	}

	png_image_alloc( image, w, h );
	png_bytep p = image->data;
	
	const size_t passCount = interlaceType == PNG_INTERLACE_NONE ? 1 : png_set_interlace_handling( readPtr );
	const size_t bytesPerRow = w * 4;
	if (flags & PNG_IMAGE_FLIP_VERTICAL)
	{
		for (size_t pass = 0; pass < passCount; pass++)
		{
			for (size_t i = 0; i < h; i++) 
			{
				png_read_row( readPtr, p + (bytesPerRow * (h - i - 1)), NULL );
			}
		}
	}
	else
	{
//		png_bytep rp[h];
//		for (size_t i = 0; i < h; i++) 
//		{
//			rp[i] = p + (bytesPerRow * i);
//		}
//		png_read_image( readPtr, rp );
		for (size_t pass = 0; pass < passCount; pass++)
		{
			for (size_t i = 0; i < h; i++) 
			{
				png_read_row( readPtr, p + (bytesPerRow * i), NULL );
			}
		}
	}
	
	png_destroy_read_struct( & readPtr, & infoPtr, NULL );
	
	return 1;
}
コード例 #7
0
ファイル: FilePreviewCtrl.cpp プロジェクト: cpzhang/zen
BOOL CImage::LoadBitmapFromPNGFile(LPTSTR szFileName)
{
    BOOL bStatus = FALSE;

    FILE *fp = NULL;
    const int number = 8;
    png_byte header[number];
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    png_infop end_info = NULL;
    png_uint_32 rowbytes = 0;
    png_uint_32 width = 0;
    png_uint_32 height = 0;
    png_bytep row = NULL;
    int y = 0;
    BITMAPINFO* pBMI = NULL;
    HDC hDC = NULL;

    _TFOPEN_S(fp, szFileName, _T("rb"));
    if (!fp)
    {
        return FALSE;
    }

    fread(header, 1, number, fp);
    if(png_sig_cmp(header, 0, number))
    {
        goto cleanup;
    }

    png_ptr = png_create_read_struct
              (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
        goto cleanup;

    if (setjmp(png_ptr->jmpbuf))
        goto cleanup;

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
        goto cleanup;

    end_info = png_create_info_struct(png_ptr);
    if (!end_info)
        goto cleanup;

    png_init_io(png_ptr, fp);
    png_set_sig_bytes(png_ptr, number);

    // Read PNG information
    png_read_info(png_ptr, info_ptr);

    // Get count of bytes per row
    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
    row = new png_byte[rowbytes];

    width = png_get_image_width(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);

    if(info_ptr->channels==3)
    {
        png_set_strip_16(png_ptr);
        png_set_packing(png_ptr);
        png_set_bgr(png_ptr);
    }

    hDC = GetDC(NULL);

    {
        CAutoLock lock(&m_csLock);
        if(m_bLoadCancelled)
            goto cleanup;
        m_hBitmap = CreateCompatibleBitmap(hDC, width, height);
    }

    pBMI = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFO)+256*4];
    memset(pBMI, 0, sizeof(BITMAPINFO)+256*4);
    pBMI->bmiHeader.biSize = sizeof(BITMAPINFO);
    pBMI->bmiHeader.biBitCount = 8*info_ptr->channels;
    pBMI->bmiHeader.biWidth = width;
    pBMI->bmiHeader.biHeight = height;
    pBMI->bmiHeader.biPlanes = 1;
    pBMI->bmiHeader.biCompression = BI_RGB;
    pBMI->bmiHeader.biSizeImage = rowbytes*height;

    if( info_ptr->channels == 1 )
    {
        RGBQUAD* palette = pBMI->bmiColors;

        int i;
        for( i = 0; i < 256; i++ )
        {
            palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
            palette[i].rgbReserved = 0;
        }

        palette[256].rgbBlue = palette[256].rgbGreen = palette[256].rgbRed = 255;
    }

    for(y=height-1; y>=0; y--)
    {
        png_read_rows(png_ptr, &row, png_bytepp_NULL, 1);

        {
            CAutoLock lock(&m_csLock);
            int n = SetDIBits(hDC, m_hBitmap, y, 1, row, pBMI, DIB_RGB_COLORS);
            if(n==0)
                goto cleanup;
        }
    }

    /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
    png_read_end(png_ptr, info_ptr);

    bStatus = TRUE;

cleanup:

    if(fp!=NULL)
    {
        fclose(fp);
    }

    if(png_ptr)
    {
        png_destroy_read_struct(&png_ptr,
                                (png_infopp)&info_ptr, (png_infopp)&end_info);
    }

    if(row)
    {
        delete [] row;
    }

    if(pBMI)
    {
        delete [] pBMI;
    }

    if(!bStatus)
    {
        Destroy();
    }

    return bStatus;
}
コード例 #8
0
ファイル: png2tx.c プロジェクト: sharkable/sharkengine
struct PNG read_png_file(char *filename) {
  unsigned char header[8];    // 8 is the maximum size that can be checked

  /* open file and test for it being a png */
  FILE *fp = fopen(filename, "rb");
  if (!fp) {
    abort_("[read_png_file] File %s could not be opened for reading", filename);
  }
  fread(header, 1, 8, fp);
  if (png_sig_cmp(header, 0, 8)) {
    abort_("[read_png_file] File %s is not recognized as a PNG file", filename);
  }

  /* initialize stuff */
  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

  if (!png_ptr) {
    abort_("[read_png_file] png_create_read_struct failed");
  }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    abort_("[read_png_file] png_create_info_struct failed");
  }

  if (setjmp(png_jmpbuf(png_ptr))) {
    abort_("[read_png_file] Error during init_io");
  }

  png_init_io(png_ptr, fp);
  png_set_sig_bytes(png_ptr, 8);

  png_read_info(png_ptr, info_ptr);

  struct PNG png; 
  png.width = png_get_image_width(png_ptr, info_ptr);
  png.height = png_get_image_height(png_ptr, info_ptr);
  png_byte color_type = png_get_color_type(png_ptr, info_ptr);
  png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);

  if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
    abort_("[read_png_file] PNG %s must be RGB or RGBA", filename);
  }
  if (bit_depth != 8) {
    abort_("[read_png_file] PNG %s must be 8 bits per channel", filename);
  }
  if (color_type == PNG_COLOR_TYPE_RGB) {
    png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER);
  }

  png_read_update_info(png_ptr, info_ptr);

  /* read file */
  if (setjmp(png_jmpbuf(png_ptr))) {
    abort_("[read_png_file] Error during read_image");
  }

  png.row_pointers = (png_bytep *)malloc(sizeof(png_bytep) * png.height);

  int row_size = png.width * 4;
  int y;
  for (y = 0; y < png.height; y++) {
    png.row_pointers[y] = (png_byte *)malloc(row_size);
  }

  png_read_image(png_ptr, png.row_pointers);
  png_read_end(png_ptr, NULL);
  png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
  fclose(fp);

  return png;
}
コード例 #9
0
ファイル: easypng.cpp プロジェクト: axzhong3/mazeRouter
// TODO: clean up error handling, too much dupe code right now
bool PNG::_read_file(string const & file_name)
{
	// unfortunately, we need to break down to the C-code level here, since
	// libpng is written in C itself

	// we need to open the file in binary mode
	FILE * fp = fopen(file_name.c_str(), "rb");
	if (!fp)
	{
		epng_err("Failed to open " + file_name);
		return false;
	}

	// read in the header (max size of 8), use it to validate this as a PNG file
	png_byte header[8];
	fread(header, 1, 8, fp);
	if (png_sig_cmp(header, 0, 8))
	{
		epng_err("File is not a valid PNG file");
		fclose(fp);
		_init();
		return false;
	}

	// set up libpng structs for reading info
	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr)
	{
		epng_err("Failed to create read struct");
		fclose(fp);
		_init();
		return false;
	}

	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		epng_err("Failed to create info struct");
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		fclose(fp);
		_init();
		return false;
	}

	// set error handling to not abort the entire program
	if (setjmp(png_jmpbuf(png_ptr)))
	{
		epng_err("Error initializing libpng io");
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(fp);
		_init();
		return false;
	}

	// initialize png reading
	png_init_io(png_ptr, fp);
	// let it know we've already read the first 8 bytes
	png_set_sig_bytes(png_ptr, 8);

	// read in the basic image info
	png_read_info(png_ptr, info_ptr);

	// convert to 8 bits
	png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
	if (bit_depth == 16)
		png_set_strip_16(png_ptr);

	// verify this is in RGBA format, and if not, convert it to RGBA
	png_byte color_type = png_get_color_type(png_ptr, info_ptr);
	if (color_type != PNG_COLOR_TYPE_RGBA && color_type != PNG_COLOR_TYPE_RGB)
	{
		if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
			if (bit_depth < 8)
				png_set_expand(png_ptr);
			png_set_gray_to_rgb(png_ptr);
		}
		if (color_type == PNG_COLOR_TYPE_PALETTE)
			png_set_palette_to_rgb(png_ptr);
	}
	// convert tRNS to alpha channel
	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
		png_set_tRNS_to_alpha(png_ptr);

	_width = png_get_image_width(png_ptr, info_ptr);
	_height = png_get_image_height(png_ptr, info_ptr);

	png_read_update_info(png_ptr, info_ptr);

	// begin reading in the image
	if (setjmp(png_jmpbuf(png_ptr)))
	{
		epng_err("Error reading image with libpng");
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(fp);
		_init();
		return false;
	}


	int bpr = png_get_rowbytes(png_ptr, info_ptr); // number of bytes in a row
	int numchannels = png_get_channels(png_ptr, info_ptr);

	// initialie our image storage
	_pixels = new RGBAPixel[_height * _width];
	png_byte * row = new png_byte[bpr];
	for (int y = 0; y < _height; y++)
	{
		png_read_row(png_ptr, row, NULL);
		png_byte * pix = row;
		for (int x = 0; x < _width; x++)
		{
			RGBAPixel & pixel = _pixel(x,y);
			if (numchannels == 1 || numchannels == 2)
			{
				// monochrome
				unsigned char color = (unsigned char) *pix++;
				pixel.red = color;
				pixel.green = color;
				pixel.blue = color;
				if (numchannels == 2)
					pixel.alpha = (unsigned char) *pix++;
				else
					pixel.alpha = 255;
			} 
			else if (numchannels == 3 || numchannels == 4) 
			{
				pixel.red = (unsigned char) *pix++;
				pixel.green = (unsigned char) *pix++;
				pixel.blue = (unsigned char) *pix++;
				if (numchannels == 4)
					pixel.alpha = (unsigned char) *pix++;
				else
					pixel.alpha = 255;
			}
		}
	}
	// cleanup
	delete [] row;
	png_read_end(png_ptr, NULL);
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	fclose(fp);
	return true;
}
コード例 #10
0
ファイル: graphicscore.c プロジェクト: cnlohr/bridgesim
int ReadTextureFromPNG( struct Texture * t, const char * filename )
{
#ifdef USE_PNG
	png_structp png_ptr;
	png_infop info_ptr;
	int number_of_passes;
	png_bytep* row_pointers;
	png_byte color_type;
	png_byte bit_depth;
	unsigned x;
	int r;
	unsigned char header[8];	// 8 is the maximum size that can be checked

	FILE * fp = fopen( filename, "rb" );

	//open file and test for it being a png 
	if (!fp)
	{
		fprintf( stderr, "[read_png_file] File %s could not be opened for reading", filename );
		goto quickexit;
	}

	r = fread(header, 8, 1, fp);

	if (png_sig_cmp(header, 0, 8))
	{
		fprintf( stderr, "[read_png_file] File %s is not recognized as a PNG file", filename );
		goto closeandquit;
	}

	//initialize stuff 
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

	if (!png_ptr)
	{
		fprintf( stderr, "[read_png_file] png_create_read_struct failed");
		goto closeandquit;
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		fprintf( stderr, "[read_png_file] png_create_info_struct failed");
		goto closepngandquit;
	}

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		fprintf( stderr, "[read_png_file] Error during init_io");
		goto closepngandquit;
	}

	png_set_sig_bytes(png_ptr, 8);
	png_set_read_fn( png_ptr, fp, mypngreadfn );

	png_read_info(png_ptr, info_ptr);

	t->width = png_get_image_width(png_ptr, info_ptr);
	t->height = png_get_image_height(png_ptr, info_ptr);
	color_type = png_get_color_type(png_ptr, info_ptr);
	bit_depth = png_get_bit_depth(png_ptr, info_ptr);

	if (color_type == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(png_ptr);

	number_of_passes = png_set_interlace_handling(png_ptr);
	png_read_update_info(png_ptr, info_ptr);

	// read file 
	if (setjmp(png_jmpbuf(png_ptr)))
	{
		fprintf(stderr,"[read_png_file] Error during read_image");
		goto closepngandquit;		
	}

	row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * t->height);
	unsigned int y;
	for ( y=0; y < (unsigned)t->height; y++)
		row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr, info_ptr));

	png_read_image(png_ptr, row_pointers);

	png_read_end( png_ptr, info_ptr );
	png_destroy_read_struct( &png_ptr, &info_ptr, NULL );

	png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);

	if (color_type & PNG_COLOR_MASK_COLOR )
		if (color_type & PNG_COLOR_MASK_ALPHA)
			t->format = TTRGBA;	
		else
			t->format = TTRGB;
	else
		if (color_type & PNG_COLOR_MASK_ALPHA)
			t->format = TTGRAYALPHA;	
		else
			t->format = TTGRAYSCALE;


//	SAFE_DELETE(texture->m_data);
	t->rawdata = malloc( t->width * t->height * channels[t->format] );

	switch (t->format)
	{
		case TTGRAYSCALE:
			for ( y=0; y < (unsigned)t->height; ++y) {
				png_byte* row = row_pointers[y];
				for ( x = 0; x < t->width; ++x) {
					png_byte* ptr = &(row[x]);
					t->rawdata[(x + y * t->width)] = ptr[0];
				}	
			}
			break;
		case TTGRAYALPHA:
			for ( y=0; y < (unsigned)t->height; ++y) {
				png_byte* row = row_pointers[y];
				for ( x = 0; x < t->width; ++x) {
					png_byte* ptr = &(row[x*2]);
					t->rawdata[(x + y * t->width) * 2] = ptr[0];
					t->rawdata[(x + y * t->width) * 2 + 1] = ptr[1];
				}	
			}
			break;
		case TTRGBA:
			for ( y=0; y < (unsigned)t->height; ++y) {
				png_byte* row = row_pointers[y];
				for ( x = 0; x < t->width; ++x) {
					png_byte* ptr = &(row[x*4]);
					t->rawdata[(x + y * t->width) * 4] = ptr[0];
					t->rawdata[(x + y * t->width) * 4 + 1] = ptr[1];
					t->rawdata[(x + y * t->width) * 4 + 2] = ptr[2];
					t->rawdata[(x + y * t->width) * 4 + 3] = ptr[3];
				}	
			}
			break;
		case TTRGB:
			for ( y=0; y < (unsigned)t->height; y++) {
				png_byte* row = row_pointers[y];
				for (x=0; x<t->width; x++) {
					png_byte* ptr = &(row[x * 3]);
					t->rawdata[(x + y * t->width) * 3] = ptr[0];
					t->rawdata[(x + y * t->width) * 3 + 1] = ptr[1];
					t->rawdata[(x + y * t->width) * 3 + 2] = ptr[2];
				}	
			}
			break;
		default:
			fprintf( stderr, "Warning: Invalid color byte type for PNG.");
			break;
	}

	for ( y=0; y < (unsigned)t->height; y++)
		free(row_pointers[y]);
	free(row_pointers);

	t->type = GL_TEXTURE_2D;

	return 0;
closepngandquit:
	png_read_end( png_ptr, info_ptr );
	png_destroy_read_struct( &png_ptr, &info_ptr, NULL );
	png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);	
closeandquit:
	fclose( fp );
quickexit:
	return -1;
#else
	fprintf( stderr, "Error.  Cannot load: %s.  PNG Support not included.\n" );
	return -1;
#endif
}