iTrans를 업데이트하면서 이미지의 해상도를 읽어야 할 상황이 생겼다.
IJG 및 libpng를 사용하면 되긴 하지만, 고작 해상도 정보 얻자고 라이브러리까지 쓰긴 좀 그래서 간단한 방법을 쓰기로 했다.
간단히(응?) 파일을 뒤져서 해상도 정보를 찾는 것.
cplusplus.com에서 관련된 소스를 찾을 수 있었다.
그런데, 이 코드에는 사소한 문제들이 있다.
- GIF도 포함된 소스인데, 난 GIF는 안 쓰기 때문에 제거 가능
- 파일 크기를 얻기 위해 fseek() 등을 쓰는데, 필요 없음
- JPEG 헤더를 읽을 때 EXIF가 앞에 들어있는 경우는 제대로 처리하지 못함
- 파일의 형식은 알려주지 않음
아래 코드는 이 내용이 반영된 코드이다.
// itype: 1=JPEG 2=PNG
bool getImageTypeNSize(LPCTSTR lpFile, int &iType, int &iWidth, int &iHeight)
{
// 참고 사이트: http://www.cplusplus.com/forum/beginner/45217/
iType = iWidth = iHeight = 0;
FILE *f;
if (_tfopen_s(&f, lpFile, _T("rb")) || !f) {
return false;
}
BYTE buf[24];
if (fread_s(buf, 24, 1, 24, f) != 24) {
fclose(f);
return false;
}
// For JPEGs, we need to read the first 12 bytes of each chunk.
// We'll read those 12 bytes at buf+2...buf+14, i.e. overwriting the existing buf.
if (buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF)
{
iType = 1;
long pos = 2;
while (buf[2] == 0xFF)
{
if (buf[3] == 0xC0 || buf[3] == 0xC1 || buf[3] == 0xC2 || buf[3] == 0xC3 || buf[3] == 0xC9 || buf[3] == 0xCA || buf[3] == 0xCB) break;
pos += 2 + (buf[4] << 8) + buf[5];
fseek(f, pos, SEEK_SET);
if (fread_s(buf + 2, 22, 1, 12, f) != 12) break;
}
}
fclose(f);
// JPEG: (first two bytes of buf are first two bytes of the jpeg file; rest of buf is the DCT frame
if (iType ==1 && buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF)
{
iHeight = (buf[7] << 8) + buf[8];
iWidth = (buf[9] << 8) + buf[10];
return true;
}
// PNG: the first frame is by definition an IHDR frame, which gives dimensions
if (buf[0] == 0x89 && buf[1] == 'P' && buf[2] == 'N' && buf[3] == 'G' && buf[4] == 0x0D && buf[5] == 0x0A && buf[6] == 0x1A && buf[7] == 0x0A
&& buf[12] == 'I' && buf[13] == 'H' && buf[14] == 'D' && buf[15] == 'R')
{
iWidth = (buf[16] << 24) + (buf[17] << 16) + (buf[18] << 8) + (buf[19] << 0);
iHeight = (buf[20] << 24) + (buf[21] << 16) + (buf[22] << 8) + (buf[23] << 0);
iType = 2;
return true;
}
return false;
}
MS Excel의 YEARFRAC() 동작 방식 (0) | 2016.09.04 |
---|---|
연산 결과를 0~255 이내로 하는 가장 빠른 방법은? (3) | 2016.04.01 |
Sqrt(2)의 수렴 (2) | 2015.01.18 |
XOR로 계산하는 암호 해독 (프로젝트 오일러 #59) (0) | 2015.01.05 |
챔퍼나운(Champernowne) 상수의 특정 자리 숫자는? (프로젝트 오일러 #40) (0) | 2014.11.02 |