2016-07-01 4 views
-5

음에 C++ 코드를 변환 시도 (사용자 정의 LZSS 압축 해제) :, 나는 C++에서이 코드를 변환하기 위해 노력하고있어 자바 스크립트 코드

// Modified LZSS routine 
// - starting position at 0 rather than 0xFEE 
// - optionally, additional byte for repetition count 
// - dictionary writing in two passes 
static bstr custom_lzss_decompress(
const bstr &input, size_t output_size, const size_t dict_capacity) 
{ 
std::vector<u8> dict(dict_capacity); 
size_t dict_size = 0; 
size_t dict_pos = 0; 

bstr output(output_size); 
auto output_ptr = output.get<u8>(); 
auto output_end = output.end<const u8>(); 
auto input_ptr = input.get<const u8>(); 
auto input_end = input.end<const u8>(); 

u16 control = 0; 
while (output_ptr < output_end) 
{ 
    control >>= 1; 
    if (!(control & 0x100)) 
     control = *input_ptr++ | 0xFF00; 

    if (control & 1) 
    { 
     dict[dict_pos++] = *output_ptr++ = *input_ptr++; 
     dict_pos %= dict_capacity; 
     if (dict_size < dict_capacity) 
      dict_size++; 
    } 
    else 
    { 
     auto tmp = *reinterpret_cast<const u16*>(input_ptr); 
     input_ptr += 2; 

     auto look_behind_pos = tmp >> 4; 
     auto repetitions = tmp & 0xF; 
     if (repetitions == 0xF) 
      repetitions += *input_ptr++; 
     repetitions += 3; 

     auto i = repetitions; 
     while (i-- && output_ptr < output_end) 
     { 
      *output_ptr++ = dict[look_behind_pos++]; 
      look_behind_pos %= dict_size; 
     } 

     auto source = &output_ptr[-repetitions]; 
     while (source < output_ptr) 
     { 
      dict[dict_pos++] = *source++; 
      dict_pos %= dict_capacity; 
      if (dict_size < dict_capacity) 
       dict_size++; 
     } 
    } 
} 

return output; 
} 
자바 스크립트 버전으로

, 나는이에 실제로 해요 :

function custom_lzss_decompress(input,osize,dictcap){ 
var dict = new Uint8Array(dictcap); 
var output = new Uint8Array(osize); 
var data = str2ab(input); 
var dict_size = 0; 
var dict_pos = 0; 
var control = 0; 
var iptr = 0; 
var optr = 0; 

while (iptr < osize){ 
    control >>= 1; 
    if(!(control & 0x100)){ 
     control = data[iptr] | 0xFF00; 
     iptr++; 
    } 
    if(control & 1){ 
     dict[dict_pos] = output[optr] = data[iptr]; 
     dict_pos++; 
     iptr++; 
     optr++; 
     dict_pos %= dictcap; 

     if(dict_size < dictcap) 
      dict_size++; 
    } 
    else{ 
     var tmp = new Uint16Array(1); 
     tmp[0] = (data[iptr] << 8) + data[iptr+1]; 
     iptr += 2; 
     var loop_behind_pos = new Uint16Array(1); 
     loop_behind_pos[0] = tmp >> 4; 
     var repetitions = new Uint16Array(1); 
     repetitions[0] = tmp & 0xF; 
     if(repetitions[0] == 0xF){ 
      repetitions[0] += data[iptr]; 
     } 
     iptr++; 
     repetitions[0] += 3; 
     var ai = new Uint16Array(1); 
     ai[0] = repetitions[0]; 

     while(ai[0] && (optr < osize)){ 
      ai[0]--; 
      output[optr] = dict[loop_behind_pos]; 
      optr++; 
      loop_behind_pos++; 
      loop_behind_pos %= dict_size; 
     } 
     var source = new Uint16Array(1); 
     source[0] = output[-repetitions[0]]; 
     while(source[0] < optr){ 
      dict[dict_pos] = output[source]; 
      dict_pos++; 
      source++; 
      dict_pos %= dictcap; 
      if(dict_size < dictcap) 
       dict_size++; 
     } 

    } 
} 
return output; 
} 

그것은 실행 ...하지만 일을하지 ... 그리고 내가 무슨 일이 일어나고 있는지 알아낼 수 없습니다 ... 누군가가 내가 보이지 않아요 기괴한 오류를 볼 수 있습니까?

+0

검사 할 때 console.log()는 무엇을 출력합니까? –

답변

0

하나의 문제점과 잠재적 인 문제점이 있습니다. 문제는 'repetitions [0] == 0xF handler. You're incrementing iptr`이지만 항상 원래 코드는 if 본문에만 있습니다.

잠재적 인 문제는 16 비트 워드 인 tmp[0] = (data[iptr] << 8) + data[iptr+1];입니다. 단어가 빅 엔디안 인 경우 작동하지만 소스가 리틀 엔디안 인 경우 올바른 값을 제공하지 않습니다.

관련 문제