Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

C/C++ vs Good Language

Name: Anonymous 2014-08-27 21:56

Good Language:
texture = png_texture_load file_name

C/C++:
GLuint png_texture_load(const char * file_name, int * width, int * height)
{
png_byte header[8];

FILE *fp = fopen(file_name, "rb");
if (fp == 0)
{
perror(file_name);
return 0;
}

// read the header
fread(header, 1, 8, fp);

if (png_sig_cmp(header, 0, 8))
{
fprintf(stderr, "error: %s is not a PNG.\n", file_name);
fclose(fp);
return 0;
}

png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
fprintf(stderr, "error: png_create_read_struct returned 0.\n");
fclose(fp);
return 0;
}

// create png info struct
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
fprintf(stderr, "error: png_create_info_struct returned 0.\n");
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
fclose(fp);
return 0;
}

// create png info struct
png_infop end_info = png_create_info_struct(png_ptr);
if (!end_info)
{
fprintf(stderr, "error: png_create_info_struct returned 0.\n");
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
fclose(fp);
return 0;
}

// the code in this if statement gets called if libpng encounters an error
if (setjmp(png_jmpbuf(png_ptr))) {
fprintf(stderr, "error from libpng\n");
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
fclose(fp);
return 0;
}

// init png reading
png_init_io(png_ptr, fp);

// let libpng know you already read the first 8 bytes
png_set_sig_bytes(png_ptr, 8);

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

// variables to pass to get info
int bit_depth, color_type;
png_uint_32 temp_width, temp_height;

// get info about png
png_get_IHDR(png_ptr, info_ptr, &temp_width, &temp_height, &bit_depth, &color_type,
NULL, NULL, NULL);

if (width){ *width = temp_width; }
if (height){ *height = temp_height; }

// Update the png info struct.
png_read_update_info(png_ptr, info_ptr);

// Row size in bytes.
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);

// glTexImage2d requires rows to be 4-byte aligned
rowbytes += 3 - ((rowbytes-1) % 4);

// Allocate the image_data as a big block, to be given to opengl
png_byte * image_data;
image_data = malloc(rowbytes * temp_height * sizeof(png_byte)+15);
if (image_data == NULL)
{
fprintf(stderr, "error: could not allocate memory for PNG image data\n");
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
fclose(fp);
return 0;
}

// row_pointers is for pointing to image_data for reading the png with libpng
png_bytep * row_pointers = malloc(temp_height * sizeof(png_bytep));
if (row_pointers == NULL)
{
fprintf(stderr, "error: could not allocate memory for PNG row pointers\n");
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
free(image_data);
fclose(fp);
return 0;
}

// set the individual row_pointers to point at the correct offsets of image_data
int i;
for (i = 0; i < temp_height; i++)
{
row_pointers[temp_height - 1 - i] = image_data + i * rowbytes;
}

// read the png into image_data through row_pointers
png_read_image(png_ptr, row_pointers);

// Generate the OpenGL texture object
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, temp_width, temp_height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// clean up
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
free(image_data);
free(row_pointers);
fclose(fp);
return texture;
}

Name: Anonymous 2014-08-29 22:33

>>1
There's no comparison between the two of those. The code you've listed for "Good language" is a function call, whereas the code you've listed for "C/C++" is a function definition.

libpng is, indeed, quite difficult to handle, but it is not C or C++. One way to get around its unwieldiness is to call a program that translates PNG to RGB or RGBA and, if necessary, resize the image to fit the pixel width and height your program requires. This can be done easily on POSIX with the use of popen(3) and convert(1):

#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>

GLuint rgb_texture(int width, int height, const GLubyte *p)
{
GLuint tex;

glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
GL_UNSIGNED_BYTE, p);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
return tex;
}

int rgb_texture_load(GLuint *texp, int width, int height, FILE *fin)
{
void *p;

if ((p = malloc((size_t) width * height * 3)) == NULL
|| fread(p, (size_t) width * height * 3, 1, fin) != 1) {
free(p);
return -1;
}
*texp = rgb_texture(width, height, p);
free(p);
return 0;
}

GLuint texture_load(GLuint *texp, int width, int height, const char *path)
{
char s[8192];
FILE *fin;

sprintf(s, "convert -resize %dx%d! %s rgb:-", width, height, path);
if ((fin = popen(s, "rb")) == NULL)
return -1;
if (rgb_texture_load(texp, width, height, fin) != 0) {
pclose(fin);
return -2;
}
pclose(fin);
return 0;
}

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List