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

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

Страницы: 1 2 3 Следующая »
#0
7:48, 13 июля 2004

Комментарий к Статье Работа с файлами форматов ZIP, JPEG и PNG.
В этой статье автор делится знаниями по работе с файлами таких форматов, как JPEG и PNG, отвечающими за хранение изображений, а также формата ZIP, для чтения архивированных данных. Описание используемых библиотек демонстрируется исходным кодом.


#1
7:48, 13 июля 2004

А зипы можно использовать бесплатно? LZW вроде бы запатентован?

#2
8:03, 13 июля 2004

В зипах не используется LZW.
А zlib и pnglib старательно разрабатывались таким образом, чтобы не наступить ни на чьи грабли.

#3
9:30, 13 июля 2004

Мне понравилось. Правда я все это уже давно написал и теперь только копи пасте :-)
Да и еще с джпегом помоему перемудрено. У меня вот так все работает

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

#4
9:52, 13 июля 2004

viv

Сразу бросилось в глаза:

> byte** RowPointer = new byte*[Height];

> delete RowPointer;

#5
10:31, 13 июля 2004

к разговору о LZW и граблях, в zip'е LZW я так думаю никогда и не использовался, скорее слегка модифицированные LZ77 или LZ78...

#6
10:38, 13 июля 2004

enki
Все библиотеки указанные в статье можно использовать бесплатно. Единственное что просят, так это указать в хэлпе, что были использованы такие-то библиотечки.

#7
10:46, 13 июля 2004

_grisha
Это мой любимый баг - delete[]
Говорил же вулфхунд "смарт поинтер + стл = наш выбор" :-)

#8
12:14, 30 июля 2004

Тонкий намек - &gamma - служебный символ в HTML (см. строчки работы с гаммой).
viv, а почему у тебя не делается флиппинг?

Баг с delete[] и вообще подобные баги часто решаются даже не shared_ptr и shared_array, а scoped_ptr и scoped_array.

edit: тонкий намек[2]: s/&/&amp;/g;

#9
14:19, 30 июля 2004

Zeux
подобные баги решаються коллекционером мусора и мусоров :-)

#10
14:25, 30 июля 2004

viv
Коллекционер мусора - маст дай. Это плохой солюшен к проблеме. Нужно делать так, чтобы мусора не было, а не так, чтобы он был, но его иногда за тобой вычищали.

#11
14:56, 30 июля 2004

Zeux
Конечно я не против того что код надо без утечек писать. Просто счасшарпом занимаюсь, вот и про БОМЖа и вспомнил.

#12
18:43, 18 сен. 2004

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 не для новичков

#13
23:52, 18 сен. 2004

Касимов Антон
>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).

#14
20:23, 19 сен. 2004

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-библиотеку будет сказано ниже.

Ниже ничего не сказано! Ошибка?

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

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