Комментарий к Статье Работа с файлами форматов ZIP, JPEG и PNG.
В этой статье автор делится знаниями по работе с файлами таких форматов, как JPEG и PNG, отвечающими за хранение изображений, а также формата ZIP, для чтения архивированных данных. Описание используемых библиотек демонстрируется исходным кодом.
А зипы можно использовать бесплатно? LZW вроде бы запатентован?
В зипах не используется LZW.
А zlib и pnglib старательно разрабатывались таким образом, чтобы не наступить ни на чьи грабли.
Мне понравилось. Правда я все это уже давно написал и теперь только копи пасте :-)
Да и еще с джпегом помоему перемудрено. У меня вот так все работает
static void jpg_noop(j_decompress_ptr cinfo) { } static boolean jpg_fill_input_buffer( j_decompress_ptr cinfo) { return 1; } static void jpg_skip_input_data( j_decompress_ptr cinfo, long num_bytes) { cinfo->src->next_input_byte += ( size_t) num_bytes; cinfo->src->bytes_in_buffer -= ( size_t) num_bytes; } static void jpeg_mem_src( j_decompress_ptr cinfo, byte *mem, int len) { cinfo->src = ( struct jpeg_source_mgr *) ( *cinfo->mem->alloc_small)( ( j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof( struct jpeg_source_mgr)); cinfo->src->init_source = jpg_noop; cinfo->src->fill_input_buffer = jpg_fill_input_buffer; cinfo->src->skip_input_data = jpg_skip_input_data; cinfo->src->resync_to_restart = jpeg_resync_to_restart; cinfo->src->term_source = jpg_noop; cinfo->src->bytes_in_buffer = len; cinfo->src->next_input_byte = mem; } bool Image::LoadJPG( const std::string &Filename) { Core::FileHandlePtr FH = Core::FileManager::Instance( ).Open( Filename); if ( !FH->Valid( )) return false; std::vector<byte> Buffer; Buffer.resize( FH->GetSize( )); FH->Read( &Buffer[0], Buffer.size( )); jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; cinfo.err = jpeg_std_error( &jerr); jpeg_create_decompress( &cinfo); jpeg_mem_src( &cinfo, &Buffer[0], int( Buffer.size( ))); jpeg_read_header( &cinfo, TRUE); jpeg_start_decompress( &cinfo); switch ( cinfo.num_components) { case 1: PixelFormat = Render::PIXEL_FORMAT_L8; break; case 3: PixelFormat = Render::PIXEL_FORMAT_RGB8; break; case 4: PixelFormat = Render::PIXEL_FORMAT_RGBA8; break; } Width = cinfo.output_width; Height = cinfo.output_height; Update( ); byte** RowPointer = new byte*[Height]; for ( int i = 0; i < Height; i++) RowPointer[Height - i - 1] = &Pixels[i * LineSize]; int RowsRead = 0; while ( cinfo.output_scanline < cinfo.output_height) { RowsRead += jpeg_read_scanlines( &cinfo, &RowPointer[RowsRead], cinfo.output_height - RowsRead); } delete RowPointer; jpeg_finish_decompress( &cinfo); jpeg_destroy_decompress( &cinfo); Buffer.clear( ); return true; }
viv
Сразу бросилось в глаза:
> byte** RowPointer = new byte*[Height];
> delete RowPointer;
к разговору о LZW и граблях, в zip'е LZW я так думаю никогда и не использовался, скорее слегка модифицированные LZ77 или LZ78...
enki
Все библиотеки указанные в статье можно использовать бесплатно. Единственное что просят, так это указать в хэлпе, что были использованы такие-то библиотечки.
_grisha
Это мой любимый баг - delete[]
Говорил же вулфхунд "смарт поинтер + стл = наш выбор" :-)
Тонкий намек - &gamma - служебный символ в HTML (см. строчки работы с гаммой).
viv, а почему у тебя не делается флиппинг?
Баг с delete[] и вообще подобные баги часто решаются даже не shared_ptr и shared_array, а scoped_ptr и scoped_array.
edit: тонкий намек[2]: s/&/&/g;
Zeux
подобные баги решаються коллекционером мусора и мусоров :-)
viv
Коллекционер мусора - маст дай. Это плохой солюшен к проблеме. Нужно делать так, чтобы мусора не было, а не так, чтобы он был, но его иногда за тобой вычищали.
Zeux
Конечно я не против того что код надо без утечек писать. Просто счасшарпом занимаюсь, вот и про БОМЖа и вспомнил.
1. Ошибка в чтении png сигнатуры
Тестируется сигнатура при помощи функции png_check_sig(), на вход которой поступает массив из считанных байт и его длина. На выходе в случае несовпадения сигнатур, будет 0, в противном случае можно считать, что файл правильный.
// проверяем сигнатуру файла (первые number байт) png_byte sig[number] = {0}; file.Read(sig, sizeof( png_byte), number); if ( !png_check_sig( sig, number) ) { file.Close( ); return( cDataManager::cError::UnknownFormat ); } // проверка прошла успешно - это png-файл
Должно быть:
На выходе в случае совпадения сигнатур, будет 0, в противном случае можно считать, что файл неправильный.
// проверяем сигнатуру файла (первые number байт) png_byte sig[number] = {0}; file.Read(sig, sizeof( png_byte), number); if ( png_check_sig( sig, number) ) { file.Close( ); return( cDataManager::cError::UnknownFormat ); } // проверка прошла успешно - это png-файл
Цитата из libpng manual
Libpng provides a simple check to see if a file is a PNG file. To use it, pass in the first 1 to 8 bytes of the file to the function png_sig_cmp(), and it will return 0 if the bytes match the corresponding bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes you pass in, the greater the accuracy of the prediction.
2. Вместо libjpeg я бы использовал Small JPEG Decoder Library.
IMHO libjpeg не для новичков
Касимов Антон
>Libpng provides a simple check to see if a file is a PNG file. To use it, pass in the first 1 to 8 bytes of the file to the function png_sig_cmp(), and it will return 0 if the bytes >match the corresponding bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes you pass in, the greater the accuracy of the prediction.
Путаешь png_sig_cmp и png_check_sig. Почитай внимательно эти строки строки мануаля.
И еще, если заглянуть в файл png.h то можно увидеть что
png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
deni
Действительно попутал.
void PNGReadFunction(png_structp png_ptr, png_bytep data, png_size_t length) { cFile* pFile = ( cFile*)png_get_io_ptr( png_ptr); pFile->Read( data, 1, length); }
На вход подается структура, содержащая информацию о библиотеке, массив байт, в который нужно занести прочитанную информацию, и длина этого массива. Первой строкой определяется указатель на поток данных. Как настроить на него PNG-библиотеку будет сказано ниже.
Ниже ничего не сказано! Ошибка?
Тема в архиве.