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

📄 jzimagebmp.cpp

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 CPP
字号:
// JzImageBmp.cpp: implementation of the CJzImageBmp class.
//
//////////////////////////////////////////////////////////////////////

#include "JzImageBmp.h"
#include "JzImageInfo.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CJzImageBmp::CJzImageBmp()
{

}

CJzImageBmp::~CJzImageBmp()
{

} 
bool CJzImageBmp::Decode(CxFile * mhFile)
{
	hFile = mhFile;
	if (hFile == NULL) return false;
	dwCompression=bmpHeader.biCompression;
	DWORD dwBitCount;
	off = hFile->Tell(); //<CSC>
	pRgb = NULL;
    if (hFile->Read(&bf,min(14,sizeof(bf)),1)==0) 
    {
    		printf("Not a BMP!");
    		goto EXIT;
    }
    if (bf.bfType != BFT_BITMAP) { //do we have a RC HEADER?
        bf.bfOffBits = 0L;
        hFile->Seek(off,SEEK_SET);
    }

	if (!DibReadBitmapInfo(hFile,&bmpHeader)) 
	{
		 printf("Error reading BMP info!\n");
		 goto EXIT;
	}
	bTopDownDib = bmpHeader.biHeight<0; //<Flanders> check if it's a top-down bitmap
	dwCompression=bmpHeader.biCompression;
	
	dwBitCount=bmpHeader.biBitCount; //preserve for BI_BITFIELDS compression <Thomas Ernst>
	bIsOldBmp = bmpHeader.biSize == sizeof(BITMAPCOREHEADER);

	
	if (info.nEscape == -1) {
		// Return output dimensions only
		info.dwWidth = bmpHeader.biWidth;
		info.dwHeight = bmpHeader.biHeight;
		printf("output dimensions returned");
		goto EXIT;
	}
	
	if (bTopDownDib) bmpHeader.biHeight=-bmpHeader.biHeight;

        printf(" =================  bmpHeader.biBitCount: %d ============\n", bmpHeader.biBitCount);
    {    
        IVSETIMAGEINFO ivSetImageInfo = ivGetImageInfoCallback();
        if( ivSetImageInfo )
        {
            IVIMAGEINFO ImageInfo;

            ImageInfo.w = bmpHeader.biWidth;
            ImageInfo.h = bmpHeader.biHeight;
            ImageInfo.bpp = bmpHeader.biBitCount;

            ivSetImageInfo( &ImageInfo );

            info.dwimaWidth = ImageInfo.w;
            info.dwimaHeight = ImageInfo.h;
            info.pImage = ImageInfo.pImage;
            ivscale = ImageInfo.ivscale;
            if( info.pImage == NULL ) return FALSE;
        }
   }        

        if( bmpHeader.biBitCount < 16 ) return FALSE;
        printf("bmpHeader.biWidth,bmpHeader.biHeight= %d, %d \n",bmpHeader.biWidth,bmpHeader.biHeight);	
	if (!CreateImageInfo(bmpHeader.biWidth,bmpHeader.biHeight,bmpHeader.biBitCount,CXIMAGE_FORMAT_BMP))
	{
			printf("Can't allocate memory!");
			goto EXIT;
	}
	if (info.nEscape)
	{ 
		printf("Cancelled!\n"); // <vho> - cancel decoding
    goto EXIT;
  }  
  if(bmpHeader.biBitCount <= 8)
	  if(bIsOldBmp)
		pRgb = new RGBQUAD[DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE)];
      else
        pRgb = new RGBQUAD[DibNumColors(&bmpHeader) * sizeof(RGBQUAD)];
  if (pRgb){
        if (bIsOldBmp){
             // convert a old color table (3 byte entries) to a new
             // color table (4 byte entries)
            hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1);
            } else {
            hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1);
			//force rgbReserved=0, to avoid problems with some WinXp bitmaps
        }
    }

	if (info.nEscape){
		 printf("Cancelled\n"); // <vho> - cancel decoding
     goto EXIT;
  }

   switch (dwBitCount) {
		case 32 :
			if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
			if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB){
				if(!Read32BPPData(dwBitCount,0))
					goto EXIT;
				
			} else
				{
					 printf("unknown compression\n");
					 goto EXIT;
				}
			break;
		case 24 :
			if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
			if (dwCompression == BI_RGB){
				if(!Read32BPPData(dwBitCount,0))
                                 {
                                        printf(" exit bmp\n");
					goto EXIT;
                                 }
			} else 
				printf("unknown compression\n");
			break;
		case 16 :
		{
			DWORD bfmask[3];
			if (dwCompression == BI_BITFIELDS)
			{
				hFile->Read(bfmask, 12, 1);
			} else {
				bfmask[0]=0x7C00; bfmask[1]=0x3E0; bfmask[2]=0x1F; //RGB555
			}
			// bf.bfOffBits required after the bitfield mask <Cui Ying Jie>
			if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
			// read in the pixels
			if(!Read32BPPData(dwBitCount,(unsigned int *)bfmask))
					goto EXIT;
			break;
		}

		case 8 :
		case 4 :
		case 1 :
                    return false;
		if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
		switch (dwCompression) {
			case BI_RGB :
				if(!Read4BPPData(dwBitCount))
					goto EXIT; // read in the pixels
				break;
			default :								
			{
				  
					printf("compression type not supported\n");
					goto EXIT;
			}
		}
	}

  if(pRgb)
  	delete[] pRgb;
  return true;
EXIT:	
	
	if (info.nEscape==-1) return true;
	return false;
}
////////////////////////////////////////////////////////////////////////////////
/*  ReadDibBitmapInfo()
 *
 *  Will read a file in DIB format and return a global HANDLE to its
 *  BITMAPINFO.  This function will work with both "old" and "new"
 *  bitmap formats, but will always return a "new" BITMAPINFO.
 */
bool CJzImageBmp::DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib)
{
	if ((fh==NULL)||(pdib==NULL)) return false;

    if (fh->Read(pdib,sizeof(BITMAPINFOHEADER),1)==0) return false;

    BITMAPCOREHEADER   bc;

    switch (pdib->biSize) // what type of bitmap info is this?
    {
        case sizeof(BITMAPINFOHEADER):
            break;

		case 64: //sizeof(OS2_BMP_HEADER):
            fh->Seek((long)(64 - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
			break;

        case sizeof(BITMAPCOREHEADER):
            bc = *(BITMAPCOREHEADER*)pdib;
            pdib->biSize               = bc.bcSize;
            pdib->biWidth              = (DWORD)bc.bcWidth;
            pdib->biHeight             = (DWORD)bc.bcHeight;
            pdib->biPlanes             =  bc.bcPlanes;
            pdib->biBitCount           =  bc.bcBitCount;
            pdib->biCompression        = BI_RGB;
            pdib->biSizeImage          = 0;
            pdib->biXPelsPerMeter      = 0;
            pdib->biYPelsPerMeter      = 0;
            pdib->biClrUsed            = 0;
            pdib->biClrImportant       = 0;

			fh->Seek((long)(sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER)), SEEK_CUR);

            break;
        default:
			//give a last chance
			 if (pdib->biSize > (sizeof(BITMAPINFOHEADER))&&
				(pdib->biSizeImage==(unsigned long)(pdib->biHeight*((((pdib->biBitCount*pdib->biWidth)+31)/32)*4)))&&
				(pdib->biPlanes==1)&&(pdib->biCompression==BI_RGB)&&(pdib->biClrUsed==0))
			 {
	             fh->Seek((long)(pdib->biSize - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
				 break;
			 }
			return false;
    }

    FixBitmapInfo(pdib);

    return true;
}

#if 1
bool CJzImageBmp::Read32BPPData(unsigned int wBpp,unsigned int *mask)
{
    DWORD i, j;
    RGBQUAD c;

    int dx, dy, direction = 0;
    BYTE *src = NULL;
    //info.dwEffWidth = pScr->w*4;
    printf(" ======== wBpp: %d\n", wBpp );
    unsigned int byte = wBpp / 8;
    //long imagesize=info.dwEffWidth;
    long imagesize=((((wBpp * bmpHeader.biWidth) + 31) / 32) * 4);
    printf(" ========== imagesize: %d\n", imagesize );
    BYTE* psrc= (BYTE*)malloc(imagesize);

    info.dwEffWidth = info.dwimaWidth*4;

    //ivscale = (int)( ((float)info.dwimaWidth/bmpHeader.biWidth)*128.0+1 );
    //if( ivscale > 128 ) ivscale = 128;

    BYTE *line = info.pImage+info.dwimaWidth*(info.dwimaHeight - 1)*4;
    //unsigned int *ptar = pScr->buffer;//for test
    //ptar += pScr->w * (info.dwimaHeight - 1);
   
    printf("cpp ============info.dwimaWidth: %d, info.dwimaHeight: %d\n", info.dwimaWidth, info.dwimaHeight );
    dy = 0;
    for( j = 0; j < info.dwimaHeight; j++ )
    {
        memset( line, 0, info.dwEffWidth );

        while( ivscale*dy/128 <= j )
        {
            if(!hFile->Read(psrc, imagesize, 1))
            {
                 printf("11Read File Error!");
                 //return false;
            }

            dy++;
        }

        //////////// row
        dx = 0;

        for( i = 0; i < info.dwimaWidth; i++ )
        {
            while( ivscale*dx/128 < i ) dx++;
            Bitfield2BPP(wBpp,mask,&psrc[dx * byte],&c);
            line[i * 4 + 2] = (unsigned int) c.rgbBlue;
            line[i * 4 + 1] = (unsigned int) c.rgbGreen;
            line[i * 4 + 0] = (unsigned int) c.rgbRed;

        }
        ///////////

        //memcpy( (void *)ptar, line, info.dwEffWidth );
        //ptar -= pScr->w;
        //line = line + info.dwimaWidth*4;
        line = line - info.dwimaWidth*4;


    }
    //test
    free(psrc);
    return true;
}

#endif

#if 0         

bool CJzImageBmp::Read32BPPData(unsigned int wBpp,unsigned int *mask)
{
  long imagesize=info.dwEffWidth;
        BYTE* psrc= (BYTE*)malloc(imagesize);
        DWORD *xtotal,ytotal;
        xtotal = (DWORD *)malloc( sizeof(DWORD) *info.dwimaWidth);
        unsigned int *line = (unsigned int *)malloc(info.dwimaWidth * 3 * sizeof(unsigned int));
        int dx,dy;
        unsigned int *ptar = pScr->buffer;
        ptar += pScr->w * (info.dwimaHeight - 1);
        dy = 0;
        unsigned int byte = wBpp / 8;
        for(DWORD i = 0;i < info.dwimaHeight ;i++)
        {
                ytotal = 0;
                memset(line,0,sizeof(unsigned int) * info.dwimaWidth * 3);
                while((DWORD)((float)dy * fyscale) == i)
                {
                        if(!hFile->Read(psrc, imagesize, 1))
                        {
                                printf("Read File Error!");
                                return false;
                        }

                        dx = 0;
                        for(DWORD j = 0; j < info.dwimaWidth; j++)
                        {
                                xtotal[j] = 0;
                                while((DWORD)((float)dx  * fxscale) == j)
                                {
                                  RGBQUAD c;
                                        Bitfield2BPP(wBpp,mask,&psrc[dx * byte],&c);

                                        line[j * 3 + 0] += (unsigned int) c.rgbBlue;
                                        line[j * 3 + 1] += (unsigned int) c.rgbGreen;
                                        line[j * 3 + 2] += (unsigned int) c.rgbRed;

                                        xtotal[j]++;
                                        dx++;
                                }
                        }
                        dy++;

                        ytotal++;

                }
                  
                for(DWORD j = 0;j < info.dwimaWidth;j++)
                {
                        int av = xtotal[j] * ytotal;
                        if(av == 0) av = 1;
                        ptar[j] = SETRGB(line[j * 3 + 0] / av, line[j * 3 + 1] / av,line[j * 3 + 2] / av);
                }
          ptar -= pScr->w;


        }
        free(psrc);
        free(xtotal);
        free(line);

        return true;
}

#endif


#if 1
bool CJzImageBmp::Read4BPPData(unsigned int wBpp)
{
	long imagesize=info.dwEffWidth;
	BYTE* psrc= (BYTE*)malloc(imagesize);
	DWORD *xtotal,ytotal;
	xtotal = (DWORD *)malloc( sizeof(DWORD) *info.dwimaWidth);
	unsigned int *line = (unsigned int *)malloc(info.dwimaWidth * 3 * sizeof(unsigned int));
	int dx,dy;
	unsigned int *ptar = pScr->buffer;
	ptar += pScr->w * (info.dwimaHeight - 1);
	dy = 0;
	unsigned char bi = 8 / wBpp;
					

	for(DWORD i = 0;i < info.dwimaHeight ;i++)
	{	
		ytotal = 0;
		memset(line,0,sizeof(unsigned int) * info.dwimaWidth * 3); 
		while((DWORD)((float)dy * fyscale) == i)
		{
			if(!hFile->Read(psrc, imagesize, 1))
			{
				printf("Read File Error!");
				return false;
			}
			
			dx = 0;
			DWORD n = 0;
			unsigned char d;
			for(DWORD j = 0; j < info.dwimaWidth; j++)
			{
				xtotal[j] = 0;
				while((DWORD)((float)dx  * fxscale) == j)
				{
					if(dx % bi == 0)
				      d = psrc[dx / bi];
					RGBQUAD c;
					Bitfield2BPP(wBpp,0,&d,&c);
				   	   
					line[j * 3 + 0] += (unsigned int) c.rgbBlue;
					line[j * 3 + 1] += (unsigned int) c.rgbGreen;
					line[j * 3 + 2] += (unsigned int) c.rgbRed;
					d = d >> wBpp;
					xtotal[j]++;
					dx++;
				}
			}
			dy++;

			ytotal++;
			
		}

		for(DWORD j = 0;j < info.dwimaWidth;j++)
		{
			int av = xtotal[j] * ytotal;
			if(av == 0) av = 1;
			
			ptar[j] = SETRGB(line[j * 3 + 0] / av, line[j * 3 + 1] / av,line[j * 3 + 2] / av); 
		}
	  ptar -= pScr->w; 
	  

	}
	free(psrc);
	free(xtotal);
	free(line);
				
	return true;
}

#endif

⌨️ 快捷键说明

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