C++ Builder 11, 사용하고 있습니다. 현재의 TPngImage 클래스의 Ver 함수 리턴값을 읽어보면 1.564 로 나옵니다.
제가 다루는 것은 5120x3840 의 14bit Gray Raw Image입니다.
저장을 위해 16 bit Gray Png 이미지를 사용하고자 테스트 하고 있습니다.
아래와 같이 Png 이미지를 생성하였고, 여기에 저장할 Raw Data Buffer를 읽어들인 형태입니다.
m_compress = 1; // compression (0~9)
ColorType = COLOR_GRAYSCALE; // :0
Bitdepth = 16; // 16 bit gray
cx = 5120; // width
cy = 3840; // height
pImgBuffer = new WORD[cx * cy *sizeof(WORD)]; // 16bit array data for image buffer
if(pImgBuffer)
LoadRaw( "tImg.raw", cx, cy ); // saved file data load
else return;
pPngImg = new TPngImage(ColorType, Bitdepth, cx, cy); // Png image class create
String sVer = pPngImg->Version; // ver 1.564
아래와 같이 저장하는 코드를 작성하였습니다.
Scanline과 ExtraScanline 을 이용하여, Gray Raw값을 8bit 씩 쪼개어 대입합니다.
1번 문제점: 이 저장 코드를 그냥 수행하면, Access Violation 오류가 발생되는 것. CPU 코드 디버그 창에는
vclimg280.@Vcl@Imaging@Pngimage@TChunkPLTE@SaveToStream$qqrp22System@Classes@TStream:
이 함수를 수행하던 중 에러 발생인 것으로 나옵니다.
다른 상용 프로그램에서 저장한 PNG파일의 내용을 보면, 16bit gray 이미지라서
PNG의 IHDR 다음에 바로 IDAT 가 나오고 있어 실제로 PLTE 헤더 데이타는 없는 형태로 나타납니다.
뭔가 설정을 더 해줘야 하는 것이 있는 것인지 모르겠네요.
2번 문제점: 상용프로그램으로 Raw데이타로 읽어서 Png로 저장해 둔 파일을 pPngImg->LoadToFile()로 한번 읽은
상태에서 저장 코드를 돌리면, 1번처럼 AccesssViolation 에러는 안나고, 저장이 됩니다.
다만, 특정 포인트 값을 보면, Raw 데이터는 0x633 이라, scanline/extrascanline 에 값을 대입했는데,
실제 저장된 결과물에는 0x600으로 저장되어 있어, 하위비트가 사라진 것처럼, 0x33값 만큼 차이가 나게 저장됩니다.
ExtraScanline의 값이 제대로 저장이 안되는 것이 아닌가 생각됩니다.
무엇을 조치해줘야 제대로 될까요? 아니면, PNGImage 클래스의 버그인가요?
1번같은 경우 TWICImage를 만들어 Assign(pPngImg)로 해 보았으나, 내부 루틴은 동일한 것인지,
유사하게 저장시에 PLTE에서 Access Violation 나옵니다.
질문
Alone
C++ Builder 11, 사용하고 있습니다. 현재의 TPngImage 클래스의 Ver 함수 리턴값을 읽어보면 1.564 로 나옵니다.
제가 다루는 것은 5120x3840 의 14bit Gray Raw Image입니다.
저장을 위해 16 bit Gray Png 이미지를 사용하고자 테스트 하고 있습니다.
아래와 같이 Png 이미지를 생성하였고, 여기에 저장할 Raw Data Buffer를 읽어들인 형태입니다.
m_compress = 1; // compression (0~9)
ColorType = COLOR_GRAYSCALE; // :0
Bitdepth = 16; // 16 bit gray
cx = 5120; // width
cy = 3840; // height
pImgBuffer = new WORD[cx * cy *sizeof(WORD)]; // 16bit array data for image buffer
if(pImgBuffer)
LoadRaw( "tImg.raw", cx, cy ); // saved file data load
else return;
pPngImg = new TPngImage(ColorType, Bitdepth, cx, cy); // Png image class create
String sVer = pPngImg->Version; // ver 1.564
아래와 같이 저장하는 코드를 작성하였습니다.
Scanline과 ExtraScanline 을 이용하여, Gray Raw값을 8bit 씩 쪼개어 대입합니다.
for(int h = 0; h < pPngImg->Height; h++)
{
ptr = (BYTE *)( pPngImg->Scanline[h] );
extp = (BYTE *)( pPngImg->ExtraScanline[h] );
for(int w=0; w<pPngImg->Width; w++)
{
pdat = (BYTE *)(pImgBuffer + h*pPngImg->Width + w); // from image buffer data to PngImage data
ptr[w] = pdat[1]; // 8bit
extp[w] = pdat[0]; // 8bit
}
}
pPngImg->SaveToFile("Test.png"); // save png image file
1번 문제점: 이 저장 코드를 그냥 수행하면, Access Violation 오류가 발생되는 것. CPU 코드 디버그 창에는
vclimg280.@Vcl@Imaging@Pngimage@TChunkPLTE@SaveToStream$qqrp22System@Classes@TStream:
이 함수를 수행하던 중 에러 발생인 것으로 나옵니다.
다른 상용 프로그램에서 저장한 PNG파일의 내용을 보면, 16bit gray 이미지라서
PNG의 IHDR 다음에 바로 IDAT 가 나오고 있어 실제로 PLTE 헤더 데이타는 없는 형태로 나타납니다.
뭔가 설정을 더 해줘야 하는 것이 있는 것인지 모르겠네요.
2번 문제점: 상용프로그램으로 Raw데이타로 읽어서 Png로 저장해 둔 파일을 pPngImg->LoadToFile()로 한번 읽은
상태에서 저장 코드를 돌리면, 1번처럼 AccesssViolation 에러는 안나고, 저장이 됩니다.
다만, 특정 포인트 값을 보면, Raw 데이터는 0x633 이라, scanline/extrascanline 에 값을 대입했는데,
실제 저장된 결과물에는 0x600으로 저장되어 있어, 하위비트가 사라진 것처럼, 0x33값 만큼 차이가 나게 저장됩니다.
ExtraScanline의 값이 제대로 저장이 안되는 것이 아닌가 생각됩니다.
무엇을 조치해줘야 제대로 될까요? 아니면, PNGImage 클래스의 버그인가요?
1번같은 경우 TWICImage를 만들어 Assign(pPngImg)로 해 보았으나, 내부 루틴은 동일한 것인지,
유사하게 저장시에 PLTE에서 Access Violation 나옵니다.
이 댓글 링크
다른 사이트에 공유하기
0 answers to this question
Recommended Posts
이 토의에 참여하세요
지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.