장길석씨가 소개해 주신 PNG파일 출력 샘플을 보고 작성해 봤습니다.
PNG와 JPEG을 처리하는 TImage란 구조체를 만들었습니다.
TBitmap를 인헤릿한 것인데 PNG와 JPEG출력에 필요한 data를 뒤에 더 추가할 수 있습니다. syntax는 gxBmpOpen과 비슷한 gxJpegOpen과 gxPngOpen함수를 만들어 TBitmap*를 return 받도록 하였습니다.
파일에서 JPEG과 PNG를 읽은 후에는 Bitmap으로 전환된다는 기본적인 생각으로 만들었습니다.
JPEG라이브러리는 포함시키지 않았습니다만 아마도 많이들 가지고 계신 라이브러리 일 것입니다.
 b_24_SetPixel이란 함수와 b_24_Color란 함수도 수정하였습니다.
저는 윈도우즈에서 gx라이브러리를 emul하여 test해 보았으므로 Big Endian Litte Endian문제가 있을 수 있습니다.
또다시 라이브러리가 바뀌었더라고요.
제가 Editing한 라이브러리는 png샘플의 것이었습니다. 아마도 그에 따라 추가적인 Editing이 필요할 것이라고 생각됩니다. 그럼 보시고 한번 검토해 주시길 바랍니다.
 
파일이 어태치가 안되네요.
계략적인 내용을 copy합니다.

typedef struct TImage__ TImage;
struct TImage__
{
   char     DcType;                                                              // DC의 형태로 Screen, Bitmap을 구분한다.
   int      Width;                                                               // 도트 단위의 폭
   int      Height;                                                              // 도트 단위의 높이
   int      Dots;                                                                // 전체 도트 갯수 width * height
   int      Bytes;                                                               // 메모리의 전체 Byte 크기
   int      Colors;                                                              // 칼라 깊이
   int      BytesPerLine;                                                        // 라인당 바이트 개수
   int      BitsPerPixel;                                                        // 비트당 픽셀 개수
   int      xCoor;                                                               // 이전에 그리기 했던 마지막 좌표
   int      yCoor;                                                               // 이전에 그리기 했던 마지막 좌표
   int      PenColor;                                                            // 현재의 펜 칼라
   int      BrushColor;                                                          // 현재의 브러쉬 칼라
   void    *Mapped;                                                              // 메모리 매핑된 포인터

   void (*ReleaseDC)( Tdc *dc);                                                  // Device Context 소멸 및 관련 메모리를 삭제
   int  (*Color   )( int Red, int Green, int Blue);              // 칼라값 구하기
   void (*Clear )( TBitmap *bmp, int Color);                // 색으로 전체 칠하기
 void (*GetPixel)( TBitmap *bmp, int xCoor, int yCoor, TColor *Color);       // 칼라 값을 읽어 오기
 void (*SetPixel)( TBitmap *bmp, int xCoor, int yCoor, int Color   );       // 점 찍기
   void (*hLine )( TBitmap *bmp, int x1st , int x2nd , int yCoor, int Color); // 수평선 긋기
   void (*vLine )( TBitmap *bmp, int xCoor, int y1st , int y2nd , int Color); // 수직선 긋기

   int   ErrorCode;                                                              // 에러 코드

 int   FileSize;                                                               // ^  이미지 파일 사이즈
 int   Reserved;                                                               // |  예약 영역
 int   DataOffset;                                                             // |
 int   HeaderSize;                                                             // |
 int   imgWidth;                                                               // |  이미지 폭
 int   imgHeight;                                                              // |  이미지 높이
 short cntPlanes;                                                              // |  bmp 헤더 영역 52 bytes
 short bpp;                                                                    // |
 int   Compression;                                                            // |  압축 형식
 int   BitmapSize;                                                             // |
 int   hRes;                                                                   // |
 int   vRes;                                                                   // |
 int   cntColors;                                                              // |
 int   ImportantColors;                                                        // v

 int            cntPalette;                                                    // 팔레트 개수
 TPalette      *Palette;                                                       // 팔레트 칼라 정보
 unsigned char *Data;                                                          // 이미지 영역의 포인터
 unsigned char *EncodedData;
 unsigned       bSizeBlue  , bSizeGreen  , bSizeRed;                           // R,G,B 각 색상별 비트 크기
 unsigned       bOffsetBlue, bOffsetGreen, bOffsetRed;                         // R,G,B 각 색상별 값을 구하기 위한 쉬프트 횟수
};

//extern TBitmap* gxJpegOpen( char  *FileName);
extern TBitmap* gxPngOpen( char  *FileName);



TBitmap*   gxPngOpen( char* FileName )
{
 Iterator iter;
 TImage*  img;
 FILE          *infile;
 unsigned char            sig[8];
 png_structp    png_ptr = NULL;
 png_infop      info_ptr = NULL;

 png_uint_32    ihdr_width, ihdr_height;
 int            width, height ,row;
 int            bit_depth, color_type;
 png_color_16p  pBackground;

 unsigned char            bg_red =0, bg_green=0, bg_blue=0;
 unsigned char           *image_data = NULL;
 int            image_channels, image_rowbytes;
 double         display_exponent  = 1.0 * 2.2;

 double         gamma;
 png_uint_32    rowbytes;
 png_bytepp     row_pointers = NULL;
 int            i;

 if ( NULL == ( img = malloc( sizeof( TImage))) )    return NULL;

 memset( img, 0, sizeof( TImage));

 memset( &iter, 0x00, sizeof(Iterator));
 iter.ima = img;


   infile = fopen( FileName, "rb");
   fread(sig, 1, 8, infile);
   if ( !png_check_sig(sig, 8)) 
    return NULL;

   png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); // 사용자 에러 정의 핸들러를 모두 NULL로 설정
   
   if ( !png_ptr)   
    return NULL;
 
   info_ptr = png_create_info_struct( png_ptr);
   
   if(!info_ptr)
   {
  png_destroy_read_struct(&png_ptr,
           (png_infopp)NULL, (png_infopp)NULL);
    return NULL;
   }

 if(setjmp(png_jmpbuf(png_ptr)))
 {
  png_destroy_read_struct( &png_ptr, &info_ptr, NULL);
  return NULL;
 }

 png_init_io( png_ptr, infile);
 png_set_sig_bytes( png_ptr, 8);                                   // we already read the 8 signature bytes
 png_read_info( png_ptr, info_ptr);                                // read all PNG info up to image data

               /* alternatively, could make separate calls to png_get_image_width(),
                * etc., but want bit_depth and color_type for later [don't care about
                * compression_type and filter_type => NULLs] */

 png_get_IHDR(png_ptr, info_ptr, &ihdr_width, &ihdr_height, &bit_depth, &color_type, NULL, NULL, NULL);
 width    = ihdr_width;
 height   = ihdr_height;

 gxGivenBmpCreate( (TBitmap*) img, ihdr_width, ihdr_height, bit_depth*3, 0 );
 //Create(info_ptr->width, info_ptr->height, pixel_depth,
 // info_ptr->color_type);

 png_get_bKGD(png_ptr, info_ptr, &pBackground);

 /* however, it always returns the raw bKGD data, regardless of any
 * bit-depth transformations, so check depth and adjust if necessary */

 if ( bit_depth == 16)
 {
   bg_red   = pBackground->red   >> 8;
   bg_green = pBackground->green >> 8;
   bg_blue  = pBackground->blue  >> 8;
 }
 else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
 {
   if (bit_depth == 1)
    bg_red = bg_green = bg_blue = pBackground->gray? 255 : 0;
   else if (bit_depth == 2)
    bg_red = bg_green = bg_blue = (255/3) * pBackground->gray;
   else /* bit_depth == 4 */
    bg_red = bg_green = bg_blue = (255/15) * pBackground->gray;
 }
 else
 {
   bg_red   = (unsigned char)pBackground->red;
   bg_green = (unsigned char)pBackground->green;
   bg_blue  = (unsigned char)pBackground->blue;
 }

 if(setjmp(png_jmpbuf(png_ptr)))
 {
  png_destroy_read_struct( &png_ptr, &info_ptr, NULL);
 }

 if (color_type == PNG_COLOR_TYPE_PALETTE)
  png_set_expand(png_ptr);
 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
  png_set_expand(png_ptr);
 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
  png_set_expand(png_ptr);
 if (bit_depth == 16)
  png_set_strip_16(png_ptr);
 if (color_type == PNG_COLOR_TYPE_GRAY ||
  color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  png_set_gray_to_rgb(png_ptr);


 /* unlike the example in the libpng documentation, we have *no* idea where
  * this file may have come from--so if it doesn't have a file gamma, don't
  * do any correction ("do no harm") */

 if (png_get_gAMA(png_ptr, info_ptr, &gamma))
  png_set_gamma(png_ptr, display_exponent, gamma);


 /* all transformations have been registered; now update info_ptr data,
  * get rowbytes and channels, and allocate image memory */

 png_read_update_info(png_ptr, info_ptr);

 image_rowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
 image_channels = (int)png_get_channels(png_ptr, info_ptr);

 if ( (image_data = (unsigned char *)malloc(rowbytes*height)) == NULL)
 {
  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  return NULL;
 }

 if ( (row_pointers = (png_bytepp)malloc(height*sizeof( png_bytep))) == NULL)
 {
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    free(image_data);
    return NULL;
 }

 for (i = 0;  i < height; i++)
   row_pointers[i] = image_data + i*rowbytes;

 /* now we can go ahead and just read the whole image */

 png_read_image( png_ptr, row_pointers);

                              {
                                 ulg red, green, blue;
                                 ulg r, g, b, a;
                                 int      row;
                                 int      clrPixel;
                                 uch     *src;

                                 for ( row = 0;  row < height;  ++row)
                                 {
                                    src   = image_data + row*image_rowbytes;
                                    if ( image_channels == 3)
                                    {
                                       for (i = 0; i < width; i++)
                                       {
                                          red   = *src++;
                                          green = *src++;
                                          blue  = *src++;
                                          clrPixel = gxColor( img, red, green, blue);
                                          gxSetPixel( img, i, row, clrPixel);
                                       }
                                    }
                                    else /* if (image_channels == 4) */
                                    {
                                       for (i = 0; i < width; i++)
                                       {
                                           r = *src++;
                                           g = *src++;
                                           b = *src++;
                                           a = *src++;
                                           if (a == 255)
                                           {
                                               red   = r;
                                               green = g;
                                               blue  = b;
                                                clrPixel = img->Color(  red, green, blue);
                                                img->SetPixel( img, i, row, clrPixel);
                                           } else if (a == 0) {                  // 투명인 부분
/*                                              red   = bg_red;
 C                                              green = bg_green;
 *                                              blue  = bg_blue;
 */
                                           } else {
/*                                               /  * this macro (from png.h) composites the foreground
 *                                                  * and background values and puts the result into the
 *                                                  * first argument *  /
 D                                               alpha_composite(red,   r, a, bg_red);
 *                                               alpha_composite(green, g, a, bg_green);
 *                                               alpha_composite(blue,  b, a, bg_blue);
 */
                                           }
                                       }
                                    }
                                 }
                              }

/* 
 IterUpset(&iter);
 row = height-1;
 while (row >=0 ) {
  IterSetRow( &iter, row_pointers[row], rowbytes );
  IterPrevRow( &iter );
  row--;
 }
*/

 free( row_pointers);
 row_pointers = NULL;

 png_read_end( png_ptr, NULL);

  // 화면 출력 끝
 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

 free(image_data);
 /* close the file */
 fclose(infile);

 return  (TBitmap*) img;
}

/*
void TestJpegToDC( Tdc *dc,                                                    // 출력 대상 화면 DC
                     char *bmpFileName                                           // 출력할 Bitmap
                   )
{
   TImage *bmp;                                                                 // Bitmap DC

   bmp = gxJpegOpen( bmpFileName);                                                // 비트맵 파일 읽기
   gxBitBlt( dc, 0, 0, (Tdc *)bmp, 0, 0, bmp->Width, bmp->Height);               // 바로 화면에 출력
   gxBmpClose( bmp);                                                             // 비트맵 파일 사용 종료
}
*/
void TestPngToDC( Tdc *dc,                                                    // 출력 대상 화면 DC
                     char *bmpFileName                                           // 출력할 Bitmap
                   )
{
   TImage *bmp;                                                                 // Bitmap DC

   bmp = gxPngOpen( bmpFileName);                                                // 비트맵 파일 읽기
   gxBitBlt( dc, 0, 0, (Tdc *)bmp, 0, 0, bmp->Width, bmp->Height);               // 바로 화면에 출력
   gxBmpClose( bmp);                                                             // 비트맵 파일 사용 종료
}

TBitmap *gxGivenBmpCreate( TBitmap* bmp , int Width, int Height, int Depth, int PaletteSize)
{

   SetHeader( bmp, Width, Height, Depth, PaletteSize);

   if ( NULL == ( bmp->Data = malloc( bmp->BitmapSize)) )
   {
      return NULL;
   }

   return SetupBitmap( bmp);
}

static void b24_SetPixel( TBitmap *bmp, int xCoor, int yCoor, int Color)
{
   unsigned char *pData;
   int            offset = ( bmp->Height -yCoor -1) * bmp->BytesPerLine + xCoor * 3;

   pData          = bmp->Data + offset;
   *(pData+3)          = (Color&0xFF000000)>>24;
   *(pData+2)          = (Color&0x00FF0000)>>16;
   *(pData+1)          = (Color&0x0000FF00)>>8;
   *(pData+0)          = (Color&0x000000FF);
}

static int b24_Color(  int Red,                                                  // 0부터 255 사이의 Red   값
                        int Green,                                               // 0부터 255 사이의 Green 값
                        int Blue                                                 // 0부터 255 사이의 Blue  값
                     )
// 설명: 칼라 값을 구한다.
{
   return  (Red << 16) | (Green << 8) | Blue;
}


/*
TBitmap   *gxJpegOpen( char  *FileName)
{

   TImage    *img;
   Iterator iter;
  struct jpeg_decompress_struct cinfo;
  struct ima_error_mgr jerr;
  FILE * infile;  
  JSAMPARRAY buffer;
  int row_stride;  

   if ( NULL == ( img = malloc( sizeof( TImage))) )    return NULL;

   memset( img, 0, sizeof( TImage));

   
  memset( &iter, 0x00, sizeof(Iterator));
  iter.ima = img;


//  struct jpeg_error_mgr jerr;

  if ((infile = fopen((const char *)FileName, "rb")) == NULL) {
  return 0;
  }

  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = ima_jpeg_error_exit;

  if (setjmp(jerr.setjmp_buffer)) {
  jpeg_destroy_decompress(&cinfo);
  fclose(infile);
  return 0;
  }
  jpeg_create_decompress(&cinfo);

  jpeg_stdio_src(&cinfo, infile);

  (void) jpeg_read_header(&cinfo, TRUE);

  if (cinfo.jpeg_color_space!=JCS_GRAYSCALE) {
 cinfo.quantize_colors = TRUE;
 cinfo.desired_number_of_colors = 128;
  }
  jpeg_start_decompress(&cinfo);

  if (cinfo.jpeg_color_space==JCS_GRAYSCALE)
  {
 gxGivenBmpCreate( (TBitmap*) img, cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, 256);
 CreateGrayColourMap( img->Palette ,256);
  }

  else
  {
 gxGivenBmpCreate( (TBitmap*)img, cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, cinfo.actual_number_of_colors);
 SetPalette( img->Palette, cinfo.actual_number_of_colors, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]);
  }
  row_stride = cinfo.output_width * cinfo.output_components;

  buffer = (*cinfo.mem->alloc_sarray)
  ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

  IterUpset(&iter);
  while (cinfo.output_scanline < cinfo.output_height) {
  (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  IterSetRow( &iter, buffer[0], row_stride);
  IterPrevRow( &iter );
  }

  (void) jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);

  fclose(infile);
  return (TBitmap*)img;
}
*/


압축한 소스파일을 업로드가 할 수 없네요. 정책적인 것인가요?


그럼 검토해 보시고 의견 주시길 바랍니다.


-->파일 첨부 버튼을 눌러도 아무런 반응이 없습니다.... ~~;;