지난번 글에 getDecodedStream 까지 분석 했습니다.
그 글 올린지 일주일이 지났네요.
회사에서 다른 일을 하느라 이 부분 분석을 못했는데요.
그 일이 어느정도 마무리 됐으니 다시 마저 분석에 들어가야 겠습니다.
지난번 다루다 끝났던 getDecodedStream 함수를 보면요.$key값이 ASCIIHexDecode, ASCII85Decode 그리고 FlateDecode 냐에 따라서 실행하는 함수가 달랐습니다.
제가 테스트 하는 PDF 문서는 FlateDecode 를 사용하더라구요.
그러면
if ($key == "FlateDecode"){
$_stream = decodeFlate($_stream);
echo $_stream . "<p>";
}
가 실행이 될 텐데요.
그 결과값을 미리 브라우저에 찍어 봤습니다.
뭐 이런게 찍히네요.
지금까지 쪼개고 쪼개고 쪼갠 값은 $_stream 의 값을 해당 함수에 넣고 돌려서 얻은 결과가 위 데이터입니다.
사람이 볼 수 있는 데이터가 되려면 아직 멀어보이네요.
그러면 decodeFlate($_stream) 을 살펴 보겠습니다.
function decodeFlate($input) {
return @gzuncompress($input);
}
뭐 이 함수는 아주 간단합니다. 다른 decodeAsciiHex($_stream) 이나 decodeAscii85($_stream) 은 그래도 뭔가 로직이 있는데 이 함수는 달랑 @gzuncompress() 메소드만 사용했네요.
이 메소드를 알아보겠습니다.
이 gzuncompress() 메소드의 PHP 매뉴얼을 보면 This function uncompress a compressed string. 라고 돼 있습니다. 그러니까 이 함수는 압축된 string 을 압축해제 하는 함수라고 합니다.
지금까지 작업한 $_stream 을 압축해제하면 저 위에 있는 화면 같은 데이터가 추출 되는군요.
<?php
$compressed = gzcompress('Compress me', 9);
$uncompressed = gzuncompress($compressed);
echo $uncompressed;
?>
위 코드를 실행 해 보세요. 그러면 Compress me 그대로 출력 될 겁니다. 압축했다가 다시 압축을 풀었으니까요.
그럼 이제 어디로 가야 될까요? 1주일이 지나서 감이 멀어졌는데. 일단 getDecodedStream 함수에서 일을 처리하고 return 하는 부분까지 했으니까 이 함수를 호출했던 pdf2text() 함수로 다시 가야겠죠.
$data = getDecodedStream($stream, $options);
이 부분이었습니다. 저 $data 변수에는 아까 브라우저에 출력했던 그 이상한 데이터가 담겨져 있을 겁니다. $_stream 의 압축을 푼 데이터죠.
그 다음 소스는 아래 내용입니다.
if (strlen($data)) {
if (preg_match_all("#BT(.*)ET#ismU", $data, $textContainers)) {
$textContainers = @$textContainers[1];
getDirtyTexts($texts, $textContainers);
} else
getCharTransformations($transformations, $data);
}
strlen 함수는 C언어에서도 똑같이 쓰는 것 같은데요. 문자열의 길이를 구하는 함수입니다.
그러니까 strlen($data) 는 $data 의 길이를 구하는거고 0 이면 데이터가 없다는 겂니다. 그러면 PHP는 0 을 false 로 취급하니까 이 if 문을 처리하지 않고 건너 뛸 겁니다.
$data 에 값이 있다면 그것이 길던 짧던 상관 안하고 if 문 안의 코드를 실행합니다.
그 다음은 다시 정규식 표현을 사용하는 preg_match_all 함수가 나오네요.
$data를 BT, ET 등으로 구분해서 $textContainers 에 넣는 것 같습니다.
BT, ET 는 아까 뽑았던 이상한 데이터들에 많이 있습니다. 잘은 모르겠지만 그냥 통박을 굴려보면 Begin Text, End Text 의 준말이 아닐까 생각되네요.
그 다음에 @가 나오는데요. 이건 PHP 에서 에러 관련해서 처리하도록 하는 부호입니다.
<?php
/* Intentional file error */
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '$php_errormsg'");
// this works for any expression, not just functions:
$value = @$cache[$key];
// will not issue a notice if the index $key doesn't exist.
?>
위에 관련 예제가 있습니다.
그 다음에는 getDirtyTexts($texts, $textContainers); 가 나옵니다.
새로운 함수 호출인데요. 두번째 인자는 방금 뽑아낸 $textContainers 변수를 전달하고 첫번째 인자는 pdf2text 초반에 만들어 뒀던 배열변수네요.
이 변수에 아직 아무 값도 안 담겼던 것 같은데...
그럼 이 호출된 함수를 볼까요?
function getDirtyTexts(&$texts, $textContainers) {
for ($j = 0; $j < count($textContainers); $j++) {
if (preg_match_all("#\[(.*)\]\s*TJ#ismU", $textContainers[$j], $parts))
$texts = array_merge($texts, @$parts[1]);
elseif(preg_match_all("#Td\s*(\(.*\))\s*Tj#ismU", $textContainers[$j], $parts))
$texts = array_merge($texts, @$parts[1]);
}
}
짧은 함수네요.
$textContainers 의 수만큼 for 문을 돌리는데 다시 preg_match_all 를 사용해서 $textContainers 파편들을 '#\[(.*)\]\s*TJ#ismU' 이 정규식 형식에 맞게 구분을 해서 $parts 에 집어넜습니다.
아까 받았던 $texts 에는 이 값들을 계속 차곡차곡 쌓아놓네요.
array_merge() 함수를 사용해서인데요. 이 함수는 한개 이상의 배열을 합하는 함수입니다.
elseif 문 안에도 똑 같은 일을 하죠. 다만 구분하는 정규표현식이 다를 뿐이죠.
즉 이 함수는 BT, ET 별로 쪼갠 값을 다시 위 정규표현식에 맞게 쪼개서 $texts 에 담는 함수입니다.
그 다음은 다시 pdf2text 함수로 돌아가야 되는데요.
BT,ET 로 나누지 않을 경우는 getCharTransformations 함수를 사용하네요.
이 함수부터는 다음 글에서 다룰께요.
마무리 하면서 getDirtyTexts($texts, $textContainers); 바로 밑에 아래 코드를 추가해 봤습니다.
for ($k = 0; $k < count($texts); $k++) {
echo $texts[$k] . "<br>";
}
바로 지금까지 만든 $texts 내용을 찍어 본 건데요.
아래 내용입니다.
이제 조금 사람이 알아볼 수 있는 글들이 나타나기 시작했습니다.
(W)-36(e)7(e)7(k )46(o)7(f) 에는 Week of 가 있죠?
그 중간에 숫자는 뭔지 잘 모르겠지만요. 빈괄호 ()는 space 일까요?
(Oct)-11(o)5(ber )10(1)4( ) 는 October 1 하고 빈괄호가 있네요.
이제 뭔가 보이기 시작합니다.
그럼 다음 시간에는 이 데이터를 마저 decode 해 보겠습니다.
|
|
'etc. > PHP' 카테고리의 다른 글
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 7 (0) | 2013.01.16 |
---|---|
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 6 (0) | 2013.01.16 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 4 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 3 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 2 (0) | 2013.01.08 |
PDF 내용을 Text 로 추출하는 PHP 프로그램 분석해 보기 1 (0) | 2013.01.05 |
PHP와 XSL 로 XML 변환하기 (0) | 2012.12.21 |
PHP로 XML , JSON 다루기 (2) | 2012.08.24 |
-PHP - Proxy 통해 원격 파일 존재 여부 파악하기 (0) | 2012.07.19 |