Пример #1
0
LPPALETTE ReadPalette( LPSTR lpFileName, BOOL bCombine )
/************************************************************************/
{
    int ifh;		/* file handle( unbuffered) */
    FILEBUF ifd;		/* file descriptor( buffered) */
    short i, iColors;
    VERSIONINFO version;
    RECINFO rec;
    LPTR lpByte;
    LPWORD lpWord;
    LPLONG lpLong;
    BYTE Previous;
    BOOL bError;
    FNAME szName;
    LPPALETTE lpHeadPalette, lpPalette, lpBigPalette;

    /* open the palette file */
    if ( ( ifh = _lopen( lpFileName, OF_READ)) < 0 )
    {
        Message( IDS_EOPEN, lpFileName);
        return( NULL );
    }

    /* create a buffered stream to speed access */
    FileFDOpenRdr( &ifd, ifh, (LPTR)LineBuffer[0], 16*1024);

// read palette version
    version.Length = sizeof(version.Number);
    version.Type = PALFILE_VERSION;
    FileRead(&ifd, (LPTR)&version, sizeof(version));
#ifdef _MAC
    swapw(&version.Length);
    swapw(&version.Number);
#endif
    if (ifd.err ||
            version.Type != PALFILE_VERSION ||
            version.Length != sizeof(version.Number) ||
            version.Number > CURRENT_VERSION)
    {
        Message(IDS_INVALIDPALETTE, lpFileName);
        _lclose(ifh);
        return(NULL);
    }
    rec.Type = 0;
    lpHeadPalette = NULL;
    lpPalette = NULL;
    bError = NO;
    while (!bError && !ifd.err && rec.Type != PALFILE_END)
    {
        Previous = rec.Type;
        FileRead(&ifd, (LPTR)&rec, sizeof(RECINFO));
#ifdef _MAC
        swapw(&rec.Length);
#endif
        if (ifd.err)
            break;
        switch (rec.Type)
        {
        case PALFILE_VERSION:
            bError = YES;
            break;
        case PALFILE_COUNT:
            lpByte = Alloc((long)rec.Length);
            FileRead(&ifd, lpByte, rec.Length);
            FreeUp(lpByte);
            break;
        case PALFILE_COLORS:
            if (!lpPalette)
            {
                bError = YES;
                break;
            }
            lpWord = (LPWORD)Alloc((long)rec.Length);
            if (!lpWord)
            {
                Message (IDS_EMEMALLOC);
                bError = YES;
                break;
            }
            FileRead(&ifd, (LPTR)lpWord, rec.Length);
            if (ifd.err)
            {
                FreeUp((LPTR)lpWord);
                break;
            }
#ifdef _MAC
            swapw(lpWord);
#endif
            iColors = *lpWord;
            if ((iColors * sizeof(COLOR) + sizeof(WORD)) != rec.Length)
            {
                FreeUp((LPTR)lpWord);
                bError = YES;
                break;
            }
            lpPalette->iColors = iColors;
            if (!iColors)
            {
                FreeUp((LPTR)lpWord);
                break;
            }
            lpLong = (LPLONG)(lpWord+1);
            lpPalette->lpColorInfo =
                (LPCOLORINFO)Alloc((long)(sizeof(COLORINFO)*iColors));
            if (!lpPalette->lpColorInfo)
            {
                Message(IDS_EMEMALLOC);
                FreeUp((LPTR)lpWord);
                bError = YES;
                break;
            }
            for (i = 0; i < iColors; ++i)
            {
                LPVOID lp = &lpPalette->lpColorInfo[i].rgb;

#ifdef _MAC
                swapl((LPDWORD)lp);
#endif

                CopyRGB(lpLong+i, lp);
                SetColorInfo(
                    &lpPalette->lpColorInfo[i],
                    &lpPalette->lpColorInfo[i],
                    CS_RGB);
            }

            FreeUp((LPTR)lpWord);
            break;
        case PALFILE_NAME:
            if (Previous == PALFILE_NAME)
            {
                bError = YES;
                break;
            }
            if (lpPalette)
            {
                lpHeadPalette = LinkPalette(lpHeadPalette, lpPalette);
                lpPalette = NULL;
            }
            rec.Length = bound(rec.Length, 0, MAX_FNAME_LEN);
            FileRead(&ifd, (LPTR)szName, rec.Length);
            if (ifd.err)
                break;
            lpPalette = NewPalette(szName);
            if (!lpPalette)
            {
                Message (IDS_EMEMALLOC);
                bError = YES;
                break;
            }
            break;
        case PALFILE_GROUP:
            if (!lpPalette || (rec.Length != sizeof(lpPalette->dwGroup)))
            {
                bError = YES;
                break;
            }
            FileRead(&ifd, (LPTR)&lpPalette->dwGroup, rec.Length);
#ifdef _MAC
            swapl((LPDWORD)(&lpPalette->dwGroup));
#endif
            break;
        case PALFILE_LABELS:
            if (!lpPalette)
            {
                bError = YES;
                break;
            }
            lpPalette->lpLabels = Alloc((long)rec.Length);
            if (!lpPalette->lpLabels)
            {
                Message (IDS_EMEMALLOC);
                bError = YES;
                break;
            }
            lpPalette->LabelsLength = rec.Length;
            FileRead(&ifd, lpPalette->lpLabels, rec.Length);
            break;
        case PALFILE_FORMAT:
            if (!lpPalette || (rec.Length > MAX_STR_LEN))
            {
                bError = YES;
                break;
            }
            FileRead(&ifd, (LPTR)lpPalette->szFormat, rec.Length);
            break;
        case PALFILE_END:
            if (lpPalette)
            {
                lpHeadPalette = LinkPalette(lpHeadPalette, lpPalette);
                lpPalette = NULL;
            }
            break;
        default:
            bError = YES;
            break;
        }
    }
    _lclose(ifh);
    if (lpPalette)
    {
        if (lpPalette->lpColorInfo)
            FreeUp((LPTR)lpPalette->lpColorInfo);
        if (lpPalette->lpLabels)
            FreeUp((LPTR)lpPalette->lpLabels);
        FreeUp((LPTR)lpPalette);
    }
    if (ifd.err || bError || rec.Type != PALFILE_END || lpPalette)
    {
        Message(IDS_INVALIDPALETTE, lpFileName);
        FreeUpPalette(lpHeadPalette);
        return(NULL);
    }

    if ( !bCombine || !lpHeadPalette )
        return( lpHeadPalette );

    if ( !(lpBigPalette = CombinePalettes(lpHeadPalette)) )
        Message (IDS_EMEMALLOC);
    FreeUpPalette(lpHeadPalette);
    return( lpBigPalette );
}
Пример #2
0
BOOL CReadBitmap::GIFRead()
/************************************************************************/
{
    GIFHDR		   hdr;
    GIFDESC		   ImDesc;
    GIFMAP		   GlobalMap;
    GIFMAP		   LocalMap;
    BYTE		      cTemp;
    LPTR		      lpFileLine, lpLineBuffer, lpOut;
    LPFRAME		   lpFrame;
    FILEBUF		   ifd;		/* file descriptor (buffered) */
    BOOL		      graymap;
    int			   i;
    int			   sy;
    int			   xres;		/* pixels per inch */
    int			   npix;		/* image width (pixels) */
    int			   nlin;		/* image height (pixels) */
    BYTE		      codeSize;
    int			   iCodeSize;
    int			   iRowMapIndex;
    BOOL		      compressInit;
    LPLZW_STUFF   lpLZW;
	FRMTYPEINFO inType, outType;
	LPCOLORMAP lpColorMap;
	CFrameTypeConvert TypeConvert;
	CFile 	theFile;
	CFile*	pTheFile;
	BOOL	fRet = FALSE;

	ProgressBegin(1);
	if ((pTheFile = OpenFile()) == NULL)
	{
		ProgressEnd();
		return(FALSE);
	}

	TRY
	{
    	lpFileLine = NULL;
    	lpFrame = NULL;
    	lpLineBuffer = NULL;
    	compressInit = NO;
		lpColorMap = NULL;

    	if (!(lpLineBuffer = Alloc (BUF_SIZE)))
	      	goto Exit;

    	FileFDOpenRdr (&ifd, pTheFile, lpLineBuffer, BUF_SIZE);

		/* initialize the Global and local color maps */
    	gifInitColorMap (&GlobalMap);
    	gifInitColorMap (&LocalMap);

		/* read gif file header */
    	if (gifReadHeader (&ifd, &hdr))
		goto BadRead;

		/* get global color map, if any */
    	if (hdr.GlobalMap) {
		if (gifReadColorMap (&ifd, hdr.bpp, &GlobalMap))
	    	goto BadRead;
    	}
		
		/* look for start of image */
    	while (1) {
		FileFDRead (&ifd, (LPTR) &cTemp, 1);
		if (ifd.err)
	    	goto BadRead;

    	/* test for image separator character */
		if (cTemp == GIFImSep)
	    	break;

    	/* test for terminator character (no image blocks in file?) */
		if (cTemp == GIFImSep)
	    	goto BadRead;

    	/* test for extension block character */
		if (cTemp == GIFExtBlk) {

		/* Skip over the extension block */

		/* read function code */
	    	FileFDRead (&ifd, (LPTR) &cTemp, 1);

	    	do {
	    	/* read byte count */
			FileFDRead (&ifd, (LPTR) &cTemp, 1);

	    	/* skip data bytes */
			if (cTemp)
		    	FileFDSeek (&ifd, (long) cTemp, 1);
	    	} while (cTemp);
		}
    	}

	/* now at the start of the first image */
    	if (gifReadImDesc (&ifd, &ImDesc))
		goto BadRead;

	/* read local color map, if any */
    	if (ImDesc.LocalMap) {
		if (gifReadColorMap (&ifd, ImDesc.bpp, &LocalMap))
	    	goto BadRead;
    	}
    	else {
		LocalMap = GlobalMap;
		ImDesc.bpp = hdr.bpp;
    	}

	/* check for gray map */
    	graymap = TRUE;
    	for (i = 0; (i < LocalMap.Length) && graymap; i++)
		graymap = (LocalMap.Map[i].red == LocalMap.Map[i].green)
		    	&& (LocalMap.Map[i].red == LocalMap.Map[i].blue);

		lpColorMap = FrameCreateColorMap();
		if (!lpColorMap)
		{
			SetError(BEC_errMemory);
			goto Exit;
		}
		lpColorMap->NumEntries = LocalMap.Length;
		for (i = 0; i < LocalMap.Length; ++i)
			lpColorMap->RGBData[i] = LocalMap.Map[i];


	/* get width of image in pixels */
    	npix = ImDesc.ImWidth;
    	nlin = ImDesc.ImHeight;
    	xres = 75;

		if (hdr.bpp == 1)
			FrameSetTypeInfo(&inType, FDT_LINEART);
		else
			FrameSetTypeInfo(&inType, FDT_PALETTECOLOR, lpColorMap);

		if (!SetupTypes(&inType, &outType, graymap))
			goto Exit;

		FrameSetTypeInfo(&inType, FDT_PALETTECOLOR, lpColorMap);

		if (!TypeConvert.Init(inType, outType, npix, m_DitherType))
		{			   
			SetError(BEC_errMemory);
			goto Exit;	
		}

	/* allocate space for one line of the image (file) */
    	if ( !AllocLines (&lpFileLine, 1, npix, 1)) {
		SetError(BEC_errMemory);
		goto BadWrite;
    	}

	/* Create the image frame store */
    	lpFrame = FrameOpen(outType, npix, nlin, xres);
    	if ( !lpFrame ) {
		SetError(BEC_errFrameOpen);
		goto Exit;
    	}

	/* convert the image */
    	if (FileFDRead (&ifd, &codeSize, 1) == -1)
		goto BadRead;

    	iCodeSize = codeSize;

    	if (FileFDSeek (&ifd, 0L, 1) == -1)
		goto BadRead;

    	if ( !( lpLZW = DecompressLZW_GIF (ifd.pFile, NULL, 0, iCodeSize, NULL)))
		goto BadRead;
    	compressInit = YES;
    	if (ImDesc.Interlaced)
		iRowMapIndex = 1;
    	else
		iRowMapIndex = 0;

		sy = gifRowMap [iRowMapIndex].first;
		for (i = 0; i < nlin; i++)
		{
			if (Progress (i, nlin, YES))
				goto Exit;
			if (!(DecompressLZW_GIF (ifd.pFile, lpFileLine, npix, iCodeSize, lpLZW)))
				goto BadRead;
			if ( !(lpOut = FramePointerRaw(lpFrame, 0, sy, YES)) )
				goto BadWrite;
			TypeConvert.ConvertData(lpFileLine, lpOut, sy, npix);
			sy += gifRowMap [iRowMapIndex].step;
			if (sy >= ImDesc.ImHeight)
			{
	    		iRowMapIndex++;
		    	sy = gifRowMap [iRowMapIndex].first;
			}
		}

		m_iWidth = npix;
		m_iHeight = nlin;
		m_iRes = xres;
		m_lpFrame = lpFrame;
		fRet = TRUE;
		goto Exit;
	}
	CATCH_ALL(e)
	{
		goto BadRead;
	}
	END_CATCH_ALL

	ProgressEnd();
	return (TRUE);

BadRead:
	SetError(BEC_errFileRead);
    goto Exit;

BadWrite:
	SetError(BEC_errFrameRead);

Exit:
    if (compressInit)
 	   DecompressLZW_GIF (ifd.pFile, NULL, 0, iCodeSize, lpLZW);
    compressInit = NO;
    if ( lpFileLine )
	FreeUp( lpFileLine );
    if ( lpLineBuffer )
	FreeUp (lpLineBuffer);
	if ( lpColorMap )
		FrameDestroyColorMap(lpColorMap);
	CloseFile(pTheFile);

	if (!fRet && lpFrame)
		FrameClose(lpFrame);

	ProgressEnd();
    return(fRet);
}