Войти
ПрограммированиеФорумОбщее

Работа с файлами форматов ZIP, JPEG и PNG. (Комментарии к статье) (3 стр)

Страницы: 1 2 3
#30
11:16, 18 авг. 2011

Эх.. вот скачал один примерчик с NeHe, а он взял и просто сразу заработал. Ну почему так?


#31
11:30, 18 авг. 2011

Мда...статья писалась левой ногой. Сначала автор делает вот так:

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

а в конце вот так:

png_destroy_read_struct(&png_ptr, 0, 0);

А кто info_ptr освобождать будет ?

Правильно делать вот так:

png_destroy_read_struct(&png_ptr, &info_ptr, 0);

чтобы не было утечек памяти!

#32
4:39, 19 авг. 2011

Еще можно посмотреть исходники SDL_Image: http://www.libsdl.org/projects/SDL_image/

Немного модифицировал загрузчик PNG оттуда, чтобы возвращалось изображение в RGB или RGBA формате:

#include <png.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIG_SIZE 8

struct tagImage
{
  void *data;
  int width;
  int height;
  int pitch;
  int bpp;
};


void png_read_data_fn(png_structp png_ptr,
  png_bytep data, png_size_t length)
{
  FILE *file = (FILE*)png_get_io_ptr(png_ptr);
  fread(data, 1, length, file);
}


struct tagImage *PNG_Load(char *filename)
{
  struct tagPNGImage *image;
  FILE *file;
  png_byte sig[SIG_SIZE];
  png_structp png_ptr;
  png_infop info_ptr;
  png_uint_32 width, height, row_bytes;
  int bit_depth, color_type, row, bpp;
  png_bytep data;
  png_bytep *row_pointers;
  file = fopen(filename, "rb");
  if (!file)
    return NULL;
  memset(sig, 0, SIG_SIZE);
  fread(sig, 1, SIG_SIZE, file);
  if (!png_check_sig(sig, SIG_SIZE))
  {
    fclose(file);
    return NULL;
  }
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
    NULL, NULL, NULL);
  if (!png_ptr)
  {
    fclose(file);
    return NULL;
  }
  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
  {
    png_destroy_read_struct(&png_ptr, NULL, NULL);
    fclose(file);
    return NULL;
  }
  png_set_read_fn(png_ptr, (void*)file, png_read_data_fn);
  if (setjmp(png_ptr->jmpbuf))
  {
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    fclose(file);
    return NULL;
  }
  png_set_sig_bytes(png_ptr, SIG_SIZE);
  png_read_info(png_ptr, info_ptr);
  png_get_IHDR(png_ptr, info_ptr, &width, &height,
    &bit_depth, &color_type, NULL, NULL, NULL);
  png_set_strip_16(png_ptr);
  if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
    png_set_palette_to_rgb(png_ptr);
  if (color_type == PNG_COLOR_TYPE_GRAY ||
    color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    png_set_gray_to_rgb(png_ptr);
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(png_ptr);
  png_read_update_info(png_ptr, info_ptr);
  png_get_IHDR(png_ptr, info_ptr, &width, &height,
    &bit_depth, &color_type, NULL, NULL, NULL);
  row_bytes = png_get_rowbytes(png_ptr, info_ptr);
  data = (png_bytep)malloc(row_bytes * (int)height);
  if (!data)
  {
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    fclose(file);
    return NULL;
  }
  row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
  for (row = 0; row < (int)height; row++)
  {
    row_pointers[row] = data + row * row_bytes;
  }
  png_read_image(png_ptr, row_pointers);
  free(row_pointers);
  bpp = bit_depth * info_ptr->channels;
  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  fclose(file);
  image = (struct tagPNGImage*)malloc(sizeof(struct tagPNGImage));
  if (image)
  {
    image->data   = data;
    image->width  = (int)width;
    image->height = (int)height;
    image->pitch  = (int)row_bytes;
    image->bpp    = bpp;
  }
  return image;
}

Создание OpenGL текстуры из загруженного изображения:

GLuint create_texture(struct tagImage *image)
{
  GLuint texture;
  int format, channels;
  if (image->bpp == 24)
  {
    channels = 3;
    format = GL_RGB;
  }
  else if (image->bpp == 32)
  {
    channels = 4;
    format = GL_RGBA;
  }
  else
  {
    return 0;
  }
  glGenTextures(1, &texture);
  glBindTexture(GL_TEXTURE_2D, texture);
  glTexParameteri(GL_TEXTURE_2D,
    GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D,
    GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glTexImage2D(GL_TEXTURE_2D, 0, channels,
    png_image->width, png_image->height,
    0, format, GL_UNSIGNED_BYTE, png_image->data);
  /* gluBuild2DMipmaps(GL_TEXTURE_2D, channels,
    png_image->width, png_image->height,
    format, GL_UNSIGNED_BYTE, png_image->data); */
  return texture;
}

Страницы: 1 2 3
ПрограммированиеФорумОбщее

Тема в архиве.