libpng falls down at loading of png file from memory
От: Sitan  
Дата: 24.05.04 12:37
Оценка:
Я использую libpng, чтобы загружать png — файл. Мне необходимо использовать
пользовательскую функцию чтения (кот. задается png_set_read_fn), либо прогрессивный метод считывания для того, чтобы распаковвывать уже загруженный в память файл.
Распаковка осуществляется в отдельный буфер (ястессно). Картинка 8 бит. 64х64.

Проблема в том, что при использовании png_set_read_fn, функция чтения устанавливается нормально. Но вот следующий вызов, наподобие png_read_png, или хотя бы png_get_IHDR сразу же проваливается (то есть либа падает и за ней падает все остальное)... почему?, не известно.

Вроде бы во время распаковки, либа встречает неизвесные ей чанки, надо ли с ними
что -нибудь явно делать?

При использовании progressive reading (с call back-ами), все работает, но... готовая
картинка получается какого-то не того цвета (сине-феолетовая), и сама картинка ничуть
не соответствует тому, что лежало в файлике. Палитра устанавливается нормально. Вроде бы все как в сэмпле, но нифига не работет как должно...

Спасибо.
... << RSDN@Home 1.1.3 stable >>

24.05.04 19:17: Перенесено модератором из 'C/C++' — Павел Кузнецов
Re: libpng falls down at loading of png file from memory
От: Alexey Chen Чили  
Дата: 24.05.04 12:53
Оценка:
Здравствуйте, Sitan, Вы писали:

S>Проблема в том, что при использовании png_set_read_fn, функция чтения устанавливается нормально. Но вот следующий вызов, наподобие png_read_png,


Ошибешся где-то.
Ты обработчик ошибок выставляешь?

Я делаю так

static void mskinpng_read_fn(png_structp png_ptr, png_bytep dest, png_size_t sz)
{
  ((PNGImageDataSource*)png_ptr->io_ptr)->Read(dest,sz);
}


и в классе

  unsigned char signature[8];
  fail_if ( this->Read(signature,8) != 8 );
  if ( !png_check_sig(signature,8) ) fail_because(FormatS(":PNGImageDataSource: %s is no PNG image",this->GetName()).c_str());
  fail_if ( !(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0)));
  fail_if ( !(info_ptr=png_create_info_struct(png_ptr)) );
  if(setjmp(png_jmpbuf(png_ptr))) {
    LogF(":PNGImageDataSource: error in ReadHeader");
    return ME_FAIL;
  }
  png_set_read_fn(png_ptr,this,mskinpng_read_fn);
  png_set_sig_bytes(png_ptr,8);
  png_read_info(png_ptr,info_ptr);
  png_set_strip_16(png_ptr);
  png_set_packing(png_ptr);
  if ( png_ptr->bit_depth < 8 
    || png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
    || png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS) )
    png_set_expand(png_ptr);
  png_read_update_info(png_ptr,info_ptr);
  long bytes_weight = (png_ptr->color_type &PNG_COLOR_MASK_ALPHA) ? 4 : 3;
  img_width_  = png_get_image_width(png_ptr,info_ptr);
  img_height_ = png_get_image_height(png_ptr,info_ptr);
  stride_     = (bytes_weight*img_width_ + 7 ) & ~3UL;
  updown_     = true;
  bpp_        = bytes_weight*8;


и дальше читаю строчки через png_read_row
Re: libpng falls down at loading of png file from memory
От: degor Россия  
Дата: 24.05.04 13:00
Оценка:
Здравствуйте, Sitan, Вы писали:

S>Проблема в том, что при использовании png_set_read_fn, функция чтения устанавливается нормально. Но вот следующий вызов, наподобие png_read_png, или хотя бы png_get_IHDR сразу же проваливается (то есть либа падает и за ней падает все остальное)... почему?, не известно.

Никогда не испытывал таких проблем. Посмотри, что ты отдаешь libpng из функции чтения.

S>Вроде бы во время распаковки, либа встречает неизвесные ей чанки, надо ли с ними

S>что -нибудь явно делать?
С чанками вообще ничего делать не надо, если тебе неинтересно их содержимое.

S>При использовании progressive reading (с call back-ами), все работает, но... готовая

S>картинка получается какого-то не того цвета (сине-феолетовая), и сама картинка ничуть
S>не соответствует тому, что лежало в файлике. Палитра устанавливается нормально. Вроде бы все как в сэмпле, но нифига не работет как должно...
Хорошо бы все-таки сверить свои понятия о содержимом файла, с тем, что об этом думает libpng. Возможно, надо задать параметры для конвертирования картинки.

Я действую по такой схеме:
        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if (!png_ptr)
            my_png_error(png_ptr, "Can't create PNG structure");
        // must set error handler after png_create_read_struct, because it uses setjmp
        png_set_error_fn(png_ptr, NULL, my_png_error, NULL);
        info_ptr = png_create_info_struct(png_ptr);

        // Initialize png_io and set my own read function
        // the second param will be returned by png_get_io_ptr() in read_data_fn()
        png_set_read_fn(png_ptr, pMemFile,    read_data_fn);

        // read header
        png_read_info(png_ptr, info_ptr);

        // set conversion parameters
        ...

        png_read_update_info(png_ptr, info_ptr);

        unsigned nLineSize = png_get_rowbytes(png_ptr, info_ptr);
        nLineSize = (nLineSize + 3)&~3;
        imgbuf = NEW(unsigned char, nLineSize * info_ptr->height);
        {
            unsigned char *ptr = imgbuf;
            unsigned char **row_pointers = NEW(png_bytep, info_ptr->height);
            for( int i=info_ptr->height ; --i >= 0; ptr += nLineSize )
                row_pointers[i] = ptr;
            png_read_image(png_ptr, row_pointers);
            DEL(row_pointers);
        }
        
        ...
        
        png_read_end(png_ptr, info_ptr);
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
... << RSDN@Home 1.1.3 stable >>
Re[2]: libpng falls down at loading of png file from memory
От: Sitan  
Дата: 24.05.04 13:39
Оценка:
Здравствуйте, degor, Вы писали:

D>Здравствуйте, Sitan, Вы писали:


S>>Проблема в том, что при использовании png_set_read_fn, функция чтения устанавливается нормально. Но вот следующий вызов, наподобие png_read_png, или хотя бы png_get_IHDR сразу же проваливается (то есть либа падает и за ней падает все остальное)... почему?, не известно.

D>Никогда не испытывал таких проблем. Посмотри, что ты отдаешь libpng из функции чтения.

Отдаю все верно... код типа такого...

void readpng1_read_user(png_structp png_ptr, png_bytep in_ptr, png_size_t in_size)
{
CDXImagePNG *mainprog_ptr;

mainprog_ptr = (CDXImagePNG *)png_get_io_ptr(png_ptr);
if (!mainprog_ptr) { assert(mainprog_ptr != NULL); return; }
memcpy(in_ptr, (unsigned char *)mainprog_ptr->GetStoragePtr() + png_ptr->sig_bytes, in_size );

return;
}

Вообщем-то, я смотрел default-овый ридер функцию... вроде бы все то же самое.
GetStoragePtr возв. указатель на память, где лежит загруженный образ файлика.

S>>Вроде бы во время распаковки, либа встречает неизвесные ей чанки, надо ли с ними

S>>что -нибудь явно делать?
D>С чанками вообще ничего делать не надо, если тебе неинтересно их содержимое.
Угу...

S>>При использовании progressive reading (с call back-ами), все работает, но... готовая

S>>картинка получается какого-то не того цвета (сине-феолетовая), и сама картинка ничуть
S>>не соответствует тому, что лежало в файлике. Палитра устанавливается нормально. Вроде бы все как в сэмпле, но нифига не работет как должно...
D>Хорошо бы все-таки сверить свои понятия о содержимом файла, с тем, что об этом думает libpng. Возможно, надо задать параметры для конвертирования картинки.
Странно... у меня такая же мысль была... но ведь во всех других загрузчиках (PSD, BMP, PCX), функции и методы используемые при загрузке никаких сбоев не доют. Код я смотрел... там вроде никаких ошибок нет... хотя при считывании с моей функцией рид, первое, что считывается в хидере (после сигн.)... размеры чанков... и он у меня равен нулю. (Так должно быть, или это такая хитрость?).

D>Я действую по такой схеме:

Я, вроде бы, действую по такой же схеме:

png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
(CDXImagePNG *)this, readpng2_error_handler, NULL);
if (png_ptr == NULL)
return (ERROR);
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return (ERROR);
}
if (setjmp(jmpbuf))
{
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
return (ERROR);
}
png_set_read_fn(png_ptr, (CDXImagePNG *)this, readpng1_read_user);
png_set_sig_bytes(png_ptr, 0);

png_read_info(png_ptr, info_ptr); //<---- here we a Great Bug
... << RSDN@Home 1.1.3 stable >>
Re[2]: libpng falls down at loading of png file from memory
От: Sitan  
Дата: 24.05.04 13:39
Оценка:
Здравствуйте, Alexey Chen, Вы писали:

AC>Здравствуйте, Sitan, Вы писали:


S>>Проблема в том, что при использовании png_set_read_fn, функция чтения устанавливается нормально. Но вот следующий вызов, наподобие png_read_png,


AC>Ошибешся где-то.

AC>Ты обработчик ошибок выставляешь?
Да.
Вот как я делать пытаюсь?

png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
(CDXImagePNG *)this, readpng2_error_handler, NULL);
if (png_ptr == NULL)
return (ERROR);
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{ png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return (ERROR);
}
if (setjmp(jmpbuf))
{
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
return (ERROR);
}
png_set_read_fn(png_ptr, (CDXImagePNG *)this, readpng1_read_user);
png_set_sig_bytes(png_ptr, 0);

png_read_info(png_ptr, info_ptr); //<---- here we have a Great Bug
... << RSDN@Home 1.1.3 stable >>
Re[3]: libpng falls down at loading of png file from memory
От: Alexey Chen Чили  
Дата: 24.05.04 14:41
Оценка:
Здравствуйте, Sitan, Вы писали:

S>Вот как я делать пытаюсь?


// вот здесь попробуй заменить 0 на 8
S>png_set_sig_bytes(png_ptr, 0);
Re[4]: libpng falls down at loading of png file from memory
От: Sitan  
Дата: 24.05.04 15:05
Оценка:
Здравствуйте, Alexey Chen, Вы писали:

AC>// вот здесь попробуй заменить 0 на 8

S>>png_set_sig_bytes(png_ptr, 0);

Попробовал ... но не помогло.
(Если я не ошибаюсь, эта функция выставляет смещение на уже прочитанное
количество байт от начала файла... в том примере мы еще ничего непрочитали
и поэтому, теоретически, никакого смещения ставить не должны.)

После того, как либа читает два DWORD (по 4 байта) она выпадает в еррор
установленный setjmp-ом.
... << RSDN@Home 1.1.3 stable >>
Re[5]: libpng falls down at loading of png file from memory
От: Alexey Chen Чили  
Дата: 24.05.04 15:43
Оценка:
Здравствуйте, Sitan, Вы писали:

AC>>// вот здесь попробуй заменить 0 на 8

S>>>png_set_sig_bytes(png_ptr, 0);

S>Попробовал ... но не помогло.

S>После того, как либа читает два DWORD (по 4 байта) она выпадает в еррор
S>установленный setjmp-ом.

Тогда у меня два предположения.

1)
png_create_read_struct с указанием ненулевых аргументов имеет свои особенности.

2)
ты ошибся в функции читающей данные.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.