Example #1
0
bool YImage::save( const char* fname, bool fast )
const
{
	FILE* fp = NULL ;
	bool rval = true ;
	png_structp png_ptr = NULL ;
	png_infop info_ptr = NULL ;
	
	// Open the file for reading in binary mode.
	fp = fopen( fname, "wb" ) ;
	if( !fp )
	{
		fprintf( stderr, ERROR_STRING_OPEN, fname ) ;
		rval = false ;
		goto YImage_save_cleanup ;
	}
	
	// Allocate the png structs.
	png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ) ;
	if( !png_ptr )
	{
		fprintf( stderr, ERROR_STRING_WRITING, fname ) ;
		rval = false ;
		goto YImage_save_cleanup ;
	}
	info_ptr = png_create_info_struct( png_ptr ) ;
	if( !info_ptr )
	{
		fprintf( stderr, ERROR_STRING_WRITING, fname ) ;
		rval = false ;
		goto YImage_save_cleanup ;
    }
	
	// Set up the png error routine.
	if( setjmp(png_jmpbuf(png_ptr)) )
	{
		fprintf( stderr, ERROR_STRING_WRITING, fname ) ;
		rval = false ;
		goto YImage_save_cleanup ;
    }
	
	// Give libpng the FILE*.
	// png_init_io( png_ptr, fp ) ;
	// or
	// use our own write callback
	png_set_write_fn( png_ptr, fp, (png_rw_ptr) user_write_data, user_flush_data ) ;
	
	// We'll use the low-level interface since the high-level interface won't handle
	// png_set_filler() which we need to tell libpng to strip out the A from our
	// 4-byte pixels.
	
	// First we set and write the info struct.
	png_set_IHDR(
		png_ptr, info_ptr,
		m_width, m_height,
		8, PNG_COLOR_TYPE_RGB_ALPHA,
		PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
		) ;
	png_write_info( png_ptr, info_ptr ) ;
	
	// If we've been asked to write quickly, speed up the compression.
	if( fast ) png_set_compression_level( png_ptr, Z_BEST_SPEED );
	
	// Then we set up transforms.
	/*
	// 1. tell libpng to strip out the filler byte in our 4-byte pixels
	// if YPixel::a comes after any other member (b,g,r), we strip AFTER
	if( offsetof( YPixel, a ) > offsetof( YPixel, b ) ) {
		png_set_filler( png_ptr, 0, PNG_FILLER_AFTER ) ;
		// printf("alpha after\n");
	} else {
		png_set_filler( png_ptr, 0, PNG_FILLER_BEFORE ) ;
		// printf("alpha before\n");
	}
	*/
	if( offsetof( YPixel, a ) < offsetof( YPixel, b ) )
		png_set_swap_alpha( png_ptr ) ;
	// 2. tell libpng how our color triples are stored (b < r or vice versa)
	if( offsetof( YPixel, b ) < offsetof( YPixel, r ) )
	{
		png_set_bgr( png_ptr ) ;
		// printf("bgr\n") ;
	}
	// else { printf("rgb\n"); }
	// printf( "offsetof r, b: %d %d\n", offsetof( YPixel, r ), offsetof( YPixel, b ) );
	
	// Finally we create a row_pointers[] pointing into our data* and write the png out to the FILE*.
	{
		// 1. allocate row pointers array
		png_bytep* row_pointers = (png_bytep*) png_malloc( png_ptr, m_height * sizeof(png_bytep) ) ;
		// 2. point row pointers into m_data
		for( int i = 0 ; i < m_height ; ++i ) {
			row_pointers[i] = (png_bytep) (m_data + i*m_width) ;
		}
		// 3. write the image data
		png_write_image( png_ptr, row_pointers ) ;
		// 4. free row pointers array
		png_free( png_ptr, row_pointers ) ;
	}
	
	// Write out end info.  We're done.  Fall through to cleanup.
	png_write_end( png_ptr, NULL ) ;
	
YImage_save_cleanup:
	png_destroy_write_struct( png_ptr ? &png_ptr : NULL, info_ptr ? &info_ptr : NULL ) ;
	if( fp ) fclose( fp ) ;
	
	return rval ;
}
Example #2
0
int main(int argc, char *argv[]) {
    char infile[255];
    char outfile[255] = "";
    char fmt_s[255];
    char window_s[255] = "blackman";

    // Default args.
    format_t fmt = FORMAT_FLOAT32;
    int verbose = 0;
    uint64_t skip = 0;

    waterfall_params_t params;
    params.overlap = 0;
    params.fftsize = 2048;
    params.clip = 0;

    int c;
    struct option long_options[] = {/*These options set a flag.*/
                                    {"verbose", no_argument, &verbose, 1},
                                    {"brief", no_argument, &verbose, 0},
                                    /*These options don’t set a flag.*/
                                    /*We distinguish them by their indices.*/
                                    {"help", no_argument, NULL, 'h'},
                                    {"fftsize", required_argument, NULL, 'n'},
                                    {"format", required_argument, NULL, 'f'},
                                    {"window", required_argument, NULL, 'w'},
                                    {"outfile", required_argument, NULL, 'o'},
                                    {"offset", required_argument, NULL, 's'},
                                    {"overlap", required_argument, NULL, 'l'},
                                    {"clip", required_argument, NULL, 'c'},
                                    {"beta", required_argument, NULL, 'b'},
                                    {0, 0, 0, 0}

    };

    int option_index;
    while ((c = getopt_long(argc, argv, "hvf:n:o:s:w:l:c:", long_options,
                            &option_index)) != -1) {
        switch (c) {
        case 0:
            // Flag option
            break;
        case 'h':
            usage(argv[0]);
            return EXIT_SUCCESS;
        case 'v':
            verbose = true;
            break;
        case 'n':
            if (!parse_uint32_t(optarg, &(params.fftsize))) {
                fprintf(stderr, "Invalid fftsize: %s\n", optarg);
                return EXIT_FAILURE;
            }
            if (!is_power_of_2(params.fftsize)) {
                fprintf(stderr, "Invalid fftsize (must be power of 2): %s\n",
                        optarg);
                return EXIT_FAILURE;
            }
            break;
        case 'l':
            if (!parse_uint32_t(optarg, &(params.overlap))) {
                fprintf(stderr, "Invalid overlap: %s\n", optarg);
                return EXIT_FAILURE;
            }
            break;
        case 'f':
            strcpy(fmt_s, optarg);
            if (parse_format(&fmt, fmt_s) < 0) {
                fprintf(stderr, "Unknown format: %s\n", optarg);
                return EXIT_FAILURE;
            }
            break;
        case 'w':
            strcpy(window_s, optarg);
            break;
        case 'o':
            strcpy(outfile, optarg);
            break;
        case 's':
            if (!parse_uint64_t(optarg, &skip)) {
                fprintf(stderr, "Invalid value for byte offset\n");
                return EXIT_FAILURE;
            }
            break;
        case 'b':
            if (!parse_double(optarg, &beta)) {
                fprintf(stderr, "Invalid value for beta\n");
                return EXIT_FAILURE;
            }
            break;
        case 'c':
            if (!parse_uint64_t(optarg, &(params.clip))) {
                fprintf(stderr, "Invalid value for clip\n");
                return EXIT_FAILURE;
            }
            break;
        case '?':
            if (optopt == 'c')
                fprintf(stderr, "Option -%c requires an argument.\n", optopt);
            else if (isprint(optopt))
                fprintf(stderr, "Unknown option `-%c'.\n", optopt);
            else
                fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
            usage(argv[0]);
            return EXIT_FAILURE;
        default:
            fprintf(stderr, "Error parsing arguments.\n");
            return EXIT_FAILURE;
        }
    }

    if ((argc - optind) > 1) {
        fprintf(stderr, "Excess arguments.\n");
        usage(argv[0]);
        return EXIT_FAILURE;
    } else if ((argc - optind) < 1) {
        fprintf(stderr, "Must supply an input filename.\n");
        usage(argv[0]);
        return EXIT_FAILURE;
    }

    window_t win;
    if (prepare_window(&win, window_s, params.fftsize, verbose) < 0) {
        fprintf(stderr, "Unknown window function: %s", window_s);
        return EXIT_FAILURE;
    }
    params.win = win;

    if (verbose)
        printf("Opening input file...\n");

    strcpy(infile, argv[optind]);

    FILE *readfp = fopen(infile, "rb");
    if (readfp == NULL) {
        fprintf(stderr, "Failed to open input file: %s\n", infile);
        return EXIT_FAILURE;
    }

    fseek(readfp, 0, SEEK_END);
    int size = ftell(readfp);
    fseek(readfp, skip, SEEK_SET);

    size_t sample_size;
    read_samples_fn reader;
    switch (fmt) {
    case FORMAT_INT8:
        sample_size = sizeof(int8_t) * 2;
        reader = read_samples_int8;
        break;
    case FORMAT_UINT8:
        sample_size = sizeof(uint8_t) * 2;
        reader = read_samples_uint8;
        break;
    case FORMAT_INT16:
        sample_size = sizeof(int16_t) * 2;
        reader = read_samples_int16;
        break;
    case FORMAT_UINT16:
        sample_size = sizeof(uint16_t) * 2;
        reader = read_samples_uint16;
        break;
    case FORMAT_INT32:
        sample_size = sizeof(int32_t) * 2;
        reader = read_samples_int32;
        break;
    case FORMAT_UINT32:
        sample_size = sizeof(uint32_t) * 2;
        reader = read_samples_uint32;
        break;
    case FORMAT_FLOAT32:
        sample_size = sizeof(float) * 2;
        reader = read_samples_float32;
        break;
    case FORMAT_FLOAT64:
        sample_size = sizeof(double) * 2;
        reader = read_samples_float64;
        break;
    }
    params.reader = reader;

    uint64_t nsamples = size / sample_size;
    if ((params.clip > 0) && (nsamples > params.clip)) {
        nsamples = params.clip;
    }

    if (params.overlap > params.fftsize) {
        fprintf(stderr, "Overlap of %d is greater than FFT frame size of %d.\n",
                params.overlap, params.fftsize);
        return EXIT_FAILURE;
    }

    params.frames = nsamples / (params.fftsize - params.overlap);

    if (!strcmp(outfile, "")) {
        strcpy(outfile, infile);
        strcat(outfile, ".png");
    }

    if (verbose) {
        printf("Reading %s samples from %s...\n", fmt_s, infile);
        printf("Writing %d x %d output to %s...\n", params.fftsize,
               params.frames, outfile);
    }

    FILE *writefp = fopen(outfile, "wb");
    if (!writefp) {
        fprintf(stderr, "Error: failed to write to %s.\n", outfile);
        return EXIT_FAILURE;
    }

    png_structp png_ptr =
        png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr) {
        fprintf(stderr, "Error: could not initialize write struct.\n");
        return EXIT_FAILURE;
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        fprintf(stderr, "Error: could not initialize info struct.\n");
        png_destroy_write_struct(&png_ptr, NULL);
        return EXIT_FAILURE;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        fprintf(stderr, "Error: libpng error.\n");
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(writefp);
        return EXIT_FAILURE;
    }

    if (verbose)
        printf("Writing PNG header..\n");
    png_init_io(png_ptr, writefp);
    png_set_IHDR(png_ptr, info_ptr, params.fftsize, params.frames, 8,
                 PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
    png_write_info(png_ptr, info_ptr);

    if (verbose)
        printf("Rendering (this may take a while)...\n");
    waterfall(png_ptr, readfp, params);

    if (verbose)
        printf("Writing PNG footer...\n");
    png_write_end(png_ptr, NULL);

    png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
    png_destroy_write_struct(&png_ptr, NULL);

    if (verbose)
        printf("Cleaning up...\n");
    fclose(writefp);
    fclose(readfp);

    destroy_window(win);

    if (verbose)
        print_scale_stats();

    return EXIT_SUCCESS;
}
char *sng_load_png_texture(const char *filename, int flipVertical, int flipHorizontal, int pre_multiply_alpha,
	int *w, int *h, int *hasAlpha, char *whynot, int whynotlen)
{
#ifndef WITHOUTOPENGL
	int i, j, bit_depth, color_type, row_bytes, image_data_row_bytes;
	png_byte header[8];
	png_uint_32 tw, th;
	png_structp png_ptr = NULL;
	png_infop info_ptr = NULL;
	png_infop end_info = NULL;
	png_byte *image_data = NULL;

	FILE *fp = fopen(filename, "rb");
	if (!fp) {
		snprintf(whynot, whynotlen, "Failed to open '%s': %s",
			filename, strerror(errno));
		return 0;
	}

	if (fread(header, 1, 8, fp) != 8) {
		snprintf(whynot, whynotlen, "Failed to read 8 byte header from '%s'\n",
				filename);
		goto cleanup;
	}
	if (png_sig_cmp(header, 0, 8)) {
		snprintf(whynot, whynotlen, "'%s' isn't a png file.",
			filename);
		goto cleanup;
	}

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
							NULL, NULL, NULL);
	if (!png_ptr) {
		snprintf(whynot, whynotlen,
			"png_create_read_struct() returned NULL");
		goto cleanup;
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr) {
		snprintf(whynot, whynotlen,
			"png_create_info_struct() returned NULL");
		goto cleanup;
	}

	end_info = png_create_info_struct(png_ptr);
	if (!end_info) {
		snprintf(whynot, whynotlen,
			"2nd png_create_info_struct() returned NULL");
		goto cleanup;
	}

	if (setjmp(png_jmpbuf(png_ptr))) {
		snprintf(whynot, whynotlen, "libpng encounted an error");
		goto cleanup;
	}

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

	/*
	 * PNG_TRANSFORM_STRIP_16 |
	 * PNG_TRANSFORM_PACKING  forces 8 bit
	 * PNG_TRANSFORM_EXPAND forces to expand a palette into RGB
	 */
	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL);

	png_get_IHDR(png_ptr, info_ptr, &tw, &th, &bit_depth, &color_type, NULL, NULL, NULL);

	if (bit_depth != 8) {
		snprintf(whynot, whynotlen, "load_png_texture only supports 8-bit image channel depth");
		goto cleanup;
	}

	if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
		snprintf(whynot, whynotlen, "load_png_texture only supports RGB and RGBA");
		goto cleanup;
	}

	if (w)
		*w = tw;
	if (h)
		*h = th;
	int has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA);
	if (hasAlpha)
		*hasAlpha = has_alpha;

	row_bytes = png_get_rowbytes(png_ptr, info_ptr);
	image_data_row_bytes = row_bytes;

	/* align to 4 byte boundary */
	if (image_data_row_bytes & 0x03)
		image_data_row_bytes += 4 - (image_data_row_bytes & 0x03);

	png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr);

	image_data = malloc(image_data_row_bytes * th * sizeof(png_byte) + 15);
	if (!image_data) {
		snprintf(whynot, whynotlen, "malloc failed in load_png_texture");
		goto cleanup;
	}

	int bytes_per_pixel = (color_type == PNG_COLOR_TYPE_RGB_ALPHA ? 4 : 3);

	for (i = 0; i < th; i++) {
		png_byte *src_row;
		png_byte *dest_row = image_data + i * image_data_row_bytes;

		if (flipVertical)
			src_row = row_pointers[th - i - 1];
		else
			src_row = row_pointers[i];

		if (flipHorizontal) {
			for (j = 0; j < tw; j++) {
				png_byte *src = src_row + bytes_per_pixel * j;
				png_byte *dest = dest_row + bytes_per_pixel * (tw - j - 1);
				memcpy(dest, src, bytes_per_pixel);
			}
		} else {
			memcpy(dest_row, src_row, row_bytes);
		}

		if (has_alpha && pre_multiply_alpha) {
			for (j = 0; j < tw; j++) {
				png_byte *pixel = dest_row + bytes_per_pixel * j;
				float alpha = pixel[3] / 255.0;
				pixel[0] = pixel[0] * alpha;
				pixel[1] = pixel[1] * alpha;
				pixel[2] = pixel[2] * alpha;
			}
		}
	}

	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	fclose(fp);
	return (char *)image_data;

cleanup:
	if (image_data)
		free(image_data);
	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
	fclose(fp);
#else
	snprintf(whynot, whynotlen, "load_png_texture: compiled without opengl support.");
#endif
	return 0;
}
Example #4
0
short load_inp_png_file(ImageData& img, const std::string& fname_inp, ProgramOptions& opts)
{
    FILE* pngfile = fopen(fname_inp.c_str(),"rb");
    if (pngfile == NULL) {
        perror(fname_inp.c_str());
        return ERR_CANT_OPEN;
    }
    png_byte header[8];
    if (fread(header,8,1,pngfile) != 1) {
        perror(fname_inp.c_str());
        fclose(pngfile);
        return ERR_FILE_READ;
    }
    if (png_sig_cmp(header,0,8)) {
        LogErr("%s: Not a PNG file",fname_inp.c_str());
        fclose(pngfile);
        return ERR_BAD_FILE;
    }

    img.png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!img.png_ptr)
    {
        LogErr("%s: png_create_read_struct error",fname_inp.c_str());
        fclose(pngfile);
        return ERR_BAD_FILE;
    }

    img.info_ptr=png_create_info_struct(img.png_ptr);
    if (!img.info_ptr)
    {
        png_destroy_read_struct(&img.png_ptr, (png_infopp)NULL, (png_infopp)NULL);
        LogErr("%s: png_create_info_struct error",fname_inp.c_str());
        fclose(pngfile);
        return ERR_BAD_FILE;
    }

    img.end_info=png_create_info_struct(img.png_ptr);
    if (!img.end_info)
    {
        png_destroy_read_struct(&img.png_ptr, &img.info_ptr, (png_infopp)NULL);
        LogErr("%s: png_create_info_struct error",fname_inp.c_str());
        fclose(pngfile);
        return ERR_BAD_FILE;
    }

    if (setjmp(png_jmpbuf(img.png_ptr)))
    {
        png_destroy_read_struct(&img.png_ptr, &img.info_ptr, &img.end_info);
        LogErr("%s: PNG error",fname_inp.c_str());
        fclose(pngfile);
        exit(1);
    }

    png_init_io(img.png_ptr, pngfile);
    png_set_sig_bytes(img.png_ptr,8);
    int trafo=PNG_TRANSFORM_PACKING|PNG_TRANSFORM_STRIP_16|PNG_TRANSFORM_EXPAND;
    png_read_png(img.png_ptr, img.info_ptr, trafo , NULL);

    int bit_depth, interlace_type, compression_type, filter_method;
    png_get_IHDR(img.png_ptr, img.info_ptr, &img.width, &img.height, &bit_depth, &img.color_type,
        &interlace_type, &compression_type, &filter_method);

    if ((img.color_type & PNG_COLOR_MASK_COLOR)==0)
    {
        LogErr("%s: Grayscale image not supported",fname_inp.c_str());
        fclose(pngfile);
        return ERR_BAD_FILE;
    }

    fclose(pngfile);

    if (img.color_type==PNG_COLOR_TYPE_PALETTE)
    {
        LogErr("Invalid format. This shouldn't happen. PNG_TRANSFORM_EXPAND transforms image to RGB.");
        return ERR_BAD_FILE;
    }

    if (img.color_type & PNG_COLOR_MASK_ALPHA) {
        img.col_bits = 32;
    } else {
        img.col_bits = 24;
    }

    return ERR_OK;
}
Example #5
0
static GstFlowReturn
gst_pngdec_chain (GstPad * pad, GstBuffer * buffer)
{
  GstPngDec *pngdec;
  GstFlowReturn ret = GST_FLOW_OK;

  pngdec = GST_PNGDEC (gst_pad_get_parent (pad));

  GST_LOG_OBJECT (pngdec, "Got buffer, size=%u", GST_BUFFER_SIZE (buffer));

  if (G_UNLIKELY (!pngdec->setup))
    goto not_configured;

  /* Something is going wrong in our callbacks */
  ret = pngdec->ret;
  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
    GST_WARNING_OBJECT (pngdec, "we have a pending return code of %d", ret);
    goto beach;
  }

  /* Let libpng come back here on error */
  if (setjmp (png_jmpbuf (pngdec->png))) {
    GST_WARNING_OBJECT (pngdec, "error during decoding");
    ret = GST_FLOW_ERROR;
    goto beach;
  }

  pngdec->in_timestamp = GST_BUFFER_TIMESTAMP (buffer);
  pngdec->in_duration = GST_BUFFER_DURATION (buffer);

  /* Progressive loading of the PNG image */
  png_process_data (pngdec->png, pngdec->info, GST_BUFFER_DATA (buffer),
      GST_BUFFER_SIZE (buffer));

  if (pngdec->image_ready) {
    if (pngdec->framed) {
      /* Reset ourselves for the next frame */
      gst_pngdec_libpng_clear (pngdec);
      gst_pngdec_libpng_init (pngdec);
      GST_LOG_OBJECT (pngdec, "setting up callbacks for next frame");
      png_set_progressive_read_fn (pngdec->png, pngdec,
          user_info_callback, user_endrow_callback, user_end_callback);
    } else {
      GST_LOG_OBJECT (pngdec, "sending EOS");
      pngdec->ret = gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
    }
    pngdec->image_ready = FALSE;
  }

  /* grab new return code */
  ret = pngdec->ret;

  /* And release the buffer */
  gst_buffer_unref (buffer);

beach:
  gst_object_unref (pngdec);

  return ret;

  /* ERRORS */
not_configured:
  {
    GST_LOG_OBJECT (pngdec, "we are not configured yet");
    ret = GST_FLOW_WRONG_STATE;
    goto beach;
  }
}
Example #6
0
void CachedTexture::reload() {
    //..... load file ......
    GLenum internal_format = GL_RGB;
    GLenum data_format = GL_RGB;
    unsigned char *data = NULL;
    if (filename.size() >= 4 && filename.substr(filename.size()-4,4) == ".png") {
        //Load a png file, as per the libpng docs:
        FILE *fp = fopen(filename.c_str(), "rb");
        if (!fp) {
            cerr << "  cannot open file." << endl;
            return;
        }
        png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL);
        if (!png) {
            cerr << "  cannot alloc read struct." << endl;
            fclose(fp);
            return;
        }
        png_infop info = png_create_info_struct(png);
        if (!info) {
            cerr << "  cannot alloc info struct." << endl;
            png_destroy_read_struct(&png, (png_infopp)NULL, (png_infopp)NULL);
            fclose(fp);
            return;
        }
        png_bytep *row_pointers = NULL;
        if (setjmp(png_jmpbuf(png))) {
            cerr << "  png interal error." << endl;
            png_destroy_read_struct(&png, &info, (png_infopp)NULL);
            if (data != NULL) delete[] data;
            if (row_pointers != NULL) delete[] row_pointers;
            fclose(fp);
            return;
        }
        png_init_io(png, fp);
        png_read_info(png, info);
        w = png_get_image_width(png, info);
        h = png_get_image_height(png, info);
        {   //find power-of-two dimensions...
            tw = 1;
            while (tw < w) tw *= 2;
            th = 1;
            while (th < h) th *= 2;
        }
        if (!pad && (tw != w || th != h)) {
            if (!have_ARB_texture_non_power_of_two()) {
                cerr << "WARNING: trying to load texture of size " << w << " x " << h << ", but non-power-of-two textures not supported." << endl;
            }
            tw = w;
            th = h;
        }
        if (png_get_color_type(png, info) == PNG_COLOR_TYPE_PALETTE)
            png_set_palette_to_rgb(png);
        if (png_get_bit_depth(png, info) < 8)
            png_set_packing(png);
        if (png_get_bit_depth(png,info) == 16)
            png_set_strip_16(png);
        png_read_update_info(png, info);
        unsigned int rowbytes = png_get_rowbytes(png, info);
        //Make sure it's the format we think it is...
        bool problem = false;
        if (png_get_color_type(png, info) == PNG_COLOR_TYPE_GRAY) {
            data_format = internal_format = GL_LUMINANCE;
            if (rowbytes != w*1) problem = true;
        } else if (png_get_color_type(png, info) == PNG_COLOR_TYPE_GRAY_ALPHA) {
            data_format = internal_format = GL_LUMINANCE_ALPHA;
            if (rowbytes != w*2) problem = true;
        } else if (png_get_color_type(png, info) == PNG_COLOR_TYPE_PALETTE || png_get_color_type(png, info) == PNG_COLOR_TYPE_RGB) {
            data_format = internal_format = GL_RGB;
            if (rowbytes != w*3) problem = true;
        } else if (png_get_color_type(png, info) == PNG_COLOR_TYPE_RGB_ALPHA) {
            data_format = internal_format = GL_RGBA;
            if (rowbytes != w*4) problem = true;
        } else {
            cerr << "  unknown color format." << endl;
            problem = true;
        }
        if (problem) {
            cerr << "  color format problem. (rowbytes: " << rowbytes << " w:" << w << ")" << endl;
            png_destroy_read_struct(&png, &info, NULL);
            fclose(fp);
            return;
        }

        unsigned int pixelbytes = rowbytes / w;
        assert(rowbytes == pixelbytes * w); //sanity check, should have bailed earlier if this was the case.
        data = new uint8_t[th*tw*pixelbytes];
        row_pointers = new png_bytep[th];
        if (flip) {
            //texture origin goes top-left, as in most images:
            for (unsigned int r = 0; r < th; ++r) {
                row_pointers[r] = (png_bytep)(data + r*pixelbytes*tw);
            }
        } else {
            //texture origin goes bottom-left, as GL says:
            for (unsigned int r = 0; r < th; ++r) {
                row_pointers[th-1-r] = (png_bytep)(data + r*tw*pixelbytes);
            }
        }
        png_read_image(png, row_pointers);
        png_destroy_read_struct(&png, &info, NULL);
        fclose(fp);
        delete[] row_pointers;

        if (pad && h != 0 && w != 0) {
            //duplicate the last column accross the texture:
            for (unsigned int r = 0; r < h; ++r) {
                for (unsigned int c = w; c < tw; ++c) {
                    memcpy(&(data[(r*tw+c)*pixelbytes]), &(data[(r*tw+w-1)*pixelbytes]),pixelbytes);
                }
            }
            //duplicate the last row down the texture:
            for (unsigned int r = h; r < th; ++r) {
                memcpy(&(data[r*pixelbytes*tw]), &(data[(h-1)*pixelbytes*tw]), pixelbytes*tw);
            }
        }
    } else {
        //well, not a supported image type I'm afraid.
        cerr << "  unknown image type." << endl;
        return;
    }

    glGenTextures(1, &obj);
    glBindTexture(GL_TEXTURE_2D, obj);
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, internal_format, tw, th, 0, data_format, GL_UNSIGNED_BYTE, data);
    glBindTexture(GL_TEXTURE_2D, 0);
    glPopClientAttrib();
    delete[] data;

    loaded = true;
    gl_errors("CachedTexture::reload()");

}
Example #7
0
int read_png_file(const char *file, int32 *pwidth, int32 *pheight, uint8 **image_data_ptr)
{
	FILE         *infile;         /* PNG file pointer */
	png_structp   png_ptr;        /* internally used by libpng */
	png_infop     info_ptr;       /* user requested transforms */
	
	uint8 *image_data;      /* raw png image data */
	char         sig[8];           /* PNG signature array */
	/*char         **row_pointers;   */
	
	int           bit_depth;
	int           color_type;
	
	png_uint_32 width;            /* PNG image width in pixels */
	png_uint_32 height;           /* PNG image height in pixels */
	unsigned int rowbytes;         /* raw bytes at row n in image */
	
	image_data = NULL;
	int i;
	png_bytepp row_pointers = NULL;
	
	/* Open the file. */
	infile = fopen(file, "rb");
	if (!infile) {
		
		return 0;
	}
	
	
	/*
	 * 		13.3 readpng_init()
	 */
	
	/* Check for the 8-byte signature */
	fread(sig, 1, 8, infile);
	
	if (png_sig_cmp((unsigned char *) sig, 0, 8) != 0) {
		fclose(infile);
		return 0;
	}
	
	/* 
	 * Set up the PNG structs 
	 */
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!png_ptr) {
		fclose(infile);
		return 4;    /* out of memory */
	}
	
	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr) {
		png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
		fclose(infile);
		return 4;    /* out of memory */
	}
	
	
	/*
	 * block to handle libpng errors, 
	 * then check whether the PNG file had a bKGD chunk
	 */
	if (setjmp(png_jmpbuf(png_ptr))) {
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(infile);
		return 0;
	}
	
	/* 
	 * takes our file stream pointer (infile) and 
	 * stores it in the png_ptr struct for later use.
	 */
	/* png_ptr->io_ptr = (png_voidp)infile;*/
	png_init_io(png_ptr, infile);
	
	/*
	 * lets libpng know that we already checked the 8 
	 * signature bytes, so it should not expect to find 
	 * them at the current file pointer location
	 */
	png_set_sig_bytes(png_ptr, 8);
	
	/* Read the image info.*/
	
	/*
	 * reads and processes not only the PNG file's IHDR chunk 
	 * but also any other chunks up to the first IDAT 
	 * (i.e., everything before the image data).
	 */
	
	/* read all the info up to the image data  */
	png_read_info(png_ptr, info_ptr);
	
	png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, 
				 &color_type, NULL, NULL, NULL);
	
	*pwidth = width;
	*pheight = height;

	if (bit_depth > 8) {
		png_set_strip_16(png_ptr);
	}
#if defined(__DAVAENGINE_WIN32__)
	if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
#endif
    
	if (color_type == PNG_COLOR_TYPE_GRAY ||
		color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
		png_set_gray_to_rgb(png_ptr);
		png_set_filler(png_ptr, 0xFFFF, PNG_FILLER_AFTER);
	}
	if (color_type == PNG_COLOR_TYPE_PALETTE) {
		png_set_palette_to_rgb(png_ptr);
		png_set_filler(png_ptr, 0xFFFF, PNG_FILLER_AFTER);
	}

	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
	{
		png_set_tRNS_to_alpha(png_ptr);
		if (CommandLineParser::Instance()->GetVerbose())
			printf("*** TOCHECK: convert tRNS to alpha\n");
	}

	if (color_type == PNG_COLOR_TYPE_RGB)
	{	
		if (CommandLineParser::Instance()->GetVerbose())
			printf("*** Converting %s from RGB to RGBA\n", file);
		png_set_filler(png_ptr, 0xFFFF, PNG_FILLER_AFTER);
	}
		
	/* Update the png info struct.*/
	png_read_update_info(png_ptr, info_ptr);
	
	/* Rowsize in bytes. */
	rowbytes = png_get_rowbytes(png_ptr, info_ptr);
	
	char string_format[16];
	strcpy(string_format, "undefined");
	if (color_type == PNG_COLOR_TYPE_RGBA)
	{
		strcpy(string_format, "RGBA");
	}
	
	
	if (CommandLineParser::Instance()->GetVerbose())
	{
		printf("* Reading PNG file: %s format: %s bit_depth:%d bytes_per_pixel:%d\n", 
		   file,
		   string_format,
		   bit_depth,
		   rowbytes / width);
	}	
	
	/* Allocate the image_data buffer. */
	// printf("r/w: %d %d\n" , rowbytes / width, bit_depth); 
	
	
	if ((image_data = new uint8 [rowbytes * height]) ==NULL) 
	{
		memset(image_data, 0, rowbytes * height);
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		return 4;
    }
	
	if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) 
	{
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        delete [] (image_data);
        image_data = NULL;
        return 4;
    }
	
	
    /* set the individual row_pointers to point at the correct offsets */
	
    for (i = 0;  i < (int)height;  ++i)
        row_pointers[i] = image_data + i*rowbytes;
	
	
    /* now we can go ahead and just read the whole image */
    png_read_image(png_ptr, row_pointers);
	
    /* and we're done!  (png_read_end() can be omitted if no processing of
     * post-IDAT text/time/etc. is desired) */
	
	/* Clean up. */
	free(row_pointers);
	
	/* Clean up. */
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	fclose(infile);
	
	*image_data_ptr = image_data;
	
	return 1;
}
Example #8
0
static int save_png_to_file (bitmap_t *bitmap, const char *path)
{
    FILE * fp;
    png_structp png_ptr = NULL;
    png_infop info_ptr = NULL;
    size_t x, y;
    png_byte ** row_pointers = NULL;
    /* "status" contains the return value of this function. At first
       it is set to a value which means 'failure'. When the routine
       has finished its work, it is set to a value which means
       'success'. */
    int status = -1;
    /* The following number is set by trial and error only. I cannot
       see where it it is documented in the libpng manual.
    */
    int pixel_size = 3;
    int depth = 8;

    fp = fopen (path, "wb");
    if (! fp) {
        goto fopen_failed;
    }

    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL) {
        goto png_create_write_struct_failed;
    }

    info_ptr = png_create_info_struct (png_ptr);
    if (info_ptr == NULL) {
        goto png_create_info_struct_failed;
    }

    /* Set up error handling. */

    if (setjmp (png_jmpbuf (png_ptr))) {
        goto png_failure;
    }

    /* Set image attributes. */

    png_set_IHDR (png_ptr,
                  info_ptr,
                  bitmap->width,
                  bitmap->height,
                  depth,
                  PNG_COLOR_TYPE_RGB,
                  PNG_INTERLACE_NONE,
                  PNG_COMPRESSION_TYPE_DEFAULT,
                  PNG_FILTER_TYPE_DEFAULT);

    /* Initialize rows of PNG. */

    row_pointers = png_malloc (png_ptr, bitmap->height * sizeof (png_byte *));
    for (y = 0; y < bitmap->height; ++y) {
        png_byte *row =
            png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * pixel_size);
        row_pointers[y] = row;
        for (x = 0; x < bitmap->width; ++x) {
            pixel_t * pixel = pixel_at (bitmap, x, y);
            *row++ = pixel->red;
            *row++ = pixel->green;
            *row++ = pixel->blue;
        }
    }

    /* Write the image data to "fp". */

    png_init_io (png_ptr, fp);
    png_set_rows (png_ptr, info_ptr, row_pointers);
    png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

    /* The routine has successfully written the file, so we set
       "status" to a value which indicates success. */

    status = 0;

    for (y = 0; y < bitmap->height; y++) {
        png_free (png_ptr, row_pointers[y]);
    }
    png_free (png_ptr, row_pointers);

png_failure:
png_create_info_struct_failed:
    png_destroy_write_struct (&png_ptr, &info_ptr);
png_create_write_struct_failed:
    fclose (fp);
fopen_failed:
    return status;
}
Example #9
0
static GstFlowReturn
gst_pngenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
{
  GstPngEnc *pngenc;
  gint row_index;
  png_byte **row_pointers;
  GstFlowReturn ret = GST_FLOW_OK;
  GstVideoInfo *info;
  GstVideoFrame vframe;

  pngenc = GST_PNGENC (encoder);
  info = &pngenc->input_state->info;

  GST_DEBUG_OBJECT (pngenc, "BEGINNING");

  /* initialize png struct stuff */
  pngenc->png_struct_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,
      (png_voidp) NULL, user_error_fn, user_warning_fn);
  if (pngenc->png_struct_ptr == NULL)
    goto struct_init_fail;

  pngenc->png_info_ptr = png_create_info_struct (pngenc->png_struct_ptr);
  if (!pngenc->png_info_ptr)
    goto png_info_fail;

  /* non-0 return is from a longjmp inside of libpng */
  if (setjmp (png_jmpbuf (pngenc->png_struct_ptr)) != 0)
    goto longjmp_fail;

  png_set_filter (pngenc->png_struct_ptr, 0,
      PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE);
  png_set_compression_level (pngenc->png_struct_ptr, pngenc->compression_level);

  png_set_IHDR (pngenc->png_struct_ptr,
      pngenc->png_info_ptr,
      GST_VIDEO_INFO_WIDTH (info),
      GST_VIDEO_INFO_HEIGHT (info),
      pngenc->depth,
      pngenc->png_color_type,
      PNG_INTERLACE_NONE,
      PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

  png_set_write_fn (pngenc->png_struct_ptr, pngenc,
      (png_rw_ptr) user_write_data, user_flush_data);

  row_pointers = g_new (png_byte *, GST_VIDEO_INFO_HEIGHT (info));
  if (!gst_video_frame_map (&vframe, &pngenc->input_state->info,
          frame->input_buffer, GST_MAP_READ)) {
    GST_ELEMENT_ERROR (pngenc, STREAM, FORMAT, (NULL),
        ("Failed to map video frame, caps problem?"));
    ret = GST_FLOW_ERROR;
    goto done;
  }

  for (row_index = 0; row_index < GST_VIDEO_INFO_HEIGHT (info); row_index++) {
    row_pointers[row_index] = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0) +
        (row_index * GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0));
  }

  /* allocate the output buffer */
  pngenc->buffer_out = gst_buffer_new ();

  png_write_info (pngenc->png_struct_ptr, pngenc->png_info_ptr);
  png_write_image (pngenc->png_struct_ptr, row_pointers);
  png_write_end (pngenc->png_struct_ptr, NULL);

  g_free (row_pointers);
  gst_video_frame_unmap (&vframe);

  png_destroy_info_struct (pngenc->png_struct_ptr, &pngenc->png_info_ptr);
  png_destroy_write_struct (&pngenc->png_struct_ptr, (png_infopp) NULL);

  /* Set final size and store */
  frame->output_buffer = pngenc->buffer_out;

  pngenc->buffer_out = NULL;

  if ((ret = gst_video_encoder_finish_frame (encoder, frame)) != GST_FLOW_OK)
    goto done;

  if (pngenc->snapshot)
    ret = GST_FLOW_EOS;

done:
  GST_DEBUG_OBJECT (pngenc, "END, ret:%d", ret);

  return ret;

  /* ERRORS */
struct_init_fail:
  {
    GST_ELEMENT_ERROR (pngenc, LIBRARY, INIT, (NULL),
        ("Failed to initialize png structure"));
    return GST_FLOW_ERROR;
  }

png_info_fail:
  {
    png_destroy_write_struct (&(pngenc->png_struct_ptr), (png_infopp) NULL);
    GST_ELEMENT_ERROR (pngenc, LIBRARY, INIT, (NULL),
        ("Failed to initialize the png info structure"));
    return GST_FLOW_ERROR;
  }

longjmp_fail:
  {
    png_destroy_write_struct (&pngenc->png_struct_ptr, &pngenc->png_info_ptr);
    GST_ELEMENT_ERROR (pngenc, LIBRARY, FAILED, (NULL),
        ("returning from longjmp"));
    return GST_FLOW_ERROR;
  }
}
Example #10
0
void _mapcache_imageio_png_decode_to_image(mapcache_context *ctx, mapcache_buffer *buffer,
      mapcache_image *img) {
   int bit_depth,color_type,i;
   unsigned char **row_pointers;
   png_structp png_ptr = NULL;
   png_infop info_ptr = NULL;
   _mapcache_buffer_closure b;
   b.buffer = buffer;
   b.ptr = buffer->buf;
   png_uint_32 width, height;


   /* could pass pointers to user-defined error handlers instead of NULLs: */
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
   if (!png_ptr) {
      ctx->set_error(ctx, 500, "failed to allocate png_struct structure");
      return;
   }

   info_ptr = png_create_info_struct(png_ptr);
   if (!info_ptr)
   {
      png_destroy_read_struct(&png_ptr, NULL, NULL);
      ctx->set_error(ctx, 500, "failed to allocate png_info structure");
      return;
   }

   if (setjmp(png_jmpbuf(png_ptr)))
   {
      ctx->set_error(ctx, 500, "failed to setjmp(png_jmpbuf(png_ptr))");
      png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
      return;
   }
   png_set_read_fn(png_ptr,&b,_mapcache_imageio_png_read_func);

   png_read_info(png_ptr,info_ptr);
   if(!png_get_IHDR(png_ptr, info_ptr, &width, &height,&bit_depth, &color_type,NULL,NULL,NULL)) {
      ctx->set_error(ctx, 500, "failed to read png header");
      return;
   }

   img->w = width;
   img->h = height;
   if(!img->data) {
      img->data = calloc(1,img->w*img->h*4*sizeof(unsigned char));
      apr_pool_cleanup_register(ctx->pool, img->data, (void*)free, apr_pool_cleanup_null) ;
      img->stride = img->w * 4;
   }
   row_pointers = apr_pcalloc(ctx->pool,img->h * sizeof(unsigned char*));

   unsigned char *rowptr = img->data;
   for(i=0;i<img->h;i++) {
      row_pointers[i] = rowptr;
      rowptr += img->stride;
   }


   png_set_expand(png_ptr);
   png_set_strip_16(png_ptr);
   png_set_gray_to_rgb(png_ptr);
   png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
   
   png_read_update_info(png_ptr, info_ptr);

   png_read_image(png_ptr, row_pointers);
   
   png_read_end(png_ptr,NULL);
   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
}
Example #11
0
pointer PNG_READ_IMAGE(register context *ctx, int n, register pointer *argv)
{
  char *file_name;
  pointer ret, image_ptr;
  ckarg(1);
  if (isstring(argv[0])) file_name = argv[0]->c.str.chars;
  else error(E_NOSTRING);

  FILE *fp = fopen(file_name, "rb");
  if (!fp) {
    error(E_OPENFILE);
    return(NIL);
  }

  png_structp png_ptr;
  png_infop info_ptr;
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  info_ptr = png_create_info_struct(png_ptr);

  if (setjmp(png_jmpbuf(png_ptr))) {
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    fclose(fp);
    error(E_EOF);
    return(NIL);
  }

  png_init_io(png_ptr, fp);
  png_read_info(png_ptr, info_ptr);
  int width = png_get_image_width(png_ptr, info_ptr);
  int height = png_get_image_height(png_ptr, info_ptr);
  int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  int channels = png_get_channels(png_ptr, info_ptr);
  int color_type = png_get_color_type(png_ptr, info_ptr);
  //fprintf(stderr, "bit_depth = %d, channels %d, color_type =%d (pal:%d,gray:%d,rgb:%d,rgba:%d)\n", bit_depth, channels, color_type, PNG_COLOR_TYPE_PALETTE,PNG_COLOR_TYPE_GRAY,PNG_COLOR_TYPE_RGB,PNG_COLOR_TYPE_RGB_ALPHA);
  switch (color_type) {
  case PNG_COLOR_TYPE_PALETTE:
    png_set_palette_to_rgb(png_ptr);
    break;
  case PNG_COLOR_TYPE_GRAY:
    #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
    if ( bit_depth < 8) png_set_gray_to_rgb(png_ptr);
    #else
    if ( bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
    #endif
    break;
  case PNG_COLOR_TYPE_RGB:
    //png_set_bgr(png_ptr);
    if (bit_depth == 16) png_set_strip_16(png_ptr); // 16bit -> 8bit
    break;
  case PNG_COLOR_TYPE_RGB_ALPHA:
    if (bit_depth == 16) png_set_strip_16(png_ptr); // 16bit -> 8bit
    png_set_invert_alpha(png_ptr);
    //png_set_bgr(png_ptr);
    //png_set_strip_alpha(png_ptr);
    // RGBA -> rgb , GA -> g
    png_color_16 my_background = {0xff, 0xff, 0xff, 0xff, 0xff};
    png_set_background(png_ptr, &my_background,
                       PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);

    break;
  }
  png_read_update_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); channels = png_get_channels(png_ptr, info_ptr);
  color_type = png_get_color_type(png_ptr, info_ptr);

  png_bytep * row_pointers = (png_bytep *)malloc(height*sizeof(png_bytep));
  int y, byte_per_scanline = png_get_rowbytes(png_ptr, info_ptr);
  image_ptr = makebuffer(height*byte_per_scanline);
  for(y=0;y<height;y++){
    row_pointers[y] = image_ptr->c.str.chars+y*byte_per_scanline;
  }
  png_read_image(png_ptr, row_pointers);
  free(row_pointers);
  png_read_end(png_ptr,info_ptr);
  png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
  fclose(fp);

  ret=cons(ctx,image_ptr,NIL);
  ret=cons(ctx,makeint(channels),ret);
  ret=cons(ctx,makeint(height),ret);
  ret=cons(ctx,makeint(width),ret);
  return (ret);
}
Example #12
0
static int qrwrap_writePNG(const char *outfile, QRcode *qrcode)
{
	static FILE *fp;
	png_structp png_ptr;
	png_infop info_ptr;
	unsigned char *row, *p, *q;
	int x, y, xx, yy, bit;
	int realwidth;
	const int margin = 0;
	const int size = 8;
	const int width = qrcode->width;

	realwidth = (width + margin * 2) * size;
	row = (unsigned char *)vj_malloc((realwidth + 7) / 8);
	if(row == NULL) {
		return 0;
	}

	fp = fopen(outfile, "wb");
	if(fp == NULL) {
		veejay_msg(VEEJAY_MSG_ERROR, "Unable to write QR code to file:%s", outfile);
		return 0;
	}
	

	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if(png_ptr == NULL) {
		fclose(fp);
		return 0;
	}

	info_ptr = png_create_info_struct(png_ptr);
	if(info_ptr == NULL) {
		fclose(fp);
		return 0;
	}

	if(setjmp(png_jmpbuf(png_ptr))) {
		png_destroy_write_struct(&png_ptr, &info_ptr);
		fclose(fp);
		return 0;
	}

	png_init_io(png_ptr, fp);
	png_set_IHDR(png_ptr, info_ptr,
			realwidth, realwidth,
			1,
			PNG_COLOR_TYPE_GRAY,
			PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_DEFAULT,
			PNG_FILTER_TYPE_DEFAULT);
	png_write_info(png_ptr, info_ptr);

	/* top margin */
	veejay_memset(row, 0xff, (realwidth + 7) / 8);
	for(y=0; y<margin * size; y++) {
		png_write_row(png_ptr, row);
	}

	/* data */
	p = qrcode->data;
	for(y=0; y<width; y++) {
		bit = 7;
		veejay_memset(row, 0xff, (realwidth + 7) / 8);
		q = row;
		q += margin * size / 8;
		bit = 7 - (margin * size % 8);
		for(x=0; x<width; x++) {
			for(xx=0; xx<size; xx++) {
				*q ^= (*p & 1) << bit;
				bit--;
				if(bit < 0) {
					q++;
					bit = 7;
				}
			}
			p++;
		}
		for(yy=0; yy<size; yy++) {
			png_write_row(png_ptr, row);
		}
	}
	/* bottom margin */
	veejay_memset(row, 0xff, (realwidth + 7) / 8);
	for(y=0; y<margin * size; y++) {
		png_write_row(png_ptr, row);
	}

	png_write_end(png_ptr, info_ptr);
	png_destroy_write_struct(&png_ptr, &info_ptr);

	fclose(fp);
	free(row);

	return 0;
}
Example #13
0
bool8 S9xDoScreenshot (int width, int height)
{
	Settings.TakeScreenshot = FALSE;

#ifdef HAVE_LIBPNG
	FILE		*fp;
	png_structp	png_ptr;
	png_infop	info_ptr;
	png_color_8	sig_bit;
	int			imgwidth, imgheight;
	const char	*fname;

	fname = S9xGetFilenameInc(".png", SCREENSHOT_DIR);

	fp = fopen(fname, "wb");
	if (!fp)
	{
		S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
		return (FALSE);
	}

	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!png_ptr)
	{
		fclose(fp);
		remove(fname);
		S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
		return (FALSE);
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
		fclose(fp);
		remove(fname);
		S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
		return (FALSE);
	}

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		png_destroy_write_struct(&png_ptr, &info_ptr);
		fclose(fp);
		remove(fname);
		S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
		return (FALSE);
	}

	imgwidth  = width;
	imgheight = height;

	if (Settings.StretchScreenshots == 1)
	{
		if (width > SNES_WIDTH && height <= SNES_HEIGHT_EXTENDED)
			imgheight = height << 1;
	}
	else
	if (Settings.StretchScreenshots == 2)
	{
		if (width  <= SNES_WIDTH)
			imgwidth  = width  << 1;
		if (height <= SNES_HEIGHT_EXTENDED)
			imgheight = height << 1;
	}

	png_init_io(png_ptr, fp);

	png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

	sig_bit.red   = 5;
	sig_bit.green = 5;
	sig_bit.blue  = 5;
	png_set_sBIT(png_ptr, info_ptr, &sig_bit);
	png_set_shift(png_ptr, &sig_bit);

	png_write_info(png_ptr, info_ptr);

	png_set_packing(png_ptr);

	png_byte	*row_pointer = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
	uint16		*screen = GFX.Screen;

	for (int y = 0; y < height; y++, screen += GFX.RealPPL)
	{
		png_byte	*rowpix = row_pointer;

		for (int x = 0; x < width; x++)
		{
			uint32	r, g, b;

			DECOMPOSE_PIXEL(screen[x], r, g, b);

			*(rowpix++) = r;
			*(rowpix++) = g;
			*(rowpix++) = b;

			if (imgwidth != width)
			{
				*(rowpix++) = r;
				*(rowpix++) = g;
				*(rowpix++) = b;
			}
		}

		png_write_row(png_ptr, row_pointer);
		if (imgheight != height)
			png_write_row(png_ptr, row_pointer);
	}

	delete [] row_pointer;

	png_write_end(png_ptr, info_ptr);
	png_destroy_write_struct(&png_ptr, &info_ptr);

	fclose(fp);

	fprintf(stderr, "%s saved.\n", fname);

	const char	*base = S9xBasename(fname);
	sprintf(String, "Saved screenshot %s", base);
	S9xMessage(S9X_INFO, 0, String);

	return (TRUE);
#else
	fprintf(stderr, "Screenshot support not available (libpng was not found at build time).\n");
	return (FALSE);
#endif
}
Example #14
0
bool YImage::load(const char* fname)
{
	FILE* fp = NULL ;
	bool rval = true;
	png_structp png_ptr = NULL ;
	png_infop info_ptr = NULL ;
    
	// for checking the png header
	const size_t PNG_BYTES_TO_CHECK = 4 ; // example.c uses 4
	png_byte header[ PNG_BYTES_TO_CHECK ] ;
	
	// Open the file for reading in binary mode.
	fp = fopen( fname, "rb" ) ;
	if( !fp )
	{
		fprintf( stderr, ERROR_STRING_OPEN, fname ) ;
		rval = false;
		goto YImage_load_cleanup ;
	}
	
	// Check some bytes at the beginning of the file to make sure it's a png.
	if( PNG_BYTES_TO_CHECK != fread( header, 1, PNG_BYTES_TO_CHECK, fp ) )
	{
		fprintf( stderr, ERROR_STRING_INVALID_FILE, fname ) ;
		rval = false;
		goto YImage_load_cleanup ;
	}
	if( png_sig_cmp( header, 0, PNG_BYTES_TO_CHECK ) )
	{
		fprintf( stderr, ERROR_STRING_INVALID_FILE, fname ) ;
		rval = false;
		goto YImage_load_cleanup ;
	}
	
	// Since it looks like we have a good png file, allocate the png structs.
	png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ) ;
	if( !png_ptr )
	{
		fprintf( stderr, ERROR_STRING_LIBERR ) ;
		rval = false;
		goto YImage_load_cleanup ;
	}
	info_ptr = png_create_info_struct( png_ptr ) ;
	if( !info_ptr )
	{
		fprintf( stderr, ERROR_STRING_LIBERR ) ;
		rval = false;
		goto YImage_load_cleanup ;
    }
	
	// Set up the png error routine.
	if( setjmp(png_jmpbuf(png_ptr)) )
	{
		fprintf( stderr, ERROR_STRING_MAYBE_FILE, fname ) ;
		rval = false;
		goto YImage_load_cleanup ;
    }
	
	// Give libpng the FILE*, tell it how many bytes we read.
	// png_init_io( png_ptr, fp ) ;
	// or
	// use our own read callback
	png_set_read_fn( png_ptr, fp, (png_rw_ptr) user_read_data ) ;
	
	png_set_sig_bytes( png_ptr, PNG_BYTES_TO_CHECK ) ;
	
	// We'll use the low-level interface since the high-level interface won't handle
	// png_set_filler() which we need to guarantee there'll be a filler "A" in our
	// 4-byte ARGB pixels.
	// Really the low-level interface isn't more complicated than the high-level interface.
	// To choose transform flags we have to query the png_info struct.
	// Instead of OR'ing in another transform flag (high-level interface), we call a set
	// method (low-level interface).
	
	// First we read the info struct.
	png_read_info( png_ptr, info_ptr ) ;
	
	// Now we set up transforms.
	// 1. convert gray and paletted to rgb (this guarantees 8 or 16 bit depths (rgb must be 8 or 16)).
	//    also expand the alpha color to an alpha channel and convert 16 bit depths to 8.
	// 2. if we don't have alpha, add an opaque channel.  also swap RGB and BGR depending on YPixel.
	// 3. ask libpng to deinterlace
	{
		
		png_byte color_type = png_get_color_type( png_ptr, info_ptr ) ;
		png_byte depth = png_get_bit_depth( png_ptr, info_ptr ) ;
		
		// 1
		if( color_type == PNG_COLOR_TYPE_PALETTE )
			png_set_expand( png_ptr ) ;
		if( color_type == PNG_COLOR_TYPE_GRAY && depth < 8 )
			png_set_expand( png_ptr ) ;
		if( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ) )
			png_set_expand( png_ptr ) ;
		if( depth == 16 )
			png_set_strip_16( png_ptr ) ;
		if( color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
			png_set_gray_to_rgb( png_ptr ) ;
		
		
		// NOTE: This next step affects the layout of the channels in the pixel.
		//       We turn the pixel into the format in YPixel,
		//       with the restrication that alpha comes at the beginning or end
		//       and green is sandwiched between red and blue.
		//       The possibilities are: ARGB, ABGR, RGBA, BGRA.
		
		// 2
		if( color_type != PNG_COLOR_TYPE_GRAY_ALPHA && color_type != PNG_COLOR_TYPE_RGB_ALPHA && !png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ) )
			png_set_filler( png_ptr, 0xFF, offsetof( YPixel, a ) < offsetof( YPixel, b ) ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER ) ;
		else if( offsetof( YPixel, a ) < offsetof( YPixel, b ) )
				png_set_swap_alpha( png_ptr ) ;
		
		if( offsetof( YPixel, b ) < offsetof( YPixel, r ) )
			png_set_bgr( png_ptr ) ;
		
		// 3
		png_set_interlace_handling( png_ptr ) ;
		
	}
	
	// We're almost ready to copy over the png data.
	// First we must resize our data* and set our width & height.
	{
		png_uint_32 widthh = png_get_image_width( png_ptr, info_ptr ) ;
		png_uint_32 heightt = png_get_image_height( png_ptr, info_ptr ) ;
		
		// fprintf( stderr, "width: %d, height: %d\n", (int) widthh, (int) heightt ) ;
		
		resize( widthh, heightt ) ;
	}
	
	// Now we can create a rows[] pointing into our data* and read the png into our buffer.
	{
		// fprintf( stderr, "width: %d, height: %d\n", (int) m_width, (int) m_height ) ;
		/*
		
		png_byte channels = png_get_channels( png_ptr, info_ptr ) ;
		assert( 4 == channels ) ;
		png_byte depth = png_get_bit_depth( png_ptr, info_ptr ) ;
		assert( 8 == depth ) ;
		png_uint_32 rowbytes = png_get_rowbytes( png_ptr, info_ptr ) ;
		assert( sizeof(YPixel) * m_width == rowbytes ) ;
		*/
		
		// 1. allocate row pointers array
		png_bytep* row_pointers = (png_bytep*) png_malloc( png_ptr, m_height * sizeof(png_bytep) ) ;
		// 2. point row pointers into m_data
		for( int i = 0 ; i < m_height ; ++i )
			row_pointers[i] = (png_bytep) (m_data + i*m_width ) ;
		// 3. read the image data
		png_read_image( png_ptr, row_pointers ) ;
		// 4. free row pointers array
		png_free( png_ptr, row_pointers ) ;
	}
	
	// Read the end info.  We're done.  Fall through to cleanup.
	png_read_end( png_ptr, NULL ) ;
	
YImage_load_cleanup:
	// due to (what looks like) a bug in libpng-1.2.4, we can't pass NULL for the png_ptr arg
	if( png_ptr ) png_destroy_read_struct( &png_ptr, info_ptr ? &info_ptr : NULL, NULL ) ;
	
	if( fp ) fclose( fp ) ;
	
	return rval ;
}
Example #15
0
// Loads a PNG image
//
// filename - name of the targa file to load
// image_data - allocated storage for the bitmap
//
// returns - true if succesful, false otherwise
//
int png_read_bitmap(char *real_filename, ubyte *image_data, ubyte *bpp, int dest_size, int cf_type)
{
	char filename[MAX_FILENAME_LEN];
	png_infop info_ptr;
	png_structp png_ptr;
	png_bytepp row_pointers;
	unsigned int i, len;

	png_file = NULL;

	strcpy_s( filename, real_filename );
	char *p = strchr( filename, '.' );
	if ( p ) *p = 0;
	strcat_s( filename, ".png" );

	png_file = cfopen(filename, "rb", CFILE_NORMAL, cf_type);

	if (png_file == NULL)
		return PNG_ERROR_READING;

	/* Create and initialize the png_struct with the desired error handler
	* functions.  If you want to use the default stderr and longjump method,
	* you can supply NULL for the last three parameters.  We also supply the
	* the compiler header file version, so that we know if the application
	* was compiled with a compatible version of the library.  REQUIRED
	*/
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

	if (png_ptr == NULL)
	{
		mprintf(("png_read_bitmap: png_ptr went wrong\n"));
		cfclose(png_file);
		return PNG_ERROR_READING;
	}

	/* Allocate/initialize the memory for image information.  REQUIRED. */
	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL)
	{
		mprintf(("png_read_bitmap: info_ptr went wrong\n"));
		cfclose(png_file);
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		return PNG_ERROR_READING;
	}

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		mprintf(("png_read_bitmap: something went wrong\n"));
		/* Free all of the memory associated with the png_ptr and info_ptr */
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		cfclose(png_file);
		/* If we get here, we had a problem reading the file */
		return PNG_ERROR_READING;
	}

	png_set_read_fn(png_ptr, &png_file, png_scp_read_data);

	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_16, NULL);
	len = png_get_rowbytes(png_ptr, info_ptr);

	row_pointers = png_get_rows(png_ptr, info_ptr);

	if(bpp)
		*bpp = (ubyte)(len / png_get_image_width(png_ptr, info_ptr)) << 3;

	//copy row data to image
	unsigned int height = png_get_image_height(png_ptr, info_ptr);
	for (i = 0; i < height; i++) {
		memcpy(&image_data[i * len], row_pointers[i], len);
	}

	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	cfclose(png_file);

	return PNG_ERROR_NONE;
}
Example #16
0
bool IGN_Create_PNG_JPR(LPCSTR mapname, long minx, long miny, long maxx, long maxy)
{
char tstring[256];
long bitmap_width = TILE_WIDTH*(maxx-minx)/1000;
long bitmap_size = bitmap_width*TILE_WIDTH;
unsigned char * bitmap_memory = (unsigned char *)malloc(bitmap_size);
CIGNTileDatabase	db;


	if (bitmap_memory == NULL) {
		printf("Couldn't allocate %d bytes of memory\n");
		return false;
	}


	// Create PNG header and write out palette
	sprintf(tstring, "%s.png", mapname);
	FILE * fp_png = fopen(tstring, "wb");
	if (fp_png == NULL) {
		printf("Couldn't open %s\n", tstring);
		return false;
	}
	
	// Create and initialize the png_struct with the desired error handler functions.
	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (png_ptr == NULL) {
		fclose(fp_png);
		return false;
	}
	
	/* Allocate/initialize the image information data.  REQUIRED */
	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) {
		png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
		fclose(fp_png);
		return false;
	}
	
	/* Set error handling.  REQUIRED */
	if (setjmp(png_jmpbuf(png_ptr))) {
		/* If we get here, we had a problem reading the file */
		png_destroy_write_struct(&png_ptr, &info_ptr);
		fclose(fp_png);
		return false;
	}

	/* set up the output control if you are using standard C streams */
	png_init_io(png_ptr, fp_png);
	
	/* Set the image information here.  Width and height are up to 2^31,
	 * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
	 * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
	 * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
	 * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
	 * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
	 * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
	 */
	png_set_IHDR(png_ptr, info_ptr, TILE_WIDTH*(maxx-minx)/1000, TILE_WIDTH*((maxy-miny)/1000), 8, PNG_COLOR_TYPE_PALETTE,
				PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

	/* set the palette if there is one.  REQUIRED for indexed-color images */
	png_colorp png_palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof (png_color));


	int i;
	BYTE * pal_ptr = (BYTE *)png_palette;
	BYTE * palette = ign_palette;
	for (i=0; i<256; i++) {
		*pal_ptr++ = palette[i*4 + 2];
		*pal_ptr++ = palette[i*4 + 1];
		*pal_ptr++ = palette[i*4 + 0];
	}

	/* ... set palette colors ... */
	png_set_PLTE(png_ptr, info_ptr, png_palette, PNG_MAX_PALETTE_LENGTH);
	/* You must not free palette here, because png_set_PLTE only makes a link to
	 * the palette that you malloced.  Wait until you are about to destroy
	 *the png structure. */
	
	/* Write the file header information.  REQUIRED */
	png_write_info(png_ptr, info_ptr);

CProgressWindow wndProgress;
wndProgress.Initialize();

wndProgress.ResetProgressBar("Tile:", (maxy-miny)/500*(maxx-minx)/500);


	for (int y=maxy-1000; y>=miny; y-=1000) {
		memset(bitmap_memory, 0x00, bitmap_size);
		for (int x=minx; x<maxx; x+=1000) {
			IGN_read_bmp(y, x, &db, bitmap_memory+(x-minx)/1000*TILE_WIDTH, bitmap_width);
		}


		// write row of PNG to file
		for (int x=0; x<TILE_WIDTH; x++) {
			png_write_row(png_ptr, bitmap_memory + x*bitmap_width);

			if (!wndProgress.ProgressBar()) return false;
		}
	}
	/* It is REQUIRED to call this to finish writing the rest of the file */
	png_write_end(png_ptr, info_ptr);

	png_free(png_ptr, png_palette);
	
	/* clean up after the write, and free any memory allocated */
	png_destroy_write_struct(&png_ptr, &info_ptr);

	/* close the file */
	fclose(fp_png);

//	IGN_dumpjprfile(mapname, minx, miny, maxx, maxy, (maxx-minx)/1000 * TILE_WIDTH, (maxy-miny)/1000*TILE_WIDTH, NULL);
	free(bitmap_memory);
	return true;
}
Example #17
0
// Reads header information from the PNG file into the bitmap pointer
//
// filename - name of the PNG bitmap file
// w - (output) width of the bitmap
// h - (output) height of the bitmap
// bpp - (output) bits per pixel of the bitmap
//
// returns - PNG_ERROR_NONE if successful, otherwise error code
//
int png_read_header(char *real_filename, CFILE *img_cfp, int *w, int *h, int *bpp, ubyte *palette)
{
	char filename[MAX_FILENAME_LEN];
	png_infop info_ptr;
	png_structp png_ptr;

	png_file = NULL;

	//mprintf(("png_read_header: %s\n", real_filename));

	if (img_cfp == NULL) {
		strcpy_s( filename, real_filename );

		char *p = strchr( filename, '.' );

		if ( p )
			*p = 0;

		strcat_s( filename, ".png" );

		png_file = cfopen( filename , "rb" );

		if ( !png_file ) {
			return PNG_ERROR_READING;
		}
	} else {
		png_file = img_cfp;
	}

	Assert( png_file != NULL );

	if (png_file == NULL)
		return PNG_ERROR_READING;

	/* Create and initialize the png_struct with the desired error handler
	* functions.  If you want to use the default stderr and longjump method,
	* you can supply NULL for the last three parameters.  We also supply the
	* the compiler header file version, so that we know if the application
	* was compiled with a compatible version of the library.  REQUIRED
	*/
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

	if (png_ptr == NULL)
	{
		mprintf(("png_read_header: error creating read struct\n"));
		cfclose(png_file);
		return PNG_ERROR_READING;
	}

	/* Allocate/initialize the memory for image information.  REQUIRED. */
	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL)
	{
		mprintf(("png_read_header: error creating info struct\n"));
		cfclose(png_file);
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		return PNG_ERROR_READING;
	}

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		mprintf(("png_read_header: something went wrong\n"));
		/* Free all of the memory associated with the png_ptr and info_ptr */
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		cfclose(png_file);
		/* If we get here, we had a problem reading the file */
		return PNG_ERROR_READING;
	}

	png_set_read_fn(png_ptr, &png_file, png_scp_read_data);

	png_read_info(png_ptr, info_ptr);

	if (w) *w = png_get_image_width(png_ptr, info_ptr);
	if (h) *h = png_get_image_height(png_ptr, info_ptr);
	// this turns out to be near useless, but meh
	if (bpp) *bpp = (png_get_channels(png_ptr, info_ptr) * png_get_bit_depth(png_ptr, info_ptr));

	if (img_cfp == NULL) {
		cfclose(png_file);
		png_file = NULL;
	}

	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

	return PNG_ERROR_NONE;
}
Example #18
0
void savePNG(const char* file_name)
{
	png_structp png_ptr;
	png_infop info_ptr;

	/* create file */
    FILE *fp = fopen(file_name, "wb");
    if (!fp)
            abort_("[write_png_file] File %s could not be opened for writing", file_name);


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

    if (!png_ptr)
            abort_("[write_png_file] png_create_write_struct failed");

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
            abort_("[write_png_file] png_create_info_struct failed");

    if (setjmp(png_jmpbuf(png_ptr)))
            abort_("[write_png_file] Error during init_io");

    png_init_io(png_ptr, fp);

    /* write header */
    if (setjmp(png_jmpbuf(png_ptr)))
            abort_("[write_png_file] Error during writing header");

	png_set_IHDR(png_ptr, info_ptr, pictureWidth, pictureHeight,
					8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
                    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

    png_write_info(png_ptr, info_ptr);


    /* write bytes */
    if (setjmp(png_jmpbuf(png_ptr)))
            abort_("[write_png_file] Error during writing bytes");

	png_bytep * row_pointers;
		
	unsigned char *array = new unsigned char[pictureWidth * pictureHeight * 4];
	for (int i = pictureWidth * pictureHeight; i >= 0; --i)
	{
		array[i*4+0] = ((unsigned char*)pictureWriteOut)[i*4+0];
		array[i*4+1] = ((unsigned char*)pictureWriteOut)[i*4+1];
		array[i*4+2] = ((unsigned char*)pictureWriteOut)[i*4+2];
		array[i*4+3] = ((unsigned char*)pictureWriteOut)[i*4+3];
	}


	// Allocate pointers...
	row_pointers = new png_bytep[pictureHeight];

	for (int i = 0; i < pictureHeight; i ++)
		row_pointers[i] = (png_bytep)(array + (i) * pictureWidth * 4); // we flip it

	png_write_image(png_ptr, row_pointers);

    /* end write */
    if (setjmp(png_jmpbuf(png_ptr)))
            abort_("[write_png_file] Error during end of write");
	
    png_write_end(png_ptr, NULL);

    /* cleanup heap allocation */
    free(row_pointers);

    fclose(fp);
}
Example #19
0
void write_png_file(const char* file_name, int32 width, int32 height, uint8 * data)
{
	if (CommandLineParser::Instance()->GetVerbose())
		printf("* Writing PNG file (%d x %d): %s\n", width, height, file_name);
	
	png_byte color_type = PNG_COLOR_TYPE_RGBA;
	png_byte bit_depth = 8;
	png_color_8 sig_bit;
	
	png_structp png_ptr;
	png_infop info_ptr;
	
	png_bytep * row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
	for (int y = 0; y < height; y++)
	{
		row_pointers[y] = (png_byte*) &data[y * width * 4];
	}
	
	
	/* create file */
	FILE *fp = fopen(file_name, "wb");
	if (!fp)
		abort_("[write_png_file] File %s could not be opened for writing", file_name);
	
	
	/* initialize stuff */
	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	
	if (!png_ptr)
		abort_("[write_png_file] png_create_write_struct failed");
	
	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
		abort_("[write_png_file] png_create_info_struct failed");
	
	if (setjmp(png_jmpbuf(png_ptr)))
		abort_("[write_png_file] Error during init_io");
	
	png_init_io(png_ptr, fp);
	
	
	/* write header */
	if (setjmp(png_jmpbuf(png_ptr)))
		abort_("[write_png_file] Error during writing header");
	
	png_set_IHDR(png_ptr, info_ptr, width, height,
				 bit_depth, color_type, PNG_INTERLACE_NONE,
				 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
	
	
	sig_bit.red = 8;
	sig_bit.green = 8;
	sig_bit.blue = 8;
	sig_bit.alpha = 8;

	png_set_sBIT(png_ptr, info_ptr, &sig_bit);
		
	png_write_info(png_ptr, info_ptr);
	png_set_shift(png_ptr, &sig_bit);
	png_set_packing(png_ptr);
	
	/* write bytes */
	if (setjmp(png_jmpbuf(png_ptr)))
		abort_("[write_png_file] Error during writing bytes");
	
	png_write_image(png_ptr, row_pointers);
	
	
	/* end write */
	if (setjmp(png_jmpbuf(png_ptr)))
		abort_("[write_png_file] Error during end of write");
	
	png_write_end(png_ptr, NULL);
	
	free(row_pointers);
	
	fclose(fp);
}
Example #20
0
int writepng(char* filename, png_store *pngdata)
{
	int code = 0;
	FILE *fp;
	png_structp png_ptr;
	png_infop info_ptr;
	png_bytep row;
	int width = pngdata->width;
	int height = pngdata->height;
//	float *buffer = pngdata->image_data;
	
	// Open file for writing (binary mode)
	fp = fopen(filename, "wb");
	if (fp == NULL) {
		fprintf(stderr, "Could not open file %s for writing\n", filename);
		code = 1;
		exit(1);
	}

	// Initialize write structure
	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (png_ptr == NULL) {
		fprintf(stderr, "Could not allocate write struct\n");
		code = 1;
		exit(1);
	}

	// Initialize info structure
	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) {
		fprintf(stderr, "Could not allocate info struct\n");
		code = 1;
		exit(1);
	}

	// Setup Exception handling
	if (setjmp(png_jmpbuf(png_ptr))) {
		fprintf(stderr, "Error during png creation\n");
		code = 1;
		exit(1);
	}

	png_init_io(png_ptr, fp);



	// Write header (8 bit colour depth)
	png_set_IHDR(png_ptr, info_ptr, width, height,
			pngdata->bitdepth, pngdata->colortype, PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

	png_write_info(png_ptr, info_ptr);

	png_write_image(png_ptr,pngdata->row_pointers);	
	// End write
	png_write_end(png_ptr, NULL);
/*
	finalise:
	if (fp != NULL) fclose(fp);
	if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
	if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
	if (row != NULL) free(row);
*/
	return code;
}
Example #21
0
int pixbuf2png(GdkPixbuf *pb, const char *output_png)
{
    int i;

    int width = gdk_pixbuf_get_width(pb);
    int height = gdk_pixbuf_get_height(pb);
    int n_channels = gdk_pixbuf_get_n_channels(pb);
    int rowstride = gdk_pixbuf_get_rowstride(pb);

    guchar *pixels = gdk_pixbuf_get_pixels(pb);
    guchar *pixels_out = MALLOC(sizeof(guchar)*width*height*4);

    //printf("pixbuf2png> opening: %s\n", output_png);
    FILE *fout = FOPEN(output_png, "wb");
    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                          NULL, NULL, NULL);
    if (!png_ptr) {
        asfPrintWarning("Couldn't open png file: %s\n", output_png);
        return FALSE;
    }

    //printf("pixbuf2png> png_create_info_struct\n");
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
        fclose(fout);
        asfPrintWarning("Couldn't open png info for %s\n", output_png);
        return FALSE;
    }

    //printf("pixbuf2png> setjmp\n");
    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fout);
        asfPrintWarning("Error writing the png: %s\n", output_png);
        return FALSE;
    }

    //printf("pixbuf2png> png_init_io\n");
    png_init_io(png_ptr, fout);

    //printf("pixbuf2png> png_set_IHDR\n");
    png_set_IHDR(png_ptr, info_ptr, width, height, 8,
                 PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

    //printf("pixbuf2png> png_write_info\n");
    png_write_info(png_ptr, info_ptr);

    // add a transparency byte to each pixel in the pixels_out buffer
    for (i=0; i<height; ++i) {
        int j;
        for (j=0; j<width; ++j) {
            // output: red=k, green=k+1, blue=k+2, alpha=k+3
            int out_k = 4*(j + i*width);
            // input: red=k, green=k+1, blue=k+2
            int in_k = j*n_channels + i*rowstride;

            // make it transparent, if the pixel is black
            // (i.e., all channels are 0)
            int trans = pixels[in_k] == 0 &&
                        pixels[in_k+1] == 0 && pixels[in_k+2] == 0;

            pixels_out[out_k] = pixels[in_k];
            pixels_out[out_k+1] = pixels[in_k+1];
            pixels_out[out_k+2] = pixels[in_k+2];
            pixels_out[out_k+3] = trans ? 0 : 255;
        }
    }

    //printf("pixbuf2png> row_pointers\n");
    png_bytep *row_pointers = MALLOC(sizeof(png_bytep)*height);
    for (i=0; i<height; ++i)
        row_pointers[i] = pixels_out + i*width*4;

    //printf("pixbuf2png> png_write_image\n");
    png_write_image(png_ptr, row_pointers);

    //printf("pixbuf2png> png_write_end\n");
    png_write_end(png_ptr, NULL);

    //printf("pixbuf2png> png_destroy_write_struct\n");
    png_destroy_write_struct(&png_ptr, &info_ptr);

    //printf("pixbuf2png> fclose\n");
    fclose(fout);

    //printf("pixbuf2png> freeing row pointers\n");
    FREE(row_pointers);
    FREE(pixels_out);

    return TRUE;
}
Example #22
0
unsigned char *readpng_get_image( png_store* pngdata)
{
    double  gamma;
    png_uint_32  i, rowbytes;
    png_bytepp  row_pointers = NULL;
    png_structp png_ptr = pngdata->png_ptr;
    png_infop info_ptr = pngdata->info_ptr;
    int color_type = pngdata->colortype;
    int bit_depth = pngdata->bitdepth;
    int height = pngdata->height;
    double display_exponent = DISPLAY_EXPONENT;
    int *pChannels = &(pngdata->channels);
    unsigned long *pRowbytes = &(pngdata->rowbytes);
    unsigned char * image_data;
    /* setjmp() must be called in every function that calls a PNG-reading
     * libpng function */

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return NULL;
    }

    /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
     * transparency chunks to full alpha channel; strip 16-bit-per-sample
     * images to 8 bits per sample; and convert grayscale to RGB[A] */

    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_expand(png_ptr);
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_expand(png_ptr);
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_expand(png_ptr);
    if (bit_depth == 16)
        png_set_strip_16(png_ptr);
    if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_ptr);


    /* unlike the example in the libpng documentation, we have *no* idea where
     * this file may have come from--so if it doesn't have a file gamma, don't
     * do any correction ("do no harm") */

    if (png_get_gAMA(png_ptr, info_ptr, &gamma))
        png_set_gamma(png_ptr, display_exponent, gamma);


    /* all transformations have been registered; now update info_ptr data,
     * get rowbytes and channels, and allocate image memory */

    png_read_update_info(png_ptr, info_ptr);

    *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
    *pChannels = (int)png_get_channels(png_ptr, info_ptr);

    if ((image_data = (unsigned char *)malloc(rowbytes*height)) == NULL) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return NULL;
    }
    if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        free(image_data);
        image_data = NULL;
        return NULL;
    }

    /* set the individual row_pointers to point at the correct offsets */

    for (i = 0;  i < height;  ++i)
        row_pointers[i] = image_data + i*rowbytes;

    /* now we can go ahead and just read the whole image */

    png_read_image(png_ptr, row_pointers);


    /* and we're done!  (png_read_end() can be omitted if no processing of
     * post-IDAT text/time/etc. is desired) */

//    free(row_pointers);
//    row_pointers = NULL;

    png_read_end(png_ptr, NULL);

    pngdata->image_data = image_data;
    pngdata->row_pointers =  row_pointers;

    return image_data;
}
Example #23
0
static void
gst_pngdec_task (GstPad * pad)
{
  GstPngDec *pngdec;
  GstBuffer *buffer = NULL;
  size_t buffer_size = 0;
  gint i = 0;
  png_bytep *rows, inp;
  png_uint_32 rowbytes;
  GstFlowReturn ret = GST_FLOW_OK;

  pngdec = GST_PNGDEC (GST_OBJECT_PARENT (pad));

  GST_LOG_OBJECT (pngdec, "read frame");

  /* Let libpng come back here on error */
  if (setjmp (png_jmpbuf (pngdec->png))) {
    ret = GST_FLOW_ERROR;
    goto pause;
  }

  /* Set reading callback */
  png_set_read_fn (pngdec->png, pngdec, user_read_data);

  /* Read info */
  png_read_info (pngdec->png, pngdec->info);

  /* Generate the caps and configure */
  ret = gst_pngdec_caps_create_and_set (pngdec);
  if (ret != GST_FLOW_OK) {
    goto pause;
  }

  /* Allocate output buffer */
  rowbytes = png_get_rowbytes (pngdec->png, pngdec->info);
  if (rowbytes > (G_MAXUINT32 - 3) || pngdec->height > G_MAXUINT32 / rowbytes) {
    ret = GST_FLOW_ERROR;
    goto pause;
  }
  rowbytes = GST_ROUND_UP_4 (rowbytes);
  buffer_size = pngdec->height * rowbytes;
  ret =
      gst_pad_alloc_buffer_and_set_caps (pngdec->srcpad, GST_BUFFER_OFFSET_NONE,
      buffer_size, GST_PAD_CAPS (pngdec->srcpad), &buffer);
  if (ret != GST_FLOW_OK)
    goto pause;

  rows = (png_bytep *) g_malloc (sizeof (png_bytep) * pngdec->height);

  inp = GST_BUFFER_DATA (buffer);

  for (i = 0; i < pngdec->height; i++) {
    rows[i] = inp;
    inp += rowbytes;
  }

  /* Read the actual picture */
  png_read_image (pngdec->png, rows);
  g_free (rows);

  /* Push the raw RGB frame */
  ret = gst_pad_push (pngdec->srcpad, buffer);
  if (ret != GST_FLOW_OK)
    goto pause;

  /* And we are done */
  gst_pad_pause_task (pngdec->sinkpad);
  gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
  return;

pause:
  {
    GST_INFO_OBJECT (pngdec, "pausing task, reason %s",
        gst_flow_get_name (ret));
    gst_pad_pause_task (pngdec->sinkpad);
    if (ret == GST_FLOW_UNEXPECTED) {
      gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
      GST_ELEMENT_ERROR (pngdec, STREAM, FAILED,
          (_("Internal data stream error.")),
          ("stream stopped, reason %s", gst_flow_get_name (ret)));
      gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ());
    }
  }
}
Example #24
0
int readpng_init(FILE *infile, png_store *pngdata)
{
    unsigned char sig[8];
    long width,height;
    int  bit_depth, color_type;
 

    /* first do a quick check that the file really is a PNG image; could
     * have used slightly more general png_sig_cmp() function instead */

    size_t fr = fread(sig, 1, 8, infile);
    if(fr != 1*8)
        return 1;   /* bad signature */

    if (!png_check_sig(sig, 8))
        return 1;   /* bad signature */


    /* could pass pointers to user-defined error handlers instead of NULLs: */

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
        return 4;   /* out of memory */

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return 4;   /* out of memory */
    }


    /* we could create a second info struct here (end_info), but it's only
     * useful if we want to keep pre- and post-IDAT chunk info separated
     * (mainly for PNG-aware image editors and converters) */


    /* setjmp() must be called in every function that calls a PNG-reading
     * libpng function */

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return 2;
    }


    png_init_io(png_ptr, infile);
    png_set_sig_bytes(png_ptr, 8);  /* we already read the 8 signature bytes */

    png_read_info(png_ptr, info_ptr);  /* read all PNG info up to image data */


    /* alternatively, could make separate calls to png_get_image_width(),
     * etc., but want bit_depth and color_type for later [don't care about
     * compression_type and filter_type => NULLs] */

    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
      NULL, NULL, NULL);
	pngdata->width = width;
	pngdata->height = height;
	pngdata->bitdepth = bit_depth;
	pngdata->colortype = color_type;
	pngdata->png_ptr = png_ptr;
	pngdata->info_ptr = info_ptr;

    /* OK, that's all we need for now; return happy */

    return 0;
}
Example #25
0
struct IplImage *ipl_readimg(char *path, int mode)
{
	FILE *f;
	unsigned char head[8];
	int numb = 8, w, h, nchans = 3, y; 
	size_t sznumb;
	struct IplImage *res;
	png_bytep* rows;
	png_structp pngp;
	png_infop infop;
	
	if (!(f = fopen(path, "rb"))) { 
		perror("error opening file\n");
		return NULL;
	}

	sznumb = fread(head, sizeof(char), numb, f);
	
	if (png_sig_cmp(head, 0, 8)) {
		perror("is not png");
		fclose(f);
		return NULL;
	}
	
	if (!(pngp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) {
		perror("can't create read struct");
		fclose(f);
		return NULL;
	}
	
	if (!(infop = png_create_info_struct(pngp))) {
		perror("can't create info");
		png_destroy_read_struct(&pngp, NULL, NULL);
		fclose(f);
		return NULL;
	}

	if (setjmp(png_jmpbuf(pngp))) {
		perror("error in jumpbuf");
		png_destroy_read_struct(&pngp, &infop, NULL);
		fclose(f);
		return NULL;
	}

	png_init_io(pngp, f);
	png_set_sig_bytes(pngp, sznumb);

	png_read_info(pngp, infop);
	
	png_set_strip_alpha(pngp);	
	png_set_strip_16(pngp);
	if (mode) {
		nchans = 3;
		png_set_palette_to_rgb(pngp);
	} else {	
		nchans = 1;
		png_set_rgb_to_gray(pngp, 1, 0.0f, 0.0f);
		png_set_expand_gray_1_2_4_to_8(pngp);
	}
	
	png_set_interlace_handling(pngp);
	png_read_update_info(pngp, infop);

	w = png_get_image_width(pngp, infop);
	h = png_get_image_height(pngp, infop);

	rows = (png_bytep *)malloc(sizeof(png_bytep) * h);
	for (y = 0; y < h; y++) {
		rows[y] = (png_byte *)malloc(png_get_rowbytes(pngp, infop));
	}

	png_read_image(pngp, rows);

	
	
	res = (struct IplImage *)malloc(sizeof(struct IplImage));
	res->width = w;
	res->height = h;
	res->nchans = nchans;
	res->data = (unsigned char *)malloc(sizeof(unsigned char) * w * h * 3);

	for (y = 0; y < h; y++) 
		memcpy(&(res->data[nchans * y * w]), rows[y], sizeof(png_byte) * png_get_rowbytes(pngp, infop));
 
	for (y = 0; y < h; y++)
		free(rows[y]); 
	
	free(rows);

	fclose(f);
	return res;
}
Example #26
0
int load_png_image(const char *filepath,
                   struct pngload_attribute *png_attr)
{
    FILE *fp;
    png_structp png_ptr;
    png_infop info_ptr;
    png_bytep* row_pointers;
    char buf[PNG_BYTES_TO_CHECK];
    int w, h, x, y, temp, color_type;

    fp = fopen( filepath, "rb" );
    if( fp == NULL ) { 
        return -1;
    }

    png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
    info_ptr = png_create_info_struct( png_ptr );

    setjmp( png_jmpbuf(png_ptr) ); 
    /* 读取PNG_BYTES_TO_CHECK个字节的数据 */
    temp = fread( buf, 1, PNG_BYTES_TO_CHECK, fp );
    /* 若读到的数据并没有PNG_BYTES_TO_CHECK个字节 */
    if( temp < PNG_BYTES_TO_CHECK ) {
        fclose(fp);
        png_destroy_read_struct( &png_ptr, &info_ptr, 0);
        return -3;
    }
    /* 检测数据是否为PNG的签名 */
    temp = png_sig_cmp( (png_bytep)buf, (png_size_t)0, PNG_BYTES_TO_CHECK );
    /* 如果不是PNG的签名,则说明该文件不是PNG文件 */
    if( temp != 0 ) {
        fclose(fp);
        png_destroy_read_struct( &png_ptr, &info_ptr, 0);
        return -4;
    }
        
    /* 复位文件指针 */
    rewind( fp );
    /* 开始读文件 */
    png_init_io( png_ptr, fp ); 
    /* 读取PNG图片信息 */
    png_read_png( png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0 );
    /* 获取图像的色彩类型 */
    color_type = png_get_color_type( png_ptr, info_ptr );
    /* 获取图像的宽高 */
    png_attr->width = w = png_get_image_width( png_ptr, info_ptr );
    png_attr->height = h = png_get_image_height( png_ptr, info_ptr );
    printf("w=%d,h=%d\n", w, h);
    /* 获取图像的所有行像素数据,row_pointers里边就是rgba数据 */
    row_pointers = png_get_rows( png_ptr, info_ptr );
    unsigned char *data;
    int index = 0;

    /* 根据不同的色彩类型进行相应处理 */
    png_attr->color_type = color_type;
    switch( color_type ) {
    case PNG_COLOR_TYPE_RGB_ALPHA:
        printf("rgba\n");
        data = malloc(w*h*4);
        png_attr->buf = data;
        for( y=0; y<h; ++y ) {
            for( x=0; x<w*4; ) {
                /* 以下是RGBA数据,需要自己补充代码,保存RGBA数据 */
                data[index++] = row_pointers[y][x++]; // red
                data[index++] = row_pointers[y][x++]; // green
                data[index++] = row_pointers[y][x++]; // blue
                data[index++] = row_pointers[y][x++]; // alpha
            }
        }
        break;

    case PNG_COLOR_TYPE_RGB:
        printf("rgb\n");
        data = malloc(w*h*3);
        png_attr->buf = data;
        for( y=0; y<h; ++y ) {
            for( x=0; x<w*3; ) {
                data[index++] = row_pointers[y][x++]; // red
                data[index++] = row_pointers[y][x++]; // green
                data[index++] = row_pointers[y][x++]; // blue
            }
        }
        break;
        /* 其它色彩类型的图像就不读了 */
    default:
        fclose(fp);
        png_destroy_read_struct( &png_ptr, &info_ptr, 0);
        return -2;
    }
    png_destroy_read_struct( &png_ptr, &info_ptr, 0);
    return 0;
}
Example #27
0
/* Read a PNG file.  You may want to return an error code if the read
 * fails (depending upon the failure).  There are two "prototypes" given
 * here - one where we are given the filename, and we need to open the
 * file, and the other where we are given an open file (possibly with
 * some or all of the magic bytes read - see comments above).
 */
#ifdef open_file /* prototype 1 */
void read_png(char *file_name)  /* We need to open the file */
{
   png_structp png_ptr;
   png_infop info_ptr;
   unsigned int sig_read = 0;
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type;
   FILE *fp;

   if ((fp = fopen(file_name, "rb")) == NULL)
      return (ERROR);
#else no_open_file /* prototype 2 */
void read_png(FILE *fp, unsigned int sig_read)  /* file is already open */
{
   png_structp png_ptr;
   png_infop info_ptr;
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type;
#endif no_open_file /* only use one prototype! */

   /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.  REQUIRED
    */
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
      png_voidp user_error_ptr, user_error_fn, user_warning_fn);

   if (png_ptr == NULL)
   {
      fclose(fp);
      return (ERROR);
   }

   /* Allocate/initialize the memory for image information.  REQUIRED. */
   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL)
   {
      fclose(fp);
      png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
      return (ERROR);
   }

   /* Set error handling if you are using the setjmp/longjmp method (this is
    * the normal method of doing things with libpng).  REQUIRED unless you
    * set up your own error handlers in the png_create_read_struct() earlier.
    */

   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);
      /* If we get here, we had a problem reading the file */
      return (ERROR);
   }

   /* One of the following I/O initialization methods is REQUIRED */
#ifdef streams /* PNG file I/O method 1 */
   /* Set up the input control if you are using standard C streams */
   png_init_io(png_ptr, fp);

#else no_streams /* PNG file I/O method 2 */
   /* If you are using replacement read functions, instead of calling
    * png_init_io() here you would call:
    */
   png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
   /* where user_io_ptr is a structure you want available to the callbacks */
#endif no_streams /* Use only one I/O method! */

   /* If we have already read some of the signature */
   png_set_sig_bytes(png_ptr, sig_read);

#ifdef hilevel
   /*
    * If you have enough memory to read in the entire image at once,
    * and you need to specify only transforms that can be controlled
    * with one of the PNG_TRANSFORM_* bits (this presently excludes
    * dithering, filling, setting background, and doing gamma
    * adjustment), then you can read the entire image (including
    * pixels) into the info structure with this call:
    */
   png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);
#else
   /* OK, you're doing it the hard way, with the lower-level functions */

   /* The call to png_read_info() gives us all of the information from the
    * PNG file before the first IDAT (image data chunk).  REQUIRED
    */
   png_read_info(png_ptr, info_ptr);

   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
       &interlace_type, int_p_NULL, int_p_NULL);

/* Set up the data transformations you want.  Note that these are all
 * optional.  Only call them if you want/need them.  Many of the
 * transformations only work on specific types of images, and many
 * are mutually exclusive.
 */

   /* tell libpng to strip 16 bit/color files down to 8 bits/color */
   png_set_strip_16(png_ptr);

   /* Strip alpha bytes from the input data without combining with the
    * background (not recommended).
    */
   png_set_strip_alpha(png_ptr);

   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
    * byte into separate bytes (useful for paletted and grayscale images).
    */
   png_set_packing(png_ptr);

   /* Change the order of packed pixels to least significant bit first
    * (not useful if you are using png_set_packing). */
   png_set_packswap(png_ptr);

   /* Expand paletted colors into true RGB triplets */
   if (color_type == PNG_COLOR_TYPE_PALETTE)
      png_set_palette_rgb(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_gray_1_2_4_to_8(png_ptr);

   /* Expand paletted or RGB images with transparency to full alpha channels
    * so the data will be available as RGBA quartets.
    */
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
      png_set_tRNS_to_alpha(png_ptr);

   /* Set the background color to draw transparent and alpha images over.
    * It is possible to set the red, green, and blue components directly
    * for paletted images instead of supplying a palette index.  Note that
    * even if the PNG file supplies a background, you are not required to
    * use it - you should use the (solid) application background if it has one.
    */

   png_color_16 my_background, *image_background;

   if (png_get_bKGD(png_ptr, info_ptr, &image_background))
      png_set_background(png_ptr, image_background,
                         PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
   else
      png_set_background(png_ptr, &my_background,
                         PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);

   /* Some suggestions as to how to get a screen gamma value */

   /* Note that screen gamma is the display_exponent, which includes
    * the CRT_exponent and any correction for viewing conditions */
   if (/* We have a user-defined screen gamma value */)
   {
      screen_gamma = user-defined screen_gamma;
   }
   /* This is one way that applications share the same screen gamma value */
   else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
Example #28
0
pngdata_t * loadpng(const char * path, int cutoff) {

	png_structp png_ptr;
	png_infop info_ptr;
	png_bytep * row_pointers;
	int width, height, rowbytes;
	int x, y;
        unsigned char header[8];    // 8 is the maximum size that can be checked
	png_byte* ptr;
	FILE *fp;
	int type = 0;
	int lb;
	uint8_t * bitmap;

        /* open file and test for it being a png */
        fp = fopen(path, "rb");
        if (!fp)
                abort_("[read_png_file] File %s could not be opened for reading", path);
        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", path);

        /* initialize stuff */
        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");

        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);

	if (png_get_channels(png_ptr, info_ptr) == 1
	    && png_get_bit_depth(png_ptr, info_ptr) == 1) {
		type = 1;
	} else if (png_get_channels(png_ptr, info_ptr) == 4
	    && png_get_bit_depth(png_ptr, info_ptr) == 8) {
		type = 2;
	}

	if (type == 0) {
		fprintf(stderr, "Invalid PNG! Only mono or 4x8-bit RGBA PNG files are allowed\n");
		exit(1);
	}

        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);

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

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

        rowbytes = type == 1 ? (width / 8) + (width % 8 > 0) : width << 2;

        for (y=0; y<height; y++)
                row_pointers[y] = (png_byte*) malloc(rowbytes);

        png_read_image(png_ptr, row_pointers);

        fclose(fp);

	lb = (height / 8) + (height % 8 > 0);
	bitmap = malloc(width*lb);
	memset(bitmap, 0, width*lb);

	#define heat_on(x, y) bitmap[(x*lb)+(y/8)] |= 1 << (7-(y%8))

  for (y=0; y<height; y++) {
    png_byte* row = row_pointers[y];
    for (x=0; x<width; x++) {
			if (type == 1) {
				ptr = &(row[x/8]);
        if ((ptr[0] & (1 << (7-(x%8)))) == 0) {
          heat_on(x, y);
        }
			} else {
        // Color 0 (red?)
        ptr = &(row[(x<<2)]);
        if (ptr[0] < cutoff) { // Adjust the cutoff (0 to 255). Any pixel darker (lower) than this will be black. Higher will be white. This can be used to turn anti-aliased pngs into monochrome with some desirable cutoff for black and white.
          heat_on(x, y);
        }
        // Color 1 (green?)
        ptr = &(row[(x<<2)+1]);
        if (ptr[0] < cutoff) {
          heat_on(x, y);
        }
        // Color 2 (blue?)
        ptr = &(row[(x<<2)+2]);
        if (ptr[0] < cutoff) {
          heat_on(x, y);
        }
        //        if ((ptr[0] & (1 << (7-(x%8)))) == 0) {
        //          heat_on(x, y);
        ///        }
			}
    }
  }
  
  /*

  for (y=0; y<height; y++) {
    png_byte* row = row_pointers[y+height*2];
    for (x=0; x<width; x++) {
      ptr = &(row[(x<<2)]);
      if ((ptr[0] & (1 << (7-(x%8)))) == 0) {
        heat_on(x, y+height*2);
      }
    }
  }
  */

	pngdata_t * ret = malloc(sizeof(pngdata_t));
	ret->w = height;
	ret->h = width;
	ret->data = bitmap;
	return ret;
}
Example #29
0
File: png.c Project: UIKit0/picogui
g_error png_load(hwrbitmap *hbmp, const u8 *data, u32 datalen) {
  png_structp png_ptr;
  png_infop info_ptr;
  struct datablock d;
  png_bytep *row_pointers;
  png_uint_32 width, height;
  int bit_depth,colortype,interlace;
  int x,y;
  u8 r,g,b,a;
  pgcolor c;
  png_bytep p;
  g_error e;
  png_colorp palette;
  int num_palette;
  png_colorp pp;
  png_bytep trans;
  int num_trans = 0;
#ifdef CONFIG_DITHER
  hwrdither dither;
#endif

  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (!png_ptr)
    return mkerror(PG_ERRT_IO, 68);   /* Error initializing libpng */
  
  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
    return mkerror(PG_ERRT_IO, 68);   /* Error initializing libpng */
  }

  /* Set libpng error handler */
  if (setjmp(png_jmpbuf(png_ptr))) {
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    return mkerror(PG_ERRT_IO, 71);   /* Error reading PNG */
  }

  /* Set libpng read handler */
  d.data = data;
  d.length = datalen;
  png_set_read_fn(png_ptr, &d, (png_rw_ptr) &png_user_read_data);

  /* Read the png into memory */
  png_read_png(png_ptr, info_ptr, 
	       PNG_TRANSFORM_STRIP_16 | 
	       PNG_TRANSFORM_PACKING, 
	       NULL);
  row_pointers = png_get_rows(png_ptr, info_ptr);
  png_get_IHDR(png_ptr, info_ptr, &width, &height,
	       &bit_depth, &colortype, &interlace, NULL, NULL);
  if (colortype == PNG_COLOR_TYPE_PALETTE) {
    png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
  }
  if (interlace != PNG_INTERLACE_NONE)
    fprintf(stderr, "png loader: OOPS... interlaced image, will b0rk\n");
  
  /* Allocate the picogui bitmap
   *
   * Important note: normally we create bitmaps at the display's
   *                 color depth, but if we have an alpha channel
   *                 we need room for ARGB colors.
   */
  if (colortype == PNG_COLOR_TYPE_GRAY_ALPHA ||
      colortype == PNG_COLOR_TYPE_RGB_ALPHA ||
      num_trans)
    e = vid->bitmap_new(hbmp,width,height,32);
  else
    e = vid->bitmap_new(hbmp,width,height,vid->bpp);
  if (iserror(e))
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);    
  errorcheck;

#ifdef CONFIG_DITHER
  /* Start dithering */
  e = vid->dither_start(&dither, *hbmp, 0,0,0,width,height);
  errorcheck;
#endif

  /* Transcribe it into a picogui bitmap. 
   * This method is slow, but ensures compatibility 
   */
  for (y=0;y<height;y++) {
    p = row_pointers[y];
    for (x=0;x<width;x++) {
      switch (colortype) {

      case PNG_COLOR_TYPE_GRAY:
	g = *(p++);
	c = mkcolor(g,g,g);
	break;

      case PNG_COLOR_TYPE_GRAY_ALPHA:
	g = *(p++);
	a = *(p++);
	c = mkcolora(a>>1,g,g,g);
	break;

      case PNG_COLOR_TYPE_PALETTE:
	pp = &palette[ (*p) % num_palette ];
	if (*p < num_trans)
	  c = mkcolora(trans[*p]>>1, pp->red, pp->green, pp->blue);
	else if (num_trans)
	  c = mkcolora(0x7f, pp->red, pp->green, pp->blue);
	else
	  c = mkcolor(pp->red, pp->green, pp->blue);
	p++;
	break;

      case PNG_COLOR_TYPE_RGB:
	r = *(p++);
	g = *(p++);
	b = *(p++);
	c = mkcolor(r,g,b);
	break;

      case PNG_COLOR_TYPE_RGB_ALPHA:
	r = *(p++);
	g = *(p++);
	b = *(p++);
	a = *(p++);
	c = mkcolora(a>>1,r,g,b);
	break;
	
      }
#ifdef CONFIG_DITHER
      vid->dither_store(dither, c, PG_LGOP_NONE);
#else
      vid->pixel(*hbmp,x,y,VID(color_pgtohwr)(c),PG_LGOP_NONE);
#endif
    }
  }
Example #30
0
int
load_png_graphics (char *txt_filename, char *png_filename)
{
    png_uint_32 row;
    png_structp png_ptr;
    png_infop info_ptr;
    unsigned int sig_read = 0;
    png_uint_32 width, height;
    int bit_depth, color_type, interlace_type;
    FILE *fp, *txt_fp;
    png_bytep *row_pointers;

    if ((fp = fopen(png_filename, "rb")) == NULL)
	return (ERROR);

    if ((txt_fp = fopen(txt_filename, "r")) == NULL)
	return (ERROR);

    /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.  REQUIRED
    */
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
	(png_voidp) user_error_ptr, user_error_fn, user_warning_fn);

    if (png_ptr == NULL) {
	fclose(fp);
	return (ERROR);
    }

    /* Allocate/initialize the memory for image information.  REQUIRED. */
    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
	fclose(fp);
#if defined (commentout)
	png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
#endif
	png_destroy_read_struct(&png_ptr, NULL, NULL);
	return (ERROR);
    }

   /* Set error handling if you are using the setjmp/longjmp method (this is
    * the normal method of doing things with libpng).  REQUIRED unless you
    * set up your own error handlers in the png_create_read_struct() earlier.
    */
    if (setjmp(png_jmpbuf(png_ptr))) {
	/* Free all of the memory associated with the png_ptr and info_ptr */
#if defined (commentout)
	png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
#endif
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	fclose(fp);
	/* If we get here, we had a problem reading the file */
	return (ERROR);
    }

    /* Set up the input control if you are using standard C streams */
    png_init_io(png_ptr, fp);

    /* If we have already read some of the signature */
    png_set_sig_bytes(png_ptr, sig_read);

    /* OK, you're doing it the hard way, with the lower-level functions */
    /* The call to png_read_info() gives us all of the information from the
    * PNG file before the first IDAT (image data chunk).  REQUIRED
    */
    png_read_info(png_ptr, info_ptr);

#if defined (commentout)
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
	&interlace_type, int_p_NULL, int_p_NULL);
#endif
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
	&interlace_type, NULL, NULL);

    printf ("PNG Header: %d x %d, bd=%d, ct=%d\n", height, width,
	bit_depth, color_type);

    /* Set up the data transformations you want.  Note that these are all
     * optional.  Only call them if you want/need them.  Many of the
     * transformations only work on specific types of images, and many
     * are mutually exclusive.
     */

   /* tell libpng to strip 16 bit/color files down to 8 bits/color */
//   png_set_strip_16(png_ptr);

   /* Strip alpha bytes from the input data without combining with the
    * background (not recommended).
    */
//   png_set_strip_alpha(png_ptr);

   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
    * byte into separate bytes (useful for paletted and grayscale images).
    */
//   png_set_packing(png_ptr);

   /* Change the order of packed pixels to least significant bit first
    * (not useful if you are using png_set_packing). */
//   png_set_packswap(png_ptr);

   /* Require color fmt w/ palette */
   if (color_type != PNG_COLOR_TYPE_PALETTE) {
	printf ("Error - png image wasn't PNG_COLOR_TYPE_PALETTE\n");
	/* Free all of the memory associated with the png_ptr and info_ptr */
#if defined (commentout)
	png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
#endif
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	fclose(fp);
	/* If we get here, we had a problem reading the file */
	return (ERROR);
   }

   /* Require 1 byte per pixel */
   if (bit_depth != 8) {
	printf ("Error - png image wasn't bit_depth = 8\n");
	/* Free all of the memory associated with the png_ptr and info_ptr */
#if defined (commentout)
	png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
#endif
	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
	fclose(fp);
	/* If we get here, we had a problem reading the file */
	return (ERROR);
   }

    /* The easiest way to read the image: */
    row_pointers = malloc (sizeof(void*)*height);
    for (row = 0; row < height; row++) {
	row_pointers[row] = png_malloc(png_ptr, 
	    png_get_rowbytes(png_ptr, info_ptr));
    }

    png_read_image(png_ptr, row_pointers);

#if defined (commentout)
    for (col = 0; col < 16; col++) {
	printf (" %02x ",row_pointers[0][col]);
    }
    printf ("\n");

    for (col = 0; col < 16; col++) {
	printf ("%3d ",row_pointers[0][col]);
    }
    printf ("\n");
#endif

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

    /* close the png file */
    fclose(fp);

    /* get the icons out of the png */
#ifdef LG
#undef LG
#endif
#define LG(typ,grp,id) load_png_graphic(typ,grp,id,txt_fp,row_pointers,height,width)

    LG(CST_GREEN,GROUP_BARE,LCT_GREEN_G);

    LG(CST_FIRE_1,GROUP_FIRE,LCT_FIRE_1_G);
    LG(CST_FIRE_2,GROUP_FIRE,LCT_FIRE_2_G);
    LG(CST_FIRE_3,GROUP_FIRE,LCT_FIRE_3_G);
    LG(CST_FIRE_4,GROUP_FIRE,LCT_FIRE_4_G);
    LG(CST_FIRE_5,GROUP_FIRE,LCT_FIRE_5_G);

    LG(CST_FIRE_DONE1,GROUP_FIRE,LCT_FIRE_DONE1_G);
    LG(CST_FIRE_DONE2,GROUP_FIRE,LCT_FIRE_DONE2_G);
    LG(CST_FIRE_DONE3,GROUP_FIRE,LCT_FIRE_DONE3_G);
    LG(CST_FIRE_DONE4,GROUP_FIRE,LCT_FIRE_DONE4_G);

    LG(CST_BURNT,GROUP_BURNT,LCT_BURNT_G);

    LG(CST_PARKLAND_PLANE,GROUP_PARKLAND,LCT_PARKLAND_PLANE_G);
    LG(CST_PARKLAND_LAKE,GROUP_PARKLAND,LCT_PARKLAND_LAKE_G);

    LG(CST_POWERL_H_L,GROUP_POWER_LINE,LCT_POWERL_H_L_G);
    LG(CST_POWERL_V_L,GROUP_POWER_LINE,LCT_POWERL_V_L_G);
    LG(CST_POWERL_LD_L,GROUP_POWER_LINE,LCT_POWERL_LD_L_G);
    LG(CST_POWERL_RD_L,GROUP_POWER_LINE,LCT_POWERL_RD_L_G);
    LG(CST_POWERL_LU_L,GROUP_POWER_LINE,LCT_POWERL_LU_L_G);
    LG(CST_POWERL_RU_L,GROUP_POWER_LINE,LCT_POWERL_RU_L_G);
    LG(CST_POWERL_LDU_L,GROUP_POWER_LINE,LCT_POWERL_LDU_L_G);
    LG(CST_POWERL_LDR_L,GROUP_POWER_LINE,LCT_POWERL_LDR_L_G);
    LG(CST_POWERL_LUR_L,GROUP_POWER_LINE,LCT_POWERL_LUR_L_G);
    LG(CST_POWERL_UDR_L,GROUP_POWER_LINE,LCT_POWERL_UDR_L_G);
    LG(CST_POWERL_LUDR_L,GROUP_POWER_LINE,LCT_POWERL_LUDR_L_G);
    LG(CST_POWERL_H_D,GROUP_POWER_LINE,LCT_POWERL_H_D_G);
    LG(CST_POWERL_V_D,GROUP_POWER_LINE,LCT_POWERL_V_D_G);
    LG(CST_POWERL_LD_D,GROUP_POWER_LINE,LCT_POWERL_LD_D_G);
    LG(CST_POWERL_RD_D,GROUP_POWER_LINE,LCT_POWERL_RD_D_G);
    LG(CST_POWERL_LU_D,GROUP_POWER_LINE,LCT_POWERL_LU_D_G);
    LG(CST_POWERL_RU_D,GROUP_POWER_LINE,LCT_POWERL_RU_D_G);
    LG(CST_POWERL_LDU_D,GROUP_POWER_LINE,LCT_POWERL_LDU_D_G);
    LG(CST_POWERL_LDR_D,GROUP_POWER_LINE,LCT_POWERL_LDR_D_G);
    LG(CST_POWERL_LUR_D,GROUP_POWER_LINE,LCT_POWERL_LUR_D_G);
    LG(CST_POWERL_UDR_D,GROUP_POWER_LINE,LCT_POWERL_UDR_D_G);
    LG(CST_POWERL_LUDR_D,GROUP_POWER_LINE,LCT_POWERL_LUDR_D_G);

    LG(CST_RAIL_LR,GROUP_RAIL,LCT_RAIL_LR_G);
    LG(CST_RAIL_LU,GROUP_RAIL,LCT_RAIL_LU_G);
    LG(CST_RAIL_LD,GROUP_RAIL,LCT_RAIL_LD_G);
    LG(CST_RAIL_UD,GROUP_RAIL,LCT_RAIL_UD_G);
    LG(CST_RAIL_UR,GROUP_RAIL,LCT_RAIL_UR_G);
    LG(CST_RAIL_DR,GROUP_RAIL,LCT_RAIL_DR_G);
    LG(CST_RAIL_LUR,GROUP_RAIL,LCT_RAIL_LUR_G);
    LG(CST_RAIL_LDR,GROUP_RAIL,LCT_RAIL_LDR_G);
    LG(CST_RAIL_LUD,GROUP_RAIL,LCT_RAIL_LUD_G);
    LG(CST_RAIL_UDR,GROUP_RAIL,LCT_RAIL_UDR_G);
    LG(CST_RAIL_LUDR,GROUP_RAIL,LCT_RAIL_LUDR_G);

    LG(CST_ROAD_LR,GROUP_ROAD,LCT_ROAD_LR_G);
    LG(CST_ROAD_LU,GROUP_ROAD,LCT_ROAD_LU_G);
    LG(CST_ROAD_LD,GROUP_ROAD,LCT_ROAD_LD_G);
    LG(CST_ROAD_UD,GROUP_ROAD,LCT_ROAD_UD_G);
    LG(CST_ROAD_UR,GROUP_ROAD,LCT_ROAD_UR_G);
    LG(CST_ROAD_DR,GROUP_ROAD,LCT_ROAD_DR_G);
    LG(CST_ROAD_LUR,GROUP_ROAD,LCT_ROAD_LUR_G);
    LG(CST_ROAD_LDR,GROUP_ROAD,LCT_ROAD_LDR_G);
    LG(CST_ROAD_LUD,GROUP_ROAD,LCT_ROAD_LUD_G);
    LG(CST_ROAD_UDR,GROUP_ROAD,LCT_ROAD_UDR_G);
    LG(CST_ROAD_LUDR,GROUP_ROAD,LCT_ROAD_LUDR_G);

    LG(CST_TRACK_LR,GROUP_TRACK,LCT_TRACK_LR_G);
    LG(CST_TRACK_LU,GROUP_TRACK,LCT_TRACK_LU_G);
    LG(CST_TRACK_LD,GROUP_TRACK,LCT_TRACK_LD_G);
    LG(CST_TRACK_UD,GROUP_TRACK,LCT_TRACK_UD_G);
    LG(CST_TRACK_UR,GROUP_TRACK,LCT_TRACK_UR_G);
    LG(CST_TRACK_DR,GROUP_TRACK,LCT_TRACK_DR_G);
    LG(CST_TRACK_LUR,GROUP_TRACK,LCT_TRACK_LUR_G);
    LG(CST_TRACK_LDR,GROUP_TRACK,LCT_TRACK_LDR_G);
    LG(CST_TRACK_LUD,GROUP_TRACK,LCT_TRACK_LUD_G);
    LG(CST_TRACK_UDR,GROUP_TRACK,LCT_TRACK_UDR_G);
    LG(CST_TRACK_LUDR,GROUP_TRACK,LCT_TRACK_LUDR_G);

    LG(CST_WATER,GROUP_WATER,LCT_WATER_G);
    LG(CST_WATER_D,GROUP_WATER,LCT_WATER_D_G);
    LG(CST_WATER_R,GROUP_WATER,LCT_WATER_R_G);
    LG(CST_WATER_U,GROUP_WATER,LCT_WATER_U_G);
    LG(CST_WATER_L,GROUP_WATER,LCT_WATER_L_G);
    LG(CST_WATER_LR,GROUP_WATER,LCT_WATER_LR_G);
    LG(CST_WATER_UD,GROUP_WATER,LCT_WATER_UD_G);
    LG(CST_WATER_LD,GROUP_WATER,LCT_WATER_LD_G);
    LG(CST_WATER_RD,GROUP_WATER,LCT_WATER_RD_G);
    LG(CST_WATER_LU,GROUP_WATER,LCT_WATER_LU_G);
    LG(CST_WATER_UR,GROUP_WATER,LCT_WATER_UR_G);
    LG(CST_WATER_LUD,GROUP_WATER,LCT_WATER_LUD_G);
    LG(CST_WATER_LRD,GROUP_WATER,LCT_WATER_LRD_G);
    LG(CST_WATER_LUR,GROUP_WATER,LCT_WATER_LUR_G);
    LG(CST_WATER_URD,GROUP_WATER,LCT_WATER_URD_G);
    LG(CST_WATER_LURD,GROUP_WATER,LCT_WATER_LURD_G);

    LG(CST_BLACKSMITH_0,GROUP_BLACKSMITH,LCT_BLACKSMITH_0_G);
    LG(CST_BLACKSMITH_1,GROUP_BLACKSMITH,LCT_BLACKSMITH_1_G);
    LG(CST_BLACKSMITH_2,GROUP_BLACKSMITH,LCT_BLACKSMITH_2_G);
    LG(CST_BLACKSMITH_3,GROUP_BLACKSMITH,LCT_BLACKSMITH_3_G);
    LG(CST_BLACKSMITH_4,GROUP_BLACKSMITH,LCT_BLACKSMITH_4_G);
    LG(CST_BLACKSMITH_5,GROUP_BLACKSMITH,LCT_BLACKSMITH_5_G);
    LG(CST_BLACKSMITH_6,GROUP_BLACKSMITH,LCT_BLACKSMITH_6_G);

    LG(CST_CRICKET_1,GROUP_CRICKET,LCT_CRICKET_1_G);
    LG(CST_CRICKET_2,GROUP_CRICKET,LCT_CRICKET_2_G);
    LG(CST_CRICKET_3,GROUP_CRICKET,LCT_CRICKET_3_G);
    LG(CST_CRICKET_4,GROUP_CRICKET,LCT_CRICKET_4_G);
    LG(CST_CRICKET_5,GROUP_CRICKET,LCT_CRICKET_5_G);
    LG(CST_CRICKET_6,GROUP_CRICKET,LCT_CRICKET_6_G);
    LG(CST_CRICKET_7,GROUP_CRICKET,LCT_CRICKET_7_G);

    LG(CST_FIRESTATION_1,GROUP_FIRESTATION,LCT_FIRESTATION_1_G);
    LG(CST_FIRESTATION_2,GROUP_FIRESTATION,LCT_FIRESTATION_2_G);
    LG(CST_FIRESTATION_3,GROUP_FIRESTATION,LCT_FIRESTATION_3_G);
    LG(CST_FIRESTATION_4,GROUP_FIRESTATION,LCT_FIRESTATION_4_G);
    LG(CST_FIRESTATION_5,GROUP_FIRESTATION,LCT_FIRESTATION_5_G);
    LG(CST_FIRESTATION_6,GROUP_FIRESTATION,LCT_FIRESTATION_6_G);
    LG(CST_FIRESTATION_7,GROUP_FIRESTATION,LCT_FIRESTATION_7_G);
    LG(CST_FIRESTATION_8,GROUP_FIRESTATION,LCT_FIRESTATION_8_G);
    LG(CST_FIRESTATION_9,GROUP_FIRESTATION,LCT_FIRESTATION_9_G);
    LG(CST_FIRESTATION_10,GROUP_FIRESTATION,LCT_FIRESTATION_10_G);

    LG(CST_HEALTH,GROUP_HEALTH,LCT_HEALTH_G);

    LG(CST_MARKET_EMPTY,GROUP_MARKET,LCT_MARKET_EMPTY_G);
    LG(CST_MARKET_LOW,GROUP_MARKET,LCT_MARKET_LOW_G);
    LG(CST_MARKET_MED,GROUP_MARKET,LCT_MARKET_MED_G);
    LG(CST_MARKET_FULL,GROUP_MARKET,LCT_MARKET_FULL_G);

    LG(CST_MILL_0,GROUP_MILL,LCT_MILL_0_G);
    LG(CST_MILL_1,GROUP_MILL,LCT_MILL_1_G);
    LG(CST_MILL_2,GROUP_MILL,LCT_MILL_2_G);
    LG(CST_MILL_3,GROUP_MILL,LCT_MILL_3_G);
    LG(CST_MILL_4,GROUP_MILL,LCT_MILL_4_G);
    LG(CST_MILL_5,GROUP_MILL,LCT_MILL_5_G);
    LG(CST_MILL_6,GROUP_MILL,LCT_MILL_6_G);

    LG(CST_MONUMENT_0,GROUP_MONUMENT,LCT_MONUMENT_0_G);
    LG(CST_MONUMENT_1,GROUP_MONUMENT,LCT_MONUMENT_1_G);
    LG(CST_MONUMENT_2,GROUP_MONUMENT,LCT_MONUMENT_2_G);
    LG(CST_MONUMENT_3,GROUP_MONUMENT,LCT_MONUMENT_3_G);
    LG(CST_MONUMENT_4,GROUP_MONUMENT,LCT_MONUMENT_4_G);
    LG(CST_MONUMENT_5,GROUP_MONUMENT,LCT_MONUMENT_5_G);

    LG(CST_POTTERY_0,GROUP_POTTERY,LCT_POTTERY_0_G);
    LG(CST_POTTERY_1,GROUP_POTTERY,LCT_POTTERY_1_G);
    LG(CST_POTTERY_2,GROUP_POTTERY,LCT_POTTERY_2_G);
    LG(CST_POTTERY_3,GROUP_POTTERY,LCT_POTTERY_3_G);
    LG(CST_POTTERY_4,GROUP_POTTERY,LCT_POTTERY_4_G);
    LG(CST_POTTERY_5,GROUP_POTTERY,LCT_POTTERY_5_G);
    LG(CST_POTTERY_6,GROUP_POTTERY,LCT_POTTERY_6_G);
    LG(CST_POTTERY_7,GROUP_POTTERY,LCT_POTTERY_7_G);
    LG(CST_POTTERY_8,GROUP_POTTERY,LCT_POTTERY_8_G);
    LG(CST_POTTERY_9,GROUP_POTTERY,LCT_POTTERY_9_G);
    LG(CST_POTTERY_10,GROUP_POTTERY,LCT_POTTERY_10_G);

    LG(CST_RECYCLE,GROUP_RECYCLE,LCT_RECYCLE_G);

    LG(CST_SCHOOL,GROUP_SCHOOL,LCT_SCHOOL_G);

    LG(CST_SHANTY,GROUP_SHANTY,LCT_SHANTY_G);

    LG(CST_SUBSTATION_R,GROUP_SUBSTATION,LCT_SUBSTATION_R_G);
    LG(CST_SUBSTATION_G,GROUP_SUBSTATION,LCT_SUBSTATION_G_G);
    LG(CST_SUBSTATION_RG,GROUP_SUBSTATION,LCT_SUBSTATION_RG_G);

    LG(CST_WINDMILL_1_G,GROUP_WINDMILL,LCT_WINDMILL_1_G_G);
    LG(CST_WINDMILL_2_G,GROUP_WINDMILL,LCT_WINDMILL_2_G_G);
    LG(CST_WINDMILL_3_G,GROUP_WINDMILL,LCT_WINDMILL_3_G_G);
    LG(CST_WINDMILL_1_RG,GROUP_WINDMILL,LCT_WINDMILL_1_RG_G);
    LG(CST_WINDMILL_2_RG,GROUP_WINDMILL,LCT_WINDMILL_2_RG_G);
    LG(CST_WINDMILL_3_RG,GROUP_WINDMILL,LCT_WINDMILL_3_RG_G);
    LG(CST_WINDMILL_1_R,GROUP_WINDMILL,LCT_WINDMILL_1_R_G);
    LG(CST_WINDMILL_2_R,GROUP_WINDMILL,LCT_WINDMILL_2_R_G);
    LG(CST_WINDMILL_3_R,GROUP_WINDMILL,LCT_WINDMILL_3_R_G);
    LG(CST_WINDMILL_1_W,GROUP_WINDMILL,LCT_WINDMILL_1_W_G);
    LG(CST_WINDMILL_2_W,GROUP_WINDMILL,LCT_WINDMILL_2_W_G);
    LG(CST_WINDMILL_3_W,GROUP_WINDMILL,LCT_WINDMILL_3_W_G);

    LG(CST_INDUSTRY_L_C,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_C_G);
    LG(CST_INDUSTRY_L_Q1,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_Q1_G);
    LG(CST_INDUSTRY_L_Q2,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_Q2_G);
    LG(CST_INDUSTRY_L_Q3,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_Q3_G);
    LG(CST_INDUSTRY_L_Q4,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_Q4_G);
    LG(CST_INDUSTRY_L_L1,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_L1_G);
    LG(CST_INDUSTRY_L_L2,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_L2_G);
    LG(CST_INDUSTRY_L_L3,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_L3_G);
    LG(CST_INDUSTRY_L_L4,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_L4_G);
    LG(CST_INDUSTRY_L_M1,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_M1_G);
    LG(CST_INDUSTRY_L_M2,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_M2_G);
    LG(CST_INDUSTRY_L_M3,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_M3_G);
    LG(CST_INDUSTRY_L_M4,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_M4_G);
    LG(CST_INDUSTRY_L_H1,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_H1_G);
    LG(CST_INDUSTRY_L_H2,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_H2_G);
    LG(CST_INDUSTRY_L_H3,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_H3_G);
    LG(CST_INDUSTRY_L_H4,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_H4_G);

    LG(CST_RESIDENCE_LL,GROUP_RESIDENCE_LL,LCT_RESIDENCE_LL_G);
    LG(CST_RESIDENCE_ML,GROUP_RESIDENCE_ML,LCT_RESIDENCE_ML_G);
    LG(CST_RESIDENCE_HL,GROUP_RESIDENCE_HL,LCT_RESIDENCE_HL_G);
    LG(CST_RESIDENCE_LH,GROUP_RESIDENCE_LH,LCT_RESIDENCE_LH_G);
    LG(CST_RESIDENCE_MH,GROUP_RESIDENCE_MH,LCT_RESIDENCE_MH_G);
    LG(CST_RESIDENCE_HH,GROUP_RESIDENCE_HH,LCT_RESIDENCE_HH_G);

    LG(CST_UNIVERSITY,GROUP_UNIVERSITY,LCT_UNIVERSITY_G);

    LG(CST_COALMINE_EMPTY,GROUP_COALMINE,LCT_COALMINE_EMPTY_G);
    LG(CST_COALMINE_LOW,GROUP_COALMINE,LCT_COALMINE_LOW_G);
    LG(CST_COALMINE_MED,GROUP_COALMINE,LCT_COALMINE_MED_G);
    LG(CST_COALMINE_FULL,GROUP_COALMINE,LCT_COALMINE_FULL_G);

    LG(CST_COMMUNE_1,GROUP_COMMUNE,LCT_COMMUNE_1_G);
    LG(CST_COMMUNE_2,GROUP_COMMUNE,LCT_COMMUNE_2_G);
    LG(CST_COMMUNE_3,GROUP_COMMUNE,LCT_COMMUNE_3_G);
    LG(CST_COMMUNE_4,GROUP_COMMUNE,LCT_COMMUNE_4_G);
    LG(CST_COMMUNE_5,GROUP_COMMUNE,LCT_COMMUNE_5_G);
    LG(CST_COMMUNE_6,GROUP_COMMUNE,LCT_COMMUNE_6_G);
    LG(CST_COMMUNE_7,GROUP_COMMUNE,LCT_COMMUNE_7_G);
    LG(CST_COMMUNE_8,GROUP_COMMUNE,LCT_COMMUNE_8_G);
    LG(CST_COMMUNE_9,GROUP_COMMUNE,LCT_COMMUNE_9_G);
    LG(CST_COMMUNE_10,GROUP_COMMUNE,LCT_COMMUNE_10_G);
    LG(CST_COMMUNE_11,GROUP_COMMUNE,LCT_COMMUNE_11_G);
    LG(CST_COMMUNE_12,GROUP_COMMUNE,LCT_COMMUNE_12_G);
    LG(CST_COMMUNE_13,GROUP_COMMUNE,LCT_COMMUNE_13_G);
    LG(CST_COMMUNE_14,GROUP_COMMUNE,LCT_COMMUNE_14_G);

    LG(CST_EX_PORT,GROUP_PORT,LCT_EX_PORT_G);

    LG(CST_FARM_O0,GROUP_ORGANIC_FARM,LCT_FARM_O0_G);
    LG(CST_FARM_O1,GROUP_ORGANIC_FARM,LCT_FARM_O1_G);
    LG(CST_FARM_O2,GROUP_ORGANIC_FARM,LCT_FARM_O2_G);
    LG(CST_FARM_O3,GROUP_ORGANIC_FARM,LCT_FARM_O3_G);
    LG(CST_FARM_O4,GROUP_ORGANIC_FARM,LCT_FARM_O4_G);
    LG(CST_FARM_O5,GROUP_ORGANIC_FARM,LCT_FARM_O5_G);
    LG(CST_FARM_O6,GROUP_ORGANIC_FARM,LCT_FARM_O6_G);
    LG(CST_FARM_O7,GROUP_ORGANIC_FARM,LCT_FARM_O7_G);
    LG(CST_FARM_O8,GROUP_ORGANIC_FARM,LCT_FARM_O8_G);
    LG(CST_FARM_O9,GROUP_ORGANIC_FARM,LCT_FARM_O9_G);
    LG(CST_FARM_O10,GROUP_ORGANIC_FARM,LCT_FARM_O10_G);
    LG(CST_FARM_O11,GROUP_ORGANIC_FARM,LCT_FARM_O11_G);
    LG(CST_FARM_O12,GROUP_ORGANIC_FARM,LCT_FARM_O12_G);
    LG(CST_FARM_O13,GROUP_ORGANIC_FARM,LCT_FARM_O13_G);
    LG(CST_FARM_O14,GROUP_ORGANIC_FARM,LCT_FARM_O14_G);
    LG(CST_FARM_O15,GROUP_ORGANIC_FARM,LCT_FARM_O15_G);
    LG(CST_FARM_O16,GROUP_ORGANIC_FARM,LCT_FARM_O16_G);

    LG(CST_INDUSTRY_H_C,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_C_G);
    LG(CST_INDUSTRY_H_L1,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L1_G);
    LG(CST_INDUSTRY_H_L2,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L2_G);
    LG(CST_INDUSTRY_H_L3,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L3_G);
    LG(CST_INDUSTRY_H_L4,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L4_G);
    LG(CST_INDUSTRY_H_L5,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L5_G);
    LG(CST_INDUSTRY_H_L6,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L6_G);
    LG(CST_INDUSTRY_H_L7,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L7_G);
    LG(CST_INDUSTRY_H_L8,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L8_G);
    LG(CST_INDUSTRY_H_M1,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M1_G);
    LG(CST_INDUSTRY_H_M2,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M2_G);
    LG(CST_INDUSTRY_H_M3,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M3_G);
    LG(CST_INDUSTRY_H_M4,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M4_G);
    LG(CST_INDUSTRY_H_M5,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M5_G);
    LG(CST_INDUSTRY_H_M6,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M6_G);
    LG(CST_INDUSTRY_H_M7,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M7_G);
    LG(CST_INDUSTRY_H_M8,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M8_G);
    LG(CST_INDUSTRY_H_H1,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H1_G);
    LG(CST_INDUSTRY_H_H2,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H2_G);
    LG(CST_INDUSTRY_H_H3,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H3_G);
    LG(CST_INDUSTRY_H_H4,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H4_G);
    LG(CST_INDUSTRY_H_H5,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H5_G);
    LG(CST_INDUSTRY_H_H6,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H6_G);
    LG(CST_INDUSTRY_H_H7,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H7_G);
    LG(CST_INDUSTRY_H_H8,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H8_G);

    LG(CST_OREMINE_1,GROUP_OREMINE,LCT_OREMINE_1_G);
    LG(CST_OREMINE_2,GROUP_OREMINE,LCT_OREMINE_2_G);
    LG(CST_OREMINE_3,GROUP_OREMINE,LCT_OREMINE_3_G);
    LG(CST_OREMINE_4,GROUP_OREMINE,LCT_OREMINE_4_G);
    LG(CST_OREMINE_5,GROUP_OREMINE,LCT_OREMINE_5_G);
    LG(CST_OREMINE_6,GROUP_OREMINE,LCT_OREMINE_6_G);
    LG(CST_OREMINE_7,GROUP_OREMINE,LCT_OREMINE_7_G);
    LG(CST_OREMINE_8,GROUP_OREMINE,LCT_OREMINE_8_G);

    LG(CST_POWERS_COAL_EMPTY,GROUP_COAL_POWER,LCT_POWERS_COAL_EMPTY_G);
    LG(CST_POWERS_COAL_LOW,GROUP_COAL_POWER,LCT_POWERS_COAL_LOW_G);
    LG(CST_POWERS_COAL_MED,GROUP_COAL_POWER,LCT_POWERS_COAL_MED_G);
    LG(CST_POWERS_COAL_FULL,GROUP_COAL_POWER,LCT_POWERS_COAL_FULL_G);

    LG(CST_POWERS_SOLAR,GROUP_SOLAR_POWER,LCT_POWERS_SOLAR_G);

    LG(CST_ROCKET_1,GROUP_ROCKET,LCT_ROCKET_1_G);
    LG(CST_ROCKET_2,GROUP_ROCKET,LCT_ROCKET_2_G);
    LG(CST_ROCKET_3,GROUP_ROCKET,LCT_ROCKET_3_G);
    LG(CST_ROCKET_4,GROUP_ROCKET,LCT_ROCKET_4_G);
    LG(CST_ROCKET_5,GROUP_ROCKET,LCT_ROCKET_5_G);
    LG(CST_ROCKET_6,GROUP_ROCKET,LCT_ROCKET_6_G);
    LG(CST_ROCKET_7,GROUP_ROCKET,LCT_ROCKET_7_G);
    LG(CST_ROCKET_FLOWN,GROUP_ROCKET,LCT_ROCKET_FLOWN_G);

    LG(CST_TIP_0,GROUP_TIP,LCT_TIP_0_G);
    LG(CST_TIP_1,GROUP_TIP,LCT_TIP_1_G);
    LG(CST_TIP_2,GROUP_TIP,LCT_TIP_2_G);
    LG(CST_TIP_3,GROUP_TIP,LCT_TIP_3_G);
    LG(CST_TIP_4,GROUP_TIP,LCT_TIP_4_G);
    LG(CST_TIP_5,GROUP_TIP,LCT_TIP_5_G);
    LG(CST_TIP_6,GROUP_TIP,LCT_TIP_6_G);
    LG(CST_TIP_7,GROUP_TIP,LCT_TIP_7_G);
    LG(CST_TIP_8,GROUP_TIP,LCT_TIP_8_G);

    // main_t
#undef LG

#if defined (commentout)
    /* PROCESS IMAGE HERE */
    while (!feof(txt_fp)) {
	char buf[128];
	char *fnp,*rip,*cip;
	int ri,ci;

	/* Get line from text file */
	fgets (buf,128,txt_fp);

	/* Tokenize */
	fnp = strtok(buf," \t");
	if (!fnp || *fnp == '#') continue;
	if (*fnp == '@') break;
	rip = strtok(NULL," \t");
	if (!rip) continue;
	cip = strtok(NULL," \t");
	if (!cip) continue;
	ri = atoi(rip);
	ci = atoi(cip);

	/* Copy icon */
	if (!strcmp(fnp,LCT_GREEN_G)) {
	    int r,c;
	    char* p;
            main_types[CST_GREEN].graphic=malloc(16*16);
	    p = main_types[CST_GREEN].graphic;
	    for (r=ri*16;r<ri*16+16;r++) {
	    for (c=ci*16;c<ci*16+16;c++) {
		*p++ = row_pointers[r][c];
	    } }
	}
    }
#endif

    /* Free the memory */
    for (row = 0; row < height; row++) {
	png_free(png_ptr, row_pointers[row]);
    }
    free(row_pointers);

    /* clean up after the read, and free any memory allocated - REQUIRED */
#if defined (commentout)
    png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
#endif
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    /* that's it */
    return (OK);
}