2011-04-22 2 views
3

저는 마조히스트이기 때문에 8 비트 PNG 파일을 디코딩하기 위해 C로 무언가를 쓰려고합니다. libpng을 재발견하는 것 ...)이미지 디코딩의 컨텍스트에서 "부호없는 모듈러스 256"이란 의미는 무엇입니까?

내 deflated, 필터링되지 않은 데이터 버퍼에있는 물건이 틀림없이 소스 이미지와 닮았지만 (여전히 아래를 보시오), 여전히, erm, filtering algorithms을 구현 한 것으로 뭔가 가짜 일 것이라고 확신합니다. 그들 대부분은 매우 간단하지만, 내가 수학에서 좋은으로 또는 어느 빌려 - 공상 과학 과정을 촬영 한하지의 docs에서 이해하지 못하는 한 가지 중요한 일이있다 :

부호없는 산술 모듈 (256)을 사용하는

, 그래서 입력과 출력이 모두 바이트에 맞는지 확인하십시오.

그게 무슨 뜻입니까?

누군가가 내가 매우 감사 할 것이라고 말할 수 있다면!



참고로 (나는 엉터리 C 죄송) 같이 docs 모습에서 설명한 필터링 알고리즘 내 멍청이 구현 :

unsigned char paeth_predictor (unsigned char a, unsigned char b, unsigned char c) { 
    // a = left, b = above, c = upper left 
    char p = a + b - c; // initial estimate 
    char pa = abs(p - a); // distances to a, b, c 
    char pb = abs(p - b); 
    char pc = abs(p - c); 
    // return nearest of a,b,c, 
    // breaking ties in order a,b,c. 
    if (pa <= pb && pa <= pc) return a; 
    else if (pb <= pc) return b; 
    else return c; 
} 

void unfilter_sub(char* out, char* in, int bpp, int row, int rowlen) { 
    for (int i = 0; i < rowlen; i++) 
     out[i] = in[i] + (i < bpp ? 0 : out[i-bpp]); 
} 

void unfilter_up(char* out, char* in, int bpp, int row, int rowlen) { 
    for (int i = 0; i < rowlen; i++) 
     out[i] = in[i] + (row == 0 ? 0 : out[i-rowlen]); 
} 

void unfilter_paeth(char* out, char* in, int bpp, int row, int rowlen) { 
    char a, b, c; 
    for (int i = 0; i < rowlen; i++) { 
     a = i < bpp ? 0 : out[i - bpp]; 
     b = row < 1 ? 0 : out[i - rowlen]; 
     c = i < bpp ? 0 : (row == 0 ? 0 : out[i - rowlen - bpp]); 
     out[i] = in[i] + paeth_predictor(a, b, c); 
    } 
}    



그리고 이미지 제가 보는 :

소스

Source http://img220.imageshack.us/img220/8111/testdn.png

출력

Output http://img862.imageshack.us/img862/2963/helloworld.png

+0

확실치 않지만 모든 곳에서'char' 대신'unsigned char'을 시도해 보셨습니까? –

+0

@Mike Dunlavey - 예, 기본적으로 마술 조합이 이루어질 때까지 여러 장소에서'서명되지 않은 char '을 추가하는 것으로 끝났습니다! – Mikesname

답변

6

그것은 의미, 알고리즘에서, 때마다 산술 연산이 수행되면, 수행됨 모듈로 256, 즉 결과가 256보다 큰 경우 it "wraps" around. 결과적으로 모든 값은 항상 오버플로가 아닌 8 비트에 맞춰집니다.

서명되지 않은 유형은 이미 위임에 의해이 방법 행동, 당신은 unsigned char를 사용 (및 시스템의 바이트는 아마 8 비트입니다), 다음 계산 결과 자연스럽게 단지 결코 오버 플로우 (8)을 넘어 비트합니다.

1

결과의 마지막 8 비트 만 사용된다는 의미입니다. 2^8 = 256, 부호없는 값 v의 마지막 8 비트는 (v % 256)과 같습니다. 257

, + 255 = 257 (2), 또는 100,000,001, 마지막 8 비트가 1이고, 257% (256)는 사용자가 "OUT"가지 않을 것을 의미 역시 '간단한 언어'1.

0

인 너의 바이트 크기의.C#에서 예를 들어

당신은 실패합니다이 시도하는 경우 :

byte test = 255 + 255; 

(1,13) : 오류 CS0031을 : 상수 값 '510'은 '바이트'

로 변환 할 수 없습니다
byte test = (byte)(255 + 255); 

(1,13) : 오류 CS0221 : 정수 값 '510'은 '바이트'로 변환 할 수있다 (사용 '취소 체크 된 '문법)

모든 계산마다 모듈로 256 (C# : % 256)을 사용해야합니다.

(byteVal1 + byteVal2 + byteVal3) % 256 
= (((byteVal1 % 256) + (byteVal2 % 256)) % 256 + (byteVal3 % 256)) % 256 
: 가끔 바이트 시리즈를 단순화 할 수

byte test = ((255 + 255) % 256); 
// test: 254 
byte test = ((255 + 255) & 255); 
// test: 254 
byte test = ((1 + 379) % 256); 
// test: 124 
byte test = ((1 + 379) & 0xFF); 
// test: 124 

참고 :

(175 + 205) mod 256 = (175 + 205) AND 255 

일부의 C# 샘플 : 대신 당신은 또한 을 할 수있는 256%와 255를 작성

관련 문제