Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Вниз

Проблема с ZLib   Найти похожие ветки 

 
Samael6 ©   (2004-04-07 17:49) [0]

Добрый день/вечер/утро!
Товарищи, если кто работал с ZLib, подскажите, плиз. Я пытаюсь распаковать блок данных содержащийся в PDF-файле и закодированный методом Flate. Все проходит чики-пуки, вот только выходной блок данных получается урезанным в конце. В чем может быть трабла? Может дело не в zlib, а в самом PDF, возможно ли такое и если нет, тогда что?

Заранее благодарен!


 
Samael6 ©   (2004-04-08 17:54) [1]

Интересно....неужели с ЗЛибом никто не работал?
Печально....


 
mrcat ©   (2004-04-08 17:56) [2]

с самим zlib"ом всё в порядке ... ищи проблему у себя ...


 
Samael6 ©   (2004-04-08 17:59) [3]

Вот процедура, которая реализует поставленную задачу. Что с ней не так?

procedure d_(const fn1,fn2:string);
var fs1, fs2:tfilestream;
  ds: tdecompressionstream;
  buf:array [1..1024] of char;
  i: integer;
begin
fs1 := tfilestream.create(fn1,fmopenread);
fs2 := tfilestream.create(fn2,fmcreate);
try
  try
    ds := TDecompressionStream.Create(fs1);
    ds.Position := 0;
    repeat
      i := ds.Read(buf,sizeof(buf));
      if i <> 0 then
        fs2.write(buf,i);
    until(i <> sizeof(buf));
  finally
    ds.free;
  end;
finally
  fs1.free;
  fs2.free;
end;
end;


 
VMcL ©   (2004-04-08 18:22) [4]

>>Samael6 c  (08.04.04 17:59) [3]

У меня со zlib"ом была когда-то аналогичная проблема. Так и не разобрался, в чем дело: то ли у меня кривые руки, то ли нет, но решил с помощью увеличения размера буфера (у тебя `buf`).

P.S. OFF: Как думаешь, что будет, если случится exception на строке:
fs2 := tfilestream.create(fn2,fmcreate);
?


 
WebErr ©   (2004-04-08 18:27) [5]

Удалено модератором


 
Samael6 ©   (2004-04-08 18:45) [6]

Не помогло.


 
VMcL ©   (2004-04-08 19:05) [7]

>>WebErr ©  (08.04.04 18:27) [5]

Никаких вопросов про запуздыривание иконок!

>>Samael6 ©  (08.04.04 18:45) [6]

Сколько поставил? Я ставил 1 МБ :)


 
Reindeer Moss Eater ©   (2004-04-08 19:10) [8]

Все очень просто.
При чтении из DecompressionStream надо указывать длину исходного несжатого файла, а не длину упакованного файла на который натравлен DecompressionStream.
Длину эту надо хранить где-то сбоку.


 
VMcL ©   (2004-04-08 19:44) [9]

>>Reindeer Moss Eater ©  (08.04.04 19:10) [8]

>Длину эту надо хранить где-то сбоку.
Во многих случаях это невозможно, например, если формат не свой.


 
Mim1   (2004-04-08 21:09) [10]

Reindeer Moss Eater ©   (08.04.04 19:10) [8]

Откуда вы это взяли?


 
Mim1   (2004-04-08 21:18) [11]

Samael6 ©   (08.04.04 17:59) [3]


procedure d_(const fn1,fn2:string);
var fs1, fs2:tfilestream;
 ds: tdecompressionstream;
 buf:array [1..1024] of byte;
 i: integer;
begin
 fs1 := tfilestream.create(fn1,fmopenread);
 try
   fs2 := tfilestream.create(fn2,fmcreate);
   try
     ds := TDecompressionStream.Create(fs1);
     try
       ds.Position := 0;
       repeat
         i := ds.Read(buf,sizeof(buf));
         if i <> 0 then
           fs2.write(buf,i);
       until(i <> sizeof(buf));
     finally
       ds.free;
     end;
   finally
     fs2.free;
   end;
 finally
   fs1.free;
 end;
end;


Тем не менее демается что ошибка в исходном файле а не в процедуре.


 
VMcL ©   (2004-04-09 13:46) [12]

>>Reindeer Moss Eater ©  (08.04.04 19:10) [8]

И вот еще: а если исходный файл стонадцать миллионов гигабайт весит, то где ж столько (виртуальной) памяти взять?


 
Reindeer Moss Eater ©   (2004-04-09 14:10) [13]

VMcL ©
Не распределяй память вообще. Создай поток для файла-результата и читай из потока DecompressionStream.

Mim1   (08.04.04 21:09) [10]
Reindeer Moss Eater ©   (08.04.04 19:10) [8]

Откуда вы это взяли?


Мама в детстве рассказывала на ночь.

VMcL ©   (08.04.04 19:44) [9]
>>Reindeer Moss Eater ©  (08.04.04 19:10) [8]

>Длину эту надо хранить где-то сбоку.
Во многих случаях это невозможно, например, если формат не свой.


Если формат не свой, то это не значит, что он не предусматривает некий заголовок архива, содержащий имена запакованных файлов, их длины и смещения относительно начала архива. Его (этот заголовок) и надо читать/писать при распаковке/создании архива не своего формата.

Возвращаясь к проблеме автора повторю:
По запакованному ZLib"ом потоку невозможно определить длину исходных данных.
А для правильного восстановления запакованного надо читать из DecompressionStream ровно столько, сколько туда было записано.
И естественно нельзя указать 0 в качестве длины (типа читать все до конца)


 
VMcL ©   (2004-04-09 14:26) [14]

>>Reindeer Moss Eater ©  (09.04.04 14:10) [13]

> Если формат не свой, то это не значит,
> что он не предусматривает некий заголовок архива

Вот Фома неверующий. Привести пример данных, формат которых не предусматривает заголовков, и тем не менее широко используется? И кто вообще говорил об архивах? Zlib не только в ZIP архивах используется.


 
Reindeer Moss Eater ©   (2004-04-09 14:29) [15]

Если какой-то формат не использует заголовков, то это означает, что ZLIB там не участвует.


 
Polevi ©   (2004-04-09 14:48) [16]

я использовал пару ф-ий CompressBuf и DecompressBuf
DecompressBuf сам выделяет память и сообщает о размере распакованных данных


 
Reindeer Moss Eater ©   (2004-04-09 14:50) [17]

Как DecompressBuf узнавал о размере незапакованных данных?


 
VMcL ©   (2004-04-09 14:51) [18]

>>Reindeer Moss Eater ©  (09.04.04 14:29) [15]

На что спорим? :))


 
Reindeer Moss Eater ©   (2004-04-09 14:53) [19]

VMcL ©  

Сначала может о предмете спора мне расскажешь?
А то я в полном неведении


 
Polevi ©   (2004-04-09 14:55) [20]

procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);


 
Polevi ©   (2004-04-09 14:57) [21]

PS
DecompressBuf это ф-ия из zlib, а не мной написанная


 
Reindeer Moss Eater ©   (2004-04-09 14:57) [22]

Polevi ©

То есть читать осторожно побайтно и до наступления исключения?
Тоже метод.


 
VMcL ©   (2004-04-09 14:59) [23]

>Reindeer Moss Eater ©  (09.04.04 14:53) [19]

>>VMcL ©  (09.04.04 14:26) [14]
>Привести пример данных, формат которых не предусматривает заголовков, и тем не менее широко используется?

>>Reindeer Moss Eater ©  (09.04.04 14:29) [15]
>Если какой-то формат не использует заголовков, то это означает, что ZLIB там не участвует.

На что спорим :), что есть формат, который не использует заголовков, но тем не менее упаковывается/распаковывается с помощью zlib?


 
Reindeer Moss Eater ©   (2004-04-09 15:03) [24]

VMcL ©

Спорить я не стану. Хотя бы по той причине, что возможно мы по разному понимаем что такое заголовок архива.

Алиса запаковала два файла ZLib"ом не исползуюя заголовок и отправила архив Бобу.
Как Боб восстанавливает имена файлов?
Ну хотя бы в общх чертах.


 
Polevi ©   (2004-04-09 15:04) [25]

>Reindeer Moss Eater ©   (09.04.04 14:57) [22]

procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
{$ENDIF}
var
 strm: TZStreamRec;
 P: Pointer;
 BufInc: Integer;
begin
 FillChar(strm, sizeof(strm), 0);
 strm.zalloc := zlibAllocMem;
 strm.zfree := zlibFreeMem;
 BufInc := (InBytes + 255) and not 255;
 if OutEstimate = 0 then
   OutBytes := BufInc
 else
   OutBytes := OutEstimate;
 GetMem(OutBuf, OutBytes);
 try
   strm.next_in := InBuf;
   strm.avail_in := InBytes;
   strm.next_out := OutBuf;
   strm.avail_out := OutBytes;
   DCheck(inflateInit_(@strm, zlib_version, sizeof(strm)));
   try
     while inflate(strm, Z_FINISH) <> Z_STREAM_END do
     begin
       P := OutBuf;
       Inc(OutBytes, BufInc);
       ReallocMem(OutBuf, OutBytes);
       strm.next_out := pBytef(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
       strm.avail_out := BufInc;
     end;
   finally
     DCheck(inflateEnd(strm));
   end;
   ReallocMem(OutBuf, strm.total_out);
   OutBytes := strm.total_out;
 except
   {$IFDEF Delphi16} {next line changed} {$ENDIF}
   zlibFreeMem(NIL, OutBuf);
   raise
 end;
end;


 
Reindeer Moss Eater ©   (2004-04-09 15:09) [26]

Polevi ©
Все понятно. Сама библиотека не знает какого размера были исходные данные.


 
VMcL ©   (2004-04-09 15:17) [27]

>>Reindeer Moss Eater ©  (09.04.04 15:03) [24]

Повторю пост [14]:
И кто вообще говорил об архивах?

Ладно. Приведу все-таки пример. Программные модули для 1С 7.7 пакуются zlib"ом без заголовков. Далее запихиваются в стримы IStorage. Ну а данные IStorage сохраняются в файл конфигурации (*.md) или внешний отчет (*.ert).


 
Reindeer Moss Eater ©   (2004-04-09 15:19) [28]

И что это доказывает?
То что единственный блок информации запакован и помещен в объект - контейнер, который и выполняет роль заголовка, хранящего имена длины и еще бог знает что.

То что он не внутри упакованного стрима, а снаружи ничего не меняет.


 
VMcL ©   (2004-04-09 15:35) [29]

>>Reindeer Moss Eater ©  (09.04.04 15:19) [28]

AFAIK, нет в этих контейнерах (*.md, *.ert) данных о длине исходных потоков.


 
Reindeer Moss Eater ©   (2004-04-09 15:39) [30]

Формат *.md и *.ert документирован 1с или это догадка?
Если и нет там длин, значит они распаковываются по методу "читать по байту пока не исключение".

Классический компромис между экономией места и производительностью.


 
VMcL ©   (2004-04-09 15:48) [31]

>>Reindeer Moss Eater ©  (09.04.04 15:39) [30]
>Формат *.md и *.ert документирован 1с или это догадка?

Ага, дождешься от них документированности :(
Но это не догадка. Берем .md и/или .ert файл, натравливаем на него фаровский плагин DocFile и изучаем.


 
Reindeer Moss Eater ©   (2004-04-09 15:50) [32]

Ну вот.
Так и знал, что это догадка неутомимого исследователя.


 
Mim1   (2004-04-09 19:18) [33]

Reindeer Moss Eater ©   (09.04.04 14:10) [13]

Очень нехорошо отвечать заведомо неверно, опираясь не на справку или исходники а на рассказы мамы.

Распаковать такой файл можно и не зная размер сжатых данных воспользовавшись алгоритмом [3] или [11], у меня на этом алгаритме работает клиент сервра приложения (причем на двух платформах), естественно ошибок в нем нет.

Если по какой то причине распаковать таким алгоритмом данные не получается то ошибка на 99% в сжатых данных, например формат не верен и тп.


 
Samael6 ©   (2004-04-12 15:39) [34]

Да-а-а-а-а
Ребят, огромное спасибо за столь продолжительное обсуждение. Но я так и не увидел какого-то радикального решения поставленной задачи. Я туплю?


 
Reindeer Moss Eater ©   (2004-04-12 15:48) [35]

Mim1
Очень нехорошо отвечать заведомо неверно, опираясь не на справку или исходники а на рассказы мамы.

Перечитай ответы и найди у меня заведомо неверные посылы.
Найдешь - покажи.


 
Samael6 ©   (2004-04-12 15:53) [36]

Так что посоветуете? Вы говорили, что проблема возможно в самом файле. А как это можно проверить? Точнее как правильно вырезать из PDF этот блок и в чем там может быть проблема? Я обратил внимание, что описание блоков Flate там бывает различно, говорит ли это о том что и реализация упаковки/распаковки тоже может различаться? Если так, то помоему алес!


 
Mim1   (2004-04-12 19:41) [37]

Reindeer Moss Eater ©   (12.04.04 15:48) [35]

Не хочу провращать обсуждение в личныю перепалку, но тем не менее если вы просити дать ответ.

Перечитай ответы и найди у меня заведомо неверные посылы.
Найдешь - покажи.


Вот например.

Все очень просто.
При чтении из DecompressionStream надо указывать длину исходного несжатого файла, а не длину упакованного файла на который натравлен DecompressionStream.
Длину эту надо хранить где-то сбоку.


Дело в том что у меня есть пример из жизни. HTTP cервер сжимает ответ, естественно нигде не говорит "разбем несжатых данных 40 терабайт", и тем не менее я успешно распаковываю ответ методом аналогичным приведенному выше.
К сожалаень DecomperssBuf под каликсом не заработал :(, по этому я отказался от его использования.

Samael6 ©   (12.04.04 15:53) [36]

Ваш вопрос отличается от начального, рекоменжую завести отдельныю новую ветку.


 
Samael6 ©   (2004-04-13 14:28) [38]


> Ваш вопрос отличается от начального, рекоменжую завести
> отдельныю новую ветку.

Да, немного. Но и по первому в принципе мало чего дельного сказали. Первый важнее, второй это просто следствие(возможное) из первого. Так что делать?


 
Samael6 ©   (2004-04-15 13:51) [39]

Ну как есть еще идеи? Может у кого работающий пример работы с ZLib есть?


 
Mim1   (2004-04-15 20:45) [40]

Работающий пример уде раз пять здесь был :)
Тебе нужен пример павильного выковыривания сжатого куска из пдф :).

Извини, но никаким способом из непавильного "архива" правильные данные не получеш.



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.044 c
1-1081969022
VirusIP
2004-04-14 22:57
2004.05.02
Randomize


7-1078580326
KME
2004-03-06 16:38
2004.05.02
Работа с дискетами


1-1082204005
Anatoli
2004-04-17 16:13
2004.05.02
При создании Node в TreeView загонять соответствующие картинки


7-1078487387
Kft
2004-03-05 14:49
2004.05.02
Количество процессоров


1-1081879867
Mishenka
2004-04-13 22:11
2004.05.02
Кавычки в FileNameEdit из RxLib...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский