Пример #1
0
    void set_rgb_to_gray(rgb_to_gray_error_action error_action
                         = rgb_to_gray_silent,
                         fixed_point red_weight   = -1,
                         fixed_point green_weight = -1) const
    {
        TRACE_IO_TRANSFORM("png_set_rgb_to_gray_fixed: error_action=%d,"
                           " red_weight=%d, green_weight=%d\n",
                           error_action, red_weight, green_weight);

        png_set_rgb_to_gray_fixed(m_png, error_action,
                                  red_weight, green_weight);
    }
Пример #2
0
int ShapeWipeMain::read_pattern_image(int new_frame_width, int new_frame_height)
{
	png_byte header[8];
	int is_png;
	int row;
	int col;
	int scaled_row;
	int scaled_col;
	int pixel_width;
	unsigned char value;
	png_uint_32 width;
	png_uint_32 height;
	png_byte color_type;
	png_byte bit_depth;
	png_structp png_ptr;
	png_infop info_ptr;
	png_infop end_info;
	png_bytep *image;
	frame_width = new_frame_width;
	frame_height = new_frame_height;

// Convert name to filename
	for(int i = 0; i < shape_paths.size(); i++)
	{
		if(!strcmp(shape_titles.get(i), shape_name))
		{
			strcpy(filename, shape_paths.get(i));
			break;
		}
	}

	FILE *fp = fopen(filename, "rb");
	if (!fp)
	{
		return 1;
	}

	fread(header, 1, 8, fp);
	is_png = !png_sig_cmp(header, 0, 8);

	if (!is_png)
	{
		return 1;
	}

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
		NULL, NULL, NULL);

	if (!png_ptr)
	{
	return 1;
	}

	/* Tell libpng we already checked the first 8 bytes */
	png_set_sig_bytes(png_ptr, 8);

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		return 1;
	}

	end_info = png_create_info_struct(png_ptr);
	if (!end_info)
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		return 1;
	}

	png_init_io(png_ptr, fp);
	png_read_info(png_ptr, info_ptr);

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

	/* Skip the alpha channel if present 
	* stripping alpha currently doesn't work in conjunction with 
	* converting to grayscale in libpng */
	if (color_type & PNG_COLOR_MASK_ALPHA)
		pixel_width = 2;
	else
		pixel_width = 1;

	/* Convert 16 bit data to 8 bit */
	if (bit_depth == 16) png_set_strip_16(png_ptr);

	/* Expand to 1 pixel per byte if necessary */
	if (bit_depth < 8) png_set_packing(png_ptr);

	/* Convert to grayscale */
	if (color_type == PNG_COLOR_TYPE_RGB || 
		color_type == PNG_COLOR_TYPE_RGB_ALPHA)
	png_set_rgb_to_gray_fixed(png_ptr, 1, -1, -1);

	/* Allocate memory to hold the original png image */
	image = (png_bytep*)malloc(sizeof(png_bytep)*height);
	for (row = 0; row < height; row++)
	{
		image[row] = (png_byte*)malloc(sizeof(png_byte)*width*pixel_width);
	}

	/* Allocate memory for the pattern image that will actually be
	* used for the wipe */
	pattern_image = (unsigned char**)malloc(sizeof(unsigned char*)*frame_height);


	png_read_image(png_ptr, image);
	png_read_end(png_ptr, end_info);

	double row_factor, col_factor;
	double row_offset = 0.5, col_offset = 0.5;	// for rounding

	if (preserve_aspect && aspect_w != 0 && aspect_h != 0)
	{
		row_factor = (height-1)/aspect_h;
		col_factor = (width-1)/aspect_w;
		if (row_factor < col_factor)
			col_factor = row_factor;
		else
			row_factor = col_factor;
		row_factor *= aspect_h/(double)(frame_height-1);
		col_factor *= aspect_w/(double)(frame_width-1);

		// center the pattern over the frame
		row_offset += (height-1-(frame_height-1)*row_factor)/2;
		col_offset += (width-1-(frame_width-1)*col_factor)/2;
	}
	else
	{
		// Stretch (or shrink) the pattern image to fill the frame
		row_factor = (double)(height-1)/(double)(frame_height-1);
		col_factor = (double)(width-1)/(double)(frame_width-1);
	}

	for (scaled_row = 0; scaled_row < frame_height; scaled_row++)
	{
		row = (int)(row_factor*scaled_row + row_offset);
		pattern_image[scaled_row] = (unsigned char*)malloc(sizeof(unsigned char)*frame_width);
		for (scaled_col = 0; scaled_col < frame_width; scaled_col++)
		{
			col = (int)(col_factor*scaled_col + col_offset)*pixel_width;
			value = image[row][col];
			pattern_image[scaled_row][scaled_col] = value;
			if (value < min_value) min_value = value;
			if (value > max_value) max_value = value;

		}
	}

	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	fclose(fp);
	/* Deallocate the original image as it is no longer needed */
	for (row = 0; row < height; row++)
	{
		free(image[row]);
	}
	free (image);
	return 0;
}
Пример #3
0
void FPngImageWrapper::UncompressPNGData( const ERGBFormat::Type InFormat, const int32 InBitDepth )
{
	// thread safety
	FScopeLock PNGLock(&GPNGSection);

	check( CompressedData.Num() );
	check( Width > 0 );
	check( Height > 0 );

	// Note that PNGs on PC tend to be BGR
	check( InFormat == ERGBFormat::BGRA || InFormat == ERGBFormat::RGBA || InFormat == ERGBFormat::Gray )	// Other formats unsupported at present
	check( InBitDepth == 8 || InBitDepth == 16 )	// Other formats unsupported at present

	// Reset to the beginning of file so we can use png_read_png(), which expects to start at the beginning.
	ReadOffset = 0;
		
	png_structp png_ptr	= png_create_read_struct_2( PNG_LIBPNG_VER_STRING, this, FPngImageWrapper::user_error_fn, FPngImageWrapper::user_warning_fn, NULL, FPngImageWrapper::user_malloc, FPngImageWrapper::user_free);
	check( png_ptr );

	png_infop info_ptr	= png_create_info_struct( png_ptr );
	check( info_ptr );
	PNGReadGuard PNGGuard( &png_ptr, &info_ptr );
	{
		if (ColorType == PNG_COLOR_TYPE_PALETTE)
		{
			png_set_palette_to_rgb(png_ptr);
		}

		if ((ColorType & PNG_COLOR_MASK_COLOR) == 0 && BitDepth < 8)
		{
			png_set_expand_gray_1_2_4_to_8(png_ptr);
		}

		// Insert alpha channel with full opacity for RGB images without alpha
		if ((ColorType & PNG_COLOR_MASK_ALPHA) == 0 && (InFormat == ERGBFormat::BGRA || InFormat == ERGBFormat::RGBA))
		{
			// png images don't set PNG_COLOR_MASK_ALPHA if they have alpha from a tRNS chunk, but png_set_add_alpha seems to be safe regardless
			if ((ColorType & PNG_COLOR_MASK_COLOR) == 0)
			{
				png_set_tRNS_to_alpha(png_ptr);
			}
			else if (ColorType == PNG_COLOR_TYPE_PALETTE)
			{
				png_set_tRNS_to_alpha(png_ptr);
			}
			if (InBitDepth == 8)
			{
				png_set_add_alpha(png_ptr, 0xff , PNG_FILLER_AFTER);
			}
			else if (InBitDepth == 16)
			{
				png_set_add_alpha(png_ptr, 0xffff , PNG_FILLER_AFTER);
			}
		}

		// Calculate Pixel Depth
		const uint32 PixelChannels = (InFormat == ERGBFormat::Gray) ? 1 : 4;
		const uint32 BytesPerPixel = (InBitDepth * PixelChannels) / 8;
		const uint32 BytesPerRow = BytesPerPixel * Width;
		RawData.Empty(Height * BytesPerRow);
		RawData.AddUninitialized(Height * BytesPerRow);

		png_set_read_fn( png_ptr, this, FPngImageWrapper::user_read_compressed );

		png_bytep* row_pointers = (png_bytep*) png_malloc( png_ptr, Height*sizeof(png_bytep) );
		PNGGuard.SetRowPointers(&row_pointers);
		for (int32 i = 0; i < Height; i++)
		{
			row_pointers[i]= &RawData[i * BytesPerRow];
		}
		png_set_rows(png_ptr, info_ptr, row_pointers);

		uint32 Transform = (InFormat == ERGBFormat::BGRA) ? PNG_TRANSFORM_BGR : PNG_TRANSFORM_IDENTITY;
			
		// PNG files store 16-bit pixels in network byte order (big-endian, ie. most significant bits first).
#if PLATFORM_LITTLE_ENDIAN
		// We're little endian so we need to swap
		if (BitDepth == 16)
		{
			Transform |= PNG_TRANSFORM_SWAP_ENDIAN;
		}
#endif

		// Convert grayscale png to RGB if requested
		if ((ColorType & PNG_COLOR_MASK_COLOR) == 0 &&
			(InFormat == ERGBFormat::RGBA || InFormat == ERGBFormat::BGRA))
		{
			Transform |= PNG_TRANSFORM_GRAY_TO_RGB;
		}

		// Convert RGB png to grayscale if requested
		if ((ColorType & PNG_COLOR_MASK_COLOR) != 0 && InFormat == ERGBFormat::Gray)
		{
			png_set_rgb_to_gray_fixed(png_ptr, 2 /* warn if image is in color */, -1, -1);
		}

		// Strip alpha channel if requested output is grayscale
		if (InFormat == ERGBFormat::Gray)
		{
			// this is not necessarily the best option, instead perhaps:
			// png_color background = {0,0,0};
			// png_set_background(png_ptr, &background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
			Transform |= PNG_TRANSFORM_STRIP_ALPHA;
		}

		// Reduce 16-bit to 8-bit if requested
		if (BitDepth == 16 && InBitDepth == 8)
		{
#if PNG_LIBPNG_VER >= 10504
			check(0); // Needs testing
			Transform |= PNG_TRANSFORM_SCALE_16;
#else
			Transform |= PNG_TRANSFORM_STRIP_16;
#endif
		}

		// Increase 8-bit to 16-bit if requested
		if (BitDepth <= 8 && InBitDepth == 16)
		{
#if PNG_LIBPNG_VER >= 10504
			check(0); // Needs testing
			Transform |= PNG_TRANSFORM_EXPAND_16
#else
			// Expanding 8-bit images to 16-bit via transform needs a libpng update
			check(0);
#endif
		}

		png_read_png(png_ptr, info_ptr, Transform, NULL);
	}

	RawFormat = InFormat;
	RawBitDepth = InBitDepth;
}
Пример #4
0
void load_image(char * inputname) { 
  char header[8];

  FILE * fp = fopen(inputname, "rb");
  if (!fp) {
    abort();
  } 
  fread(header, 1, 8, fp);
  if(png_sig_cmp((png_byte *)header, 0, 8))
    abort();

  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

  if (!png_ptr)
    abort();

  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
    abort();
  if (setjmp(png_jmpbuf(png_ptr)))
    abort();

  png_init_io(png_ptr, fp);
  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);
  color_type = png_get_color_type(png_ptr, info_ptr);

  if (color_type == PNG_COLOR_TYPE_RGB || PNG_COLOR_TYPE_RGB_ALPHA) 
    png_set_rgb_to_gray_fixed(png_ptr, 1, -1, -1);
                      

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



  if (setjmp(png_jmpbuf(png_ptr))) abort();

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

  for (int y = 0 ; y < height ; y++) { 
    row_pointers[y] = (png_byte *)malloc(png_get_rowbytes(png_ptr, info_ptr));
  }

  png_read_image(png_ptr, row_pointers);

  fprintf(stdout, "Example has %d pixels width and %d pixels height with %d depth\n", width, height, bit_depth);

  fclose(fp);


  




}
Пример #5
0
// PNG  8/24/32 bits
my_image *loadPNG(boost::filesystem::path & aPath, int nbytes, bool for_bmp, bool inverse)
{
    if ( nbytes != 0 && nbytes != 1 && nbytes != 3 && nbytes != 4 ) return NULL;

    FILE *fp;
    fopen_s(&fp, aPath.file_string().data(), "rb");
    if (!fp) return NULL;

    // read header
    char header[8];
    fread(header, 1, 8, fp);
    if (png_sig_cmp((png_bytep)header, 0, 8)) { // not a PNG file
        fclose(fp);
        return NULL;
    }

    // create and initialize the png_struct
    png_structp	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr) {
        fclose(fp);
        return NULL;
    }

    // allocate the memory for image information
    png_infop	info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
        fclose(fp);
        return NULL;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        // free all of the memory associated with the png_ptr and info_ptr
        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
        fclose(fp);
        return NULL;
    }

    // set up the input control (use standard C streams)
    png_init_io(png_ptr, fp);
    png_set_sig_bytes(png_ptr, 8);

    // read information from the PNG file
    png_read_info(png_ptr, info_ptr);

    // bytes per pixel in stored image
    int samples;

    png_byte	color_type	= info_ptr->color_type;
    png_byte	bit_depth	= info_ptr->bit_depth;

    // interlacing temporary not supported
    if ( info_ptr->interlace_type != PNG_INTERLACE_NONE ) {
        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
        fclose(fp);
        return NULL;
    }

    //strip 16 bit/color files down to 8 bits/color
    if (bit_depth == 16)
        png_set_strip_16(png_ptr);

    // expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_expand_gray_1_2_4_to_8(png_ptr);

    // expand paletted colors into true RGB triplets
    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png_ptr);

    switch (color_type) {
    case PNG_COLOR_TYPE_GRAY:
        samples = 1;
        break;
    case PNG_COLOR_TYPE_PALETTE:
        color_type = PNG_COLOR_TYPE_RGB;
        samples = 3;
        break;
    case PNG_COLOR_TYPE_RGB:
        samples = 3;
        break;
    case PNG_COLOR_TYPE_RGBA:
    case PNG_COLOR_TYPE_GRAY_ALPHA:
        samples = 4;
        break;
    default: // unknown color type
        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
        fclose(fp);
        return NULL;
        break;
    }

    if (nbytes == 0) nbytes = samples;

    if (nbytes == 1) {
        // convert an RGB or RGBA image to grayscale or grayscale with alpha
        if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA)
            png_set_rgb_to_gray_fixed(png_ptr, 1, 21268, 71514);
        // strip alpha bytes
        if (color_type & PNG_COLOR_MASK_ALPHA)
            png_set_strip_alpha(png_ptr);
    }

    if (nbytes == 3) {
        // convert a grayscale image to RGB
        if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
            png_set_gray_to_rgb(png_ptr);
        // strip alpha bytes
        if (color_type & PNG_COLOR_MASK_ALPHA)
            png_set_strip_alpha(png_ptr);
    }

    if (nbytes == 4) {
        // convert a grayscale image to RGB
        if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
            png_set_gray_to_rgb(png_ptr);
        // add alpha bytes
        if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY)
            png_set_add_alpha(png_ptr, 255, PNG_FILLER_AFTER);
    }

    // call to update the users info_ptr structure
    png_read_update_info(png_ptr, info_ptr);

    // allocate memory for one row
    png_byte *row_pointer = (png_byte*) malloc(info_ptr->rowbytes);

    // create new image
    my_image *image = image_create(info_ptr->width, info_ptr->height, nbytes, for_bmp);

    // can't allocate memory
    if ( !image || !row_pointer ) {
        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
        fclose(fp);
        if (row_pointer) free(row_pointer);
        if (image) image_release(image);
        return NULL;
    }

    // length of row in new image
    int rowlen	= image->width * image->nbytes;
    int height	= image->height;
    int step	= image->step;
    UCHAR *dst	= image->data;
    if (inverse) {
        dst = image->data + (height - 1) * step;
        step = -step;
    }

    // TODO: add interlacing support
    // //turn on interlace handling
    //int number_of_passes = png_set_interlace_handling(png_ptr);
    // //for interlaced image (temporary, not so good !!! )
    //for (int pass = 0; pass < number_of_passes - 1; pass++)
    //	for (j = 0; j < height; j++)
    //		png_read_rows(png_ptr, &row_pointer, png_bytepp_NULL, 1);

    for (int j = 0; j < height; j++) {
        png_read_rows(png_ptr, &row_pointer, png_bytepp_NULL, 1);
        memcpy(dst, (UCHAR*)row_pointer, rowlen);
        dst += step;
    }

    if (row_pointer) free(row_pointer);

    // read rest of file, and get additional chunks in info_ptr
    png_read_end(png_ptr, info_ptr);

    // clean up after the read, and free any memory allocated
    png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);

    fclose(fp);
    return image;
}