⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dim_bmp_format.cpp

📁 Digital Notebook Source Code v1.1.0 [
💻 CPP
字号:
/*****************************************************************************
  BMP support 
  Copyright (c) 2004 by Dmitry V. Fedorov <www.dimin.net> <dima@dimin.net>

  IMPLEMENTATION
  
  Programmer: Dima V. Fedorov <mailto:dima@dimin.net> <http://www.dimin.net/>

  History:
    04/22/2004 13:06 - First creation
    05/10/2004 14:55 - Big endian support
    08/04/2004 22:25 - Update to FMT_IFS 1.2, support for io protorypes
        
  Ver : 3
*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Disables Visual Studio 2005 warnings for deprecated code#ifdef WIN32   #pragma warning(disable:4996)#endif

#include "dim_bmp_format.h"
#include "dim_bmp_format_io.cpp"

//****************************************************************************
//
// INTERNAL STRUCTURES
//
//****************************************************************************

bool bmpGetImageInfo( TDimFormatHandle *fmtHndl )
{
  if (fmtHndl == NULL) return FALSE;
  if (fmtHndl->internalParams == NULL) return FALSE;
  TDimBmpParams *bmpPar = (TDimBmpParams *) fmtHndl->internalParams;
  TDimImageInfo *info = &bmpPar->i;  

  *info = initTDimImageInfo();
  info->number_pages = 1;
  info->samples = 1;


  if (fmtHndl->stream == NULL) return FALSE;
  if (dimSeek(fmtHndl, 0, SEEK_SET) != 0) return FALSE;
  if ( dimRead( fmtHndl, &bmpPar->bf, 1, sizeof(TDimBITMAPFILEHEADER) ) != 
       sizeof(TDimBITMAPFILEHEADER)) return FALSE;
  
  // test if is BMP
  unsigned char *mag_num = (unsigned char *) &bmpPar->bf.bfType;
  if ( (mag_num[0] != 0x42) || (mag_num[1] != 0x4d) ) return FALSE;

  // swap structure elements if running on Big endian machine...
  if (dimBigendian) {
    dimSwapLong( (DIM_UINT32*) &bmpPar->bf.bfOffBits );
    dimSwapLong( (DIM_UINT32*) &bmpPar->bf.bfSize );
  }
 
  if ( dimRead( fmtHndl, &bmpPar->bi, 1, sizeof(TDimBITMAPINFOHEADER) ) != 
       sizeof(TDimBITMAPINFOHEADER)) return FALSE;

  // swap structure elements if running on Big endian machine...
  if (dimBigendian) {
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biSize );    
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biWidth );  
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biHeight );  
    dimSwapShort( (DIM_UINT16*) &bmpPar->bi.biPlanes );
    dimSwapShort( (DIM_UINT16*) &bmpPar->bi.biBitCount );
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biCompression );    
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biSizeImage );    
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biXPelsPerMeter );    
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biYPelsPerMeter );    
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biClrUsed );    
    dimSwapLong( (DIM_UINT32*) &bmpPar->bi.biClrImportant );    
  }

  // test for image parameters
  if ( !(bmpPar->bi.biBitCount == 1  || bmpPar->bi.biBitCount == 4  || bmpPar->bi.biBitCount == 8   || 
         bmpPar->bi.biBitCount == 16 || bmpPar->bi.biBitCount == 24 || bmpPar->bi.biBitCount == 32) ||
	       bmpPar->bi.biPlanes != 1 || bmpPar->bi.biCompression > DIM_BMP_BITFIELDS )
	return FALSE;	// weird BMP image

  if ( !(bmpPar->bi.biCompression == DIM_BMP_RGB || 
        (bmpPar->bi.biBitCount == 4 && bmpPar->bi.biCompression == DIM_BMP_RLE4) ||
	      (bmpPar->bi.biBitCount == 8 && bmpPar->bi.biCompression == DIM_BMP_RLE8) || 
        ((bmpPar->bi.biBitCount == 16 || bmpPar->bi.biBitCount == 32) && bmpPar->bi.biCompression == DIM_BMP_BITFIELDS)) )
	return FALSE;	// weird compression type

  info->width  = bmpPar->bi.biWidth;
  info->height = bmpPar->bi.biHeight;
  info->depth = 8;
  info->samples = 1;
  info->imageMode = DIM_GRAYSCALE;

  if (bmpPar->bi.biBitCount < 8) info->depth = bmpPar->bi.biBitCount;
  if (bmpPar->bi.biBitCount > 8) { info->samples = 3; info->imageMode = DIM_RGB; }
  if (bmpPar->bi.biBitCount == 32) { info->samples = 4; info->imageMode = DIM_RGBA; }



  //-------------------------------------------------
  // init palette
  //-------------------------------------------------
  DIM_UINT i;
  int num_colors = 0;
  if ( bmpPar->bi.biBitCount <= 8 )
    num_colors = bmpPar->bi.biClrUsed ? bmpPar->bi.biClrUsed : 1 << bmpPar->bi.biBitCount;  
  if (num_colors > 0) info->imageMode = DIM_INDEXED;

  info->lut.count = 0;
  for (i=0; i<256; i++) info->lut.rgba[i] = dimRGB(i, i, i);

  
  //-------------------------------------------------
  // read palette
  //-------------------------------------------------
  if (dimSeek( fmtHndl, BMP_FILEHDR_SIZE + bmpPar->bi.biSize, SEEK_SET ) != 0) return FALSE;

  if ( num_colors > 0 ) // LUT is present
  {
    DIM_UCHAR rgb[4];
    info->lut.count = num_colors;
    int   rgb_len = bmpPar->bi.biSize == DIM_BMP_OLD ? 3 : 4;
    for ( i=0; i<(DIM_UINT)num_colors; i++ ) 
    {
      if ( dimRead( fmtHndl, (char *)rgb, 1, rgb_len ) != (unsigned int) rgb_len ) return FALSE;
      info->lut.rgba[i] = dimRGB( rgb[2], rgb[1], rgb[0] );
    }

  } 
   
  return TRUE;
}

//****************************************************************************
//
// FORMAT DEMANDED FUNTIONS
//
//****************************************************************************


//----------------------------------------------------------------------------
// PARAMETERS, INITS
//----------------------------------------------------------------------------

DIM_INT dimBmpValidateFormatProc (DIM_MAGIC_STREAM *magic, DIM_UINT length)
{
  if (length < 2) return -1;
  unsigned char *mag_num = (unsigned char *) magic;
  if ( (mag_num[0] == 0x42) && (mag_num[1] == 0x4d) ) return 0;
  return -1;
}

TDimFormatHandle dimBmpAquireFormatProc( void )
{
  TDimFormatHandle fp = initTDimFormatHandle();
  return fp;
}

void dimBmpReleaseFormatProc (TDimFormatHandle *fmtHndl)
{
  if (fmtHndl == NULL) return;
  dimBmpCloseImageProc ( fmtHndl );  
}


//----------------------------------------------------------------------------
// OPEN/CLOSE
//----------------------------------------------------------------------------
void dimBmpCloseImageProc (TDimFormatHandle *fmtHndl)
{
  if (fmtHndl == NULL) return;
  dimClose ( fmtHndl );
  dimFree ( &fmtHndl->internalParams );
}

DIM_UINT dimBmpOpenImageProc  (TDimFormatHandle *fmtHndl, DIM_ImageIOModes io_mode)
{
  if (fmtHndl == NULL) return 1;
  if (fmtHndl->internalParams != NULL) dimBmpCloseImageProc (fmtHndl);  
  fmtHndl->internalParams = (void *) new TDimBmpParams [1];
  //TDimBmpParams *bmpPar = (TDimBmpParams *) fmtHndl->internalParams;

  if ( io_mode == DIM_IO_READ )
  {
    if ( isCustomReading ( fmtHndl ) != TRUE )
      fmtHndl->stream = /*(void *)*/ fopen( fmtHndl->fileName, "rb" );
    
    if (fmtHndl->stream == NULL) { dimBmpCloseImageProc (fmtHndl); return 1; };
    if ( !bmpGetImageInfo( fmtHndl ) ) { dimBmpCloseImageProc (fmtHndl); return 1; };
  }

  if ( io_mode == DIM_IO_WRITE )
  {
    if ( isCustomWriting ( fmtHndl ) != TRUE )
      fmtHndl->stream = /*(void *)*/ fopen( fmtHndl->fileName, "wb" );
    if (fmtHndl->stream == NULL) { dimBmpCloseImageProc (fmtHndl); return 1; };
  }

  return 0;
}


DIM_UINT dimBmpFOpenImageProc (TDimFormatHandle *fmtHndl, char* fileName, DIM_ImageIOModes io_mode)
{
  fmtHndl->fileName = fileName;
  return dimBmpOpenImageProc(fmtHndl, io_mode);
}

DIM_UINT dimBmpIOpenImageProc (TDimFormatHandle *fmtHndl, char* fileName, 
                                         DIM_IMAGE_CLASS *image, DIM_ImageIOModes io_mode)
{
  fmtHndl->fileName = fileName;
  fmtHndl->image    = image;
  return dimBmpOpenImageProc(fmtHndl, io_mode);
}


//----------------------------------------------------------------------------
// INFO for OPEN image
//----------------------------------------------------------------------------

DIM_UINT dimBmpGetNumPagesProc ( TDimFormatHandle *fmtHndl )
{
  if (fmtHndl == NULL) return 0;
  if (fmtHndl->internalParams == NULL) return 0;

  return 1;
}


TDimImageInfo dimBmpGetImageInfoProc ( TDimFormatHandle *fmtHndl, DIM_UINT page_num )
{
  TDimImageInfo ii = initTDimImageInfo();
  page_num;

  if (fmtHndl == NULL) return ii;
  TDimBmpParams *bmpPar = (TDimBmpParams *) fmtHndl->internalParams;

  return bmpPar->i;
}

//----------------------------------------------------------------------------
// METADATA
//----------------------------------------------------------------------------

DIM_UINT dimBmpAddMetaDataProc (TDimFormatHandle *fmtHndl)
{
  fmtHndl=fmtHndl;
  return 1;
}


DIM_UINT dimBmpReadMetaDataProc (TDimFormatHandle *fmtHndl, DIM_UINT page, int group, int tag, int type)
{
  fmtHndl; page; group; tag; type;
  return 1;
}

char* dimBmpReadMetaDataAsTextProc ( TDimFormatHandle *fmtHndl )
{
  fmtHndl;
  return NULL;
}


//----------------------------------------------------------------------------
// READ/WRITE
//----------------------------------------------------------------------------

DIM_UINT dimBmpReadImageProc  ( TDimFormatHandle *fmtHndl, DIM_UINT page )
{
  if (fmtHndl == NULL) return 1;
  if (fmtHndl->stream == NULL) return 1;

  fmtHndl->pageNumber = page;
  return read_bmp_image( fmtHndl );
}

DIM_UINT dimBmpWriteImageProc ( TDimFormatHandle *fmtHndl )
{
  if (fmtHndl == NULL) return 1;
  if (fmtHndl->stream == NULL) return 1;
  return write_bmp_image( fmtHndl );
}

//****************************************************************************
//
// EXPORTED FUNCTION
//
//****************************************************************************

TDimFormatItem dimBmpItems[1] = {
{
    "BMP",            // short name, no spaces
    "Windows Bitmap", // Long format name
    "bmp",        // pipe "|" separated supported extension list
    1, //canRead;      // 0 - NO, 1 - YES
    1, //canWrite;     // 0 - NO, 1 - YES
    0, //canReadMeta;  // 0 - NO, 1 - YES
    0, //canWriteMeta; // 0 - NO, 1 - YES
    0, //canWriteMultiPage;   // 0 - NO, 1 - YES
    //TDivFormatConstrains constrains ( w, h, pages, minsampl, maxsampl, minbitsampl, maxbitsampl, noLut )
    { 0, 0, 1, 1, 4, 1, 8, 0 } 
  }  
};

TDimFormatHeader dimBmpHeader = {

  sizeof(TDimFormatHeader),
  "1.0.0",
  "DIMIN BMP CODEC",
  "BMP CODEC",
  
  2,                     // 0 or more, specify number of bytes needed to identify the file
  {1, 1, dimBmpItems},   // dimJpegSupported,
  
  dimBmpValidateFormatProc,
  // begin
  dimBmpAquireFormatProc, //TDimAquireFormatProc
  // end
  dimBmpReleaseFormatProc, //TDimReleaseFormatProc
  
  // params
  NULL, //TDimAquireIntParamsProc
  NULL, //TDimLoadFormatParamsProc
  NULL, //TDimStoreFormatParamsProc

  // image begin
  dimBmpOpenImageProc, //TDimOpenImageProc
  dimBmpCloseImageProc, //TDimCloseImageProc 

  // info
  dimBmpGetNumPagesProc, //TDimGetNumPagesProc
  dimBmpGetImageInfoProc, //TDimGetImageInfoProc


  // read/write
  dimBmpReadImageProc, //TDimReadImageProc 
  dimBmpWriteImageProc, //TDimWriteImageProc
  NULL, //TDimReadImageTileProc
  NULL, //TDimWriteImageTileProc
  NULL, //TDimReadImageLineProc
  NULL, //TDimWriteImageLineProc
  NULL, //TDimReadImageThumbProc
  NULL, //TDimWriteImageThumbProc
  NULL, //dimJpegReadImagePreviewProc, //TDimReadImagePreviewProc
  
  // meta data
  dimBmpReadMetaDataProc, //TDimReadMetaDataProc
  dimBmpAddMetaDataProc,  //TDimAddMetaDataProc
  dimBmpReadMetaDataAsTextProc, //TDimReadMetaDataAsTextProc

  NULL,
  NULL,
  NULL,
  ""

};

extern "C" {

TDimFormatHeader* dimBmpGetFormatHeader(void)
{
  return &dimBmpHeader;
}

} // extern C


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -