C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[76447] TPngImage 사용하여 16bit Gray Raw Data를 저장시 문제
Alone [] 628 읽음    2023-03-29 18:25
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;
    cx = 5120;
    cy = 3840;

    pImgBuffer = new WORD[cx * cy *sizeof(WORD)];
    if(pImgBuffer)
        LoadRaw( "tImg.raw",  cx, cy );
    else return;

    pPngImg = new TPngImage(ColorType, Bitdepth, cx, cy);
    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);

                ptr[w] = pdat[1];       //  8bit
                extp[w] = pdat[0];      //  8bit
            }
        }
        pPngImg->SaveToFile("Test.png");

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번처럼 에러는 안나고, 저장은 됩니다.
                  다만,  특정 포인트 값을 보면, Raw 데이터는 0x633 이라, scanline/extrascanline 에 값을 대입했는데,
                  실제 저장된 결과물에는 0x600으로 저장되어 있어, 하위비트가 사라진 것처럼,  0x33값 만큼 차이가 나게 저장됩니다.
                  ExtraScanline의 값이 제대로 저장이 안되는 것이 아닌가 생각됩니다.

무엇을 조치해줘야 제대로 될까요? 아니면, PNGImage 클래스의 버그인가요?
1번같은 경우 TWICImage를 만들어 Assign 해 보았으나,  내부 루틴은 동일한 것인지
  저장시에 PLTE에서 Access Violation 나옵니다.


+ -

관련 글 리스트
76447 TPngImage 사용하여 16bit Gray Raw Data를 저장시 문제 Alone 628 2023/03/29
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.