2009-03-19 18 views
5

Tôi nghĩ rằng tôi có thể làm việc này ra bản thân mình nhưng tôi dường như không được di chuyển về phía trước cả.Làm thế nào để tạo cây Huffman từ tiêu đề FFC4 (DHT) trong tệp jpeg?

Ok, nền:

tôi cần phải tạo ra một cây Huffman mã từ những thông tin được cung cấp bởi các FFC4, DHT (Xác định Huffman Bảng) tiêu đề trong một file jpg. Tiêu đề DHT xác định bảng Huffman theo cách này:

1) Một chuỗi gồm 16 byte. Mỗi byte xác định có bao nhiêu biểu tượng có mã Huffman của số bit n trong đó n là vị trí của byte trong chuỗi. (Đã làm cho bất kỳ ý nghĩa !!?) Ví dụ các dữ liệu thô trong hex là:

00 01 05 01 01 01 ... 00

này có nghĩa là:

Num of bits: 1 2 3 4 5 6 7 ... 16 
Num of codes: 00 01 05 01 01 01 01 ... 00 

2) Sau khi danh sách 16 byte đến các ký hiệu thực tế. Ví dụ:

00 01 02 03 04 05 06 07 08 09 0A 0B

3) Kết hợp hai phần chúng ta thấy rằng họ là:
00 mã với 1 chút.
01 mã với 2 bit: nên lấy biểu tượng đầu tiên trong danh sách: 00
05 mã với 3 bit: nên lấy 5 ký tự kế tiếp từ danh sách: 01 02 03 04 05
.. và vv

4) Cuối cùng, chúng tôi phải tìm ra các mã Huffman thực tế từ thông tin trên. Nếu bạn là một thiên tài toán học, bạn có thể đã phát hiện ra rằng các mã này có thể được làm việc bằng cách đơn giản tăng số nhị phân với số bit thích hợp cho mỗi mã mới ở độ dài bit nhất định. Khi độ dài bit tăng lên, chỉ cần tăng số nhị phân và sau đó tăng gấp đôi nó và tiếp tục. Nó trở nên rõ ràng với mọi người khi bạn đã vẽ ra một số cây nhị phân này bằng tay ...

5) Vì vậy, đây là mã tôi đã sử dụng để tính toán mã Huffman và lưu trữ chúng trong một mảng: (đầu tiên tôi đọc dữ liệu ở mức 1) và đặt nó trong một mảng: dhtBitnum)

  int binaryCode = 0; 
      count = 0; 
      StringBuffer codeString = new StringBuffer();    

      //populate array with code strings 
      for (int numBits=1; numBits<=16; numBits++) { 

       //dhtBitnum contains the number of codes that have a certain number of bits 
       for (int i=1; i<=dhtBitnum[(numBits-1)]; i++) { 

        //turn the binary number into a string 
        codeString.append(Integer.toBinaryString(binaryCode)); 
        //prepend 0s until the code string is the right length 
        for(int n=codeString.length(); n<numBits; n++) { 
         codeString.insert(0, "0"); 
        } 
        //put the created Huffman code in an array 
        dhtCodes[count]=codeString.toString(); 
        binaryCode++; 
        count ++; 
        codeString.delete(0, codeString.length()); 
       } 
       binaryCode = binaryCode << 1; 

      } 

một khi tôi đã tạo ra mã Huffman và lưu trữ chúng theo thứ tự, tôi chỉ có thể thêm các biểu tượng mà họ đề cập đến theo thứ tự như họ đi cùng trong 2). Điều này có thể không được terribly thanh lịch nhưng nó dường như làm việc ít nhất và tạo ra các bảng chính xác.

6) Nếu bất kỳ ai vẫn đang theo dõi điều này, bạn xứng đáng nhận được huy chương.

7) Bây giờ vấn đề là tôi muốn lưu trữ thông tin này trong một cây nhị phân để tôi có thể giải mã hiệu quả dữ liệu hình ảnh jpg sau này, thay vì tìm kiếm thông qua các mảng mọi lúc. Thật không may tôi không thể tìm ra một cách sạch sẽ và hiệu quả để làm điều này trực tiếp từ các thông tin được cung cấp trong các tiêu đề jpg như trên.
Cách duy nhất tôi có thể nghĩ đến là làm việc với các mã Huffman như trên trước, sau đó triển khai một số phương thức tạo các nút khi cần và lưu các ký hiệu ở vị trí thích hợp, sử dụng mã làm địa chỉ.Tuy nhiên điều này có vẻ như một vòng về cách mà cũng là nhân bản các thông tin tôi cần, tôi chắc chắn phải có một phương pháp tốt hơn và đơn giản hơn nhiều.

8) Vì vậy, nếu có ai hiểu ramblings của tôi, tôi sẽ rất biết ơn đối với một số gợi ý. Tôi nhận ra đây là một vấn đề rất cụ thể, nhưng nếu không có gì khác thì thông tin trên có thể hữu ích cho ai đó. Tôi vẫn còn rất mới ở đây vì vậy lý do vô minh của tôi, dễ hiểu mã đặc biệt được chào đón!

+0

Điều này đã giúp tôi rất nhiều. Cảm ơn bạn người đàn ông, bạn là vua: D – MrD

Trả lời

2

Làm thế nào để thực hiện điều này trực tiếp tôi không hoàn toàn chắc chắn, vì phải mất một thời gian để xử lý thông tin, nhưng thuật toán nên được khá thẳng về phía trước nếu bạn biết về tries. Có vẻ như từ điểm 7 mà bạn không?

Tôi sẽ thêm một ví dụ:

  ° 
     /\ 
    / \ 
     °  ° 
    /\ /\ 
    a b c d 

Trong Trie đơn giản này, nếu chúng ta đi lại chúng tôi sẽ giả định trái là 0, bên phải là một 1. Vì vậy, Nếu bạn gặp các mô hình '00' điều này tương ứng với a. Mẫu '10' tương ứng với c. Thông thường với những cây huffman, cây trie sẽ không cân bằng, tức là

 ° 
    /\ 
    a ° 
    /\ 
    b ° 
     /\ 
     c d 

Trong trường hợp này, mã tiền tố '0' tương ứng với a. Mã 111 đến 'd'.

+0

Cảm ơn wds, cố gắng đã được đề cập đến tôi trong một bài viết trên một câu hỏi tương tự. Tôi không chắc chắn tôi hiểu sự khác biệt giữa họ và một cây nhị phân mặc dù. Thing là tôi đang gặp vấn đề một cách hiệu quả tạo ra trie/cây trực tiếp từ thông tin tiêu đề DHT. – joinJpegs

+0

Đừng lo lắng tôi nhận ra điều này có lẽ quá bí truyền một câu hỏi cho bất kỳ câu trả lời cụ thể nào. Tôi đã hy vọng tôi có thể rơi vào một guru jpg với bộ giải mã riêng của họ, người có thể ném một số mã đã sẵn sàng theo cách của tôi! – joinJpegs

+0

Hmmm bạn có thể chỉnh sửa câu hỏi của mình để giải thích cách bạn biết biểu tượng, ví dụ, hai bit được mã hóa là 00 và không phải là 11 chẳng hạn? Sau đó, tôi có thể có thể đưa ra một thuật toán. – wds

0

Như @wds đã nói, hãy thử trợ giúp. Ý tưởng cốt lõi với giải mã Huffman là các bit của mã seqence nên được sử dụng để "đi bộ" các trie, lấy một trái khi mã có 0, và một quyền cho 1, cho đến khi từ mã kết thúc. Sau đó, bạn sẽ ở trong nút trie lưu trữ dữ liệu thay thế cho mã đó.

+0

Tôi nghĩ rằng tôi đã được một chút terse vì vậy tôi chỉ cần thêm một ví dụ để gợi ra rằng điểm rất. :) – wds

Các vấn đề liên quan