示例#1
0
static int DGifGetLine(GifFileType * GifFile, GifPixelType * Line, int LineLen)
{
	GifByteType *Dummy;
	GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

	if (!IS_READABLE(Private))
	{
		_GifError = D_GIF_ERR_NOT_READABLE;
		return GIF_ERROR;
	}

	if (!LineLen)
		LineLen = GifFile->Image.Width;

	if ((Private->PixelCount -= LineLen) > 0xffff0000UL)
	{
		_GifError = D_GIF_ERR_DATA_TOO_BIG;
		return GIF_ERROR;
	}

	if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK)
	{
		if (Private->PixelCount == 0)
		{
			do
				if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
					return GIF_ERROR; while (Dummy != NULL);
		}
		return GIF_OK;
	}
	else
		return GIF_ERROR;
}
示例#2
0
文件: dgif_lib.c 项目: 9miao/CrossApp
/******************************************************************************
 Put one pixel (Pixel) into GIF file.
******************************************************************************/
int
DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
{
    GifByteType *Dummy;
    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
        /* This file was NOT open for reading: */
        GifFile->Error = D_GIF_ERR_NOT_READABLE;
        return GIF_ERROR;
    }
    if (--Private->PixelCount > 0xffff0000UL)
    {
        GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
        return GIF_ERROR;
    }

    if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
        if (Private->PixelCount == 0) {
            /* We probably won't be called any more, so let's clean up
             * everything before we return: need to flush out all the
             * rest of image until an empty block (size 0)
             * detected. We use GetCodeNext.
	     */
            do
                if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
                    return GIF_ERROR;
            while (Dummy != NULL) ;
        }
        return GIF_OK;
    } else
        return GIF_ERROR;
}
示例#3
0
文件: dgif_lib.c 项目: 9miao/CrossApp
/******************************************************************************
 Interface for accessing the LZ codes directly. Set Code to the real code
 (12bits), or to -1 if EOF code is returned.
******************************************************************************/
int
DGifGetLZCodes(GifFileType *GifFile, int *Code)
{
    GifByteType *CodeBlock;
    GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;

    if (!IS_READABLE(Private)) {
        /* This file was NOT open for reading: */
        GifFile->Error = D_GIF_ERR_NOT_READABLE;
        return GIF_ERROR;
    }

    if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
        return GIF_ERROR;

    if (*Code == Private->EOFCode) {
        /* Skip rest of codes (hopefully only NULL terminating block): */
        do {
            if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
                return GIF_ERROR;
        } while (CodeBlock != NULL) ;

        *Code = -1;
    } else if (*Code == Private->ClearCode) {
        /* We need to start over again: */
        Private->RunningCode = Private->EOFCode + 1;
        Private->RunningBits = Private->BitsPerPixel + 1;
        Private->MaxCode1 = 1 << Private->RunningBits;
    }

    return GIF_OK;
}
示例#4
0
文件: ungif.c 项目: hoangduit/reactos
/******************************************************************************
 * Get one full scanned line (Line) of length LineLen from GIF file.
 *****************************************************************************/
static int
DGifGetLine(GifFileType * GifFile,
            GifPixelType * Line,
            int LineLen) {

    GifByteType *Dummy;
    GifFilePrivateType *Private = GifFile->Private;

    if (!LineLen)
        LineLen = GifFile->Image.Width;

    if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
        return GIF_ERROR;
    }

    if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
        if (Private->PixelCount == 0) {
            /* We probably would not be called any more, so lets clean
             * everything before we return: need to flush out all rest of
             * image until empty block (size 0) detected. We use GetCodeNext. */
            do
                if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
                    return GIF_ERROR;
            while (Dummy != NULL) ;
        }
        return GIF_OK;
    } else
        return GIF_ERROR;
}
示例#5
0
文件: gif.c 项目: scanlime/picogui
/******************************************************************************
* Put one pixel (Pixel) into GIF file.					      *
******************************************************************************/
int DGifGetPixel(GifFileType *GifFile, GifPixelType *Pixel)
{
    GifByteType *Dummy;
    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
	/* This file was NOT open for reading: */
	_GifError = D_GIF_ERR_NOT_READABLE;
	return GIF_ERROR;
    }

#if defined(__MSDOS__) || defined(__GNUC__)
    if (--Private->PixelCount > 0xffff0000UL)
#else
    if (--Private->PixelCount > 0xffff0000)
#endif /* __MSDOS__ */
    {
	_GifError = D_GIF_ERR_DATA_TOO_BIG;
	return GIF_ERROR;
    }

    if (DGifDecompressLine(GifFile, Pixel, 1) == GIF_OK) {
	if (Private->PixelCount == 0) {
	    /* We probably would not be called any more, so lets clean 	     */
	    /* everything before we return: need to flush out all rest of    */
	    /* image until empty block (size 0) detected. We use GetCodeNext.*/
	    do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
		return GIF_ERROR;
	    while (Dummy != NULL);
	}
	return GIF_OK;
    }
    else
	return GIF_ERROR;
}
示例#6
0
/******************************************************************************
*   Get the image code in compressed form.  his routine can be called if the  *
* information needed to be piped out as is. Obviously this is much faster     *
* than decoding and encoding again. This routine should be followed by calls  *
* to DGifGetCodeNext, until NULL block is returned.			      *
*   The block should NOT be freed by the user (not dynamically allocated).    *
******************************************************************************/
int DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
{
    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
	/* This file was NOT open for reading: */
	_GifError = D_GIF_ERR_NOT_READABLE;
	return GIF_ERROR;
    }

    *CodeSize = Private->BitsPerPixel;

    return DGifGetCodeNext(GifFile, CodeBlock);
}
示例#7
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	Error, NumFiles, ExtCode, CodeSize, ImageNum = 0,
	ImageNFlag = FALSE, ImageN, HelpFlag = FALSE, HasGIFOutput;
    GifRecordType RecordType;
    GifByteType *Extension, *CodeBlock;
    char **FileName = NULL, *ColorFileName, *TranslateFileName;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &SaveFlag, 
		&TranslateFlag, &TranslateFileName,
		&LoadFlag, &ColorFileName,
		&GammaFlag, &Gamma, &ImageNFlag, &ImageN,
		&HelpFlag, &NumFiles, &FileName)) != FALSE ||
		(NumFiles > 1 && !HelpFlag)) {
	if (Error)
	    GAPrintErrMsg(Error);
	else if (NumFiles > 1)
	    GIF_MESSAGE("Error in command line parsing - one GIF file please.");
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

    if (HelpFlag) {
	fprintf(stderr, VersionStr);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    if (SaveFlag + LoadFlag + GammaFlag + TranslateFlag > 1)
	GIF_EXIT("Can not handle more than one of -s -l, -t, or -g at the same time.");

    if (NumFiles == 1) {
	if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }
    else {
	/* Use stdin instead: */
	if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    if (SaveFlag) {
	/* We are dumping out the color map as text file to stdout: */
	ColorFile = stdout;
    }
    else {
	if (TranslateFlag) {
	    /* We are loading new color map from specified file: */
	    if ((TranslateFile = fopen(TranslateFileName, "rt")) == NULL)
		GIF_EXIT("Failed to open specified color translation file.");
	}

	if (LoadFlag) {
	    /* We are loading new color map from specified file: */
	    if ((ColorFile = fopen(ColorFileName, "rt")) == NULL)
		GIF_EXIT("Failed to open specified color map file.");
	}
    }

    if ((HasGIFOutput = (LoadFlag || TranslateFlag || GammaFlag)) != 0) {
	/* Open stdout for GIF output file: */
	if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    if (!ImageNFlag) {
	/* We are suppose to modify the screen color map, so do it: */
	GifFileIn->SColorMap = ModifyColorMap(GifFileIn->SColorMap);
	if (!HasGIFOutput) {
	    /* We can quit here, as we have the color map: */
	    if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
	    fclose(ColorFile);
	    exit(EXIT_SUCCESS);
	}
    }
    /* And dump out its new possible repositioned screen information: */
    if (HasGIFOutput)
	if (EGifPutScreenDesc(GifFileOut,
	    GifFileIn->SWidth, GifFileIn->SHeight,
	    GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
	    GifFileIn->SColorMap) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if ((++ImageNum == ImageN) && ImageNFlag) {
		    /* We are suppose to modify this image color map, do it: */
		    GifFileIn->SColorMap =ModifyColorMap(GifFileIn->SColorMap);
		    if (!HasGIFOutput) {
			/* We can quit here, as we have the color map: */
			if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
			fclose(ColorFile);
			exit(EXIT_SUCCESS);
		    }
		}
		if (HasGIFOutput)
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height,
			GifFileIn->Image.Interlace,
			GifFileIn->Image.ColorMap) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		if (!TranslateFlag || (ImageNFlag && (ImageN != ImageNum)))
		{
		    /* Now read image itself in decoded form as we don't */
		    /* really care what we have there, and this is much  */
		    /* faster.						 */
		    if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    if (HasGIFOutput)
			if (EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL) {
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
			if (HasGIFOutput)
			    if (EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
				QuitGifError(GifFileIn, GifFileOut);
		    }
		}
		else	/* we need to mung pixels intices */
		{
		    int	i;
		    register GifPixelType *cp;

		    GifPixelType *Line
			= (GifPixelType *) malloc(GifFileIn->Image.Width *
						  sizeof(GifPixelType));
		    for (i = 0; i < GifFileIn->Image.Height; i++) {
			if (DGifGetLine(GifFileIn, Line,GifFileIn->Image.Width)
			    == GIF_ERROR) {
			    QuitGifError(GifFileIn, GifFileOut);
			}

			/* translation step goes here */
			for (cp = Line; cp < Line+GifFileIn->Image.Width; cp++)
			    *cp = Translation[*cp];

			if (EGifPutLine(GifFileOut,
					Line, GifFileIn->Image.Width)
			    == GIF_ERROR) {
			    QuitGifError(GifFileIn, GifFileOut);
			}
		    }
		    free((char *) Line);
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (HasGIFOutput)
		    if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
							Extension) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		/* No support to more than one extension blocks, so discard: */
		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    if (DGifCloseFile(GifFileIn) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);
    if (HasGIFOutput)
	if (EGifCloseFile(GifFileOut) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

    return 0;
}
示例#8
0
/******************************************************************************
 Main sequence
******************************************************************************/
int main(int argc, char **argv)
{
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
    GifRecordType RecordType;
    int CodeSize, ExtCode, ErrorCode;
    GifByteType *CodeBlock, *Extension;

    /*
     * Command-line processing goes here.
     */

    /* Use stdin as input (note this also read screen descriptor in: */
    if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    /* Use the stdout as output: */
    if ((GifFileOut = EGifOpenFileHandle(1, &ErrorCode)) == NULL) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    /* And dump out its screen information: */
    if (EGifPutScreenDesc(GifFileOut,
	GifFileIn->SWidth, GifFileIn->SHeight,
	GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
	GifFileIn->SColorMap) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);

    /* Scan the content of the input GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		/* Put image descriptor to out file: */
		if (EGifPutImageDesc(GifFileOut,
		    GifFileIn->Image.Left, GifFileIn->Image.Top,
		    GifFileIn->Image.Width, GifFileIn->Image.Height,
		    GifFileIn->Image.Interlace,
		    GifFileIn->Image.ColorMap) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		/* Now read image itself in decoded form as we dont really   */
		/* care what we have there, and this is much faster.	     */
		if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR ||
		    EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		while (CodeBlock != NULL) {
		    if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
			EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* pass through extension records */
		if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (EGifPutExtensionLeader(GifFileOut, ExtCode) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (EGifPutExtensionBlock(GifFileOut, 
					  Extension[0],
					  Extension + 1) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFileIn, &Extension)==GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    if (Extension != NULL)
			if (EGifPutExtensionBlock(GifFileOut, 
						  Extension[0],
						  Extension + 1) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
		}
		if (EGifPutExtensionTrailer(GifFileOut) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:	     /* Should be trapped by DGifGetRecordType */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
    {
	PrintGifError(ErrorCode);
	if (GifFileIn != NULL) {
	    EGifCloseFile(GifFileIn, NULL);
	}
	exit(EXIT_FAILURE);
    }
    if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR)
    {
	PrintGifError(ErrorCode);
	if (GifFileOut != NULL) {
	    EGifCloseFile(GifFileOut, NULL);
	}
	exit(EXIT_FAILURE);
    }

    return 0;
}
示例#9
0
void DDGifSlurp(GifInfo *info, bool shouldDecode) {
    GifRecordType RecordType;
    GifByteType *ExtData;
    int codeSize;
    int ExtFunction;
    do {
        if (DGifGetRecordType(info->gifFilePtr, &RecordType) == GIF_ERROR)
            return;
        switch (RecordType) {
            case IMAGE_DESC_RECORD_TYPE:

                if (DGifGetImageDesc(info->gifFilePtr, !shouldDecode) == GIF_ERROR)
                    return;

                const uint_fast16_t requiredScreenWidth = info->gifFilePtr->Image.Left + info->gifFilePtr->Image.Width;
                const uint_fast16_t requiredScreenHeight = info->gifFilePtr->Image.Top + info->gifFilePtr->Image.Height;

                if (requiredScreenWidth > info->gifFilePtr->SWidth || requiredScreenHeight > info->gifFilePtr->SHeight) {
                    if (shouldDecode) {
                        void *tmpRasterBits = realloc(info->rasterBits,
                                                      requiredScreenWidth * requiredScreenHeight * sizeof(GifPixelType));
                        if (tmpRasterBits == NULL) {
                            info->gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
                            return;
                        }
                        info->rasterBits = tmpRasterBits;
                    }
                    else {
                        info->gifFilePtr->SWidth = requiredScreenWidth;
                        info->gifFilePtr->SHeight = requiredScreenHeight;
                    }
                }

                if (shouldDecode) {
                    if (info->gifFilePtr->Image.Interlace) {
                        uint_fast16_t i, j;
                        /*
                         * The way an interlaced image should be read -
                         * offsets and jumps...
                         */
                        uint_fast8_t InterlacedOffset[] = {0, 4, 2, 1};
                        uint_fast8_t InterlacedJumps[] = {8, 8, 4, 2};
                        /* Need to perform 4 passes on the image */
                        for (i = 0; i < 4; i++)
                            for (j = InterlacedOffset[i]; j < info->gifFilePtr->Image.Height; j += InterlacedJumps[i]) {
                                if (DGifGetLine(info->gifFilePtr, info->rasterBits + j * info->gifFilePtr->Image.Width,
                                                info->gifFilePtr->Image.Width) == GIF_ERROR)
                                    return;
                            }
                    }
                    else {
                        if (DGifGetLine(
                                info->gifFilePtr, info->rasterBits,
                                info->gifFilePtr->Image.Width * info->gifFilePtr->Image.Height) == GIF_ERROR)
                            return;
                    }
                    return;
                }
                else {
                    if (DGifGetCode(info->gifFilePtr, &codeSize, &ExtData) == GIF_ERROR)
                        return;
                    while (ExtData != NULL) {
                        if (DGifGetCodeNext(info->gifFilePtr, &ExtData) == GIF_ERROR)
                            return;
                    }
                }
                break;

            case EXTENSION_RECORD_TYPE:
                if (DGifGetExtension(info->gifFilePtr, &ExtFunction, &ExtData) == GIF_ERROR)
                    return;
                if (!shouldDecode) {
                    GraphicsControlBlock *tmpInfos = realloc(info->controlBlock,
                                                             (info->gifFilePtr->ImageCount + 1) *
                                                             sizeof(GraphicsControlBlock));
                    if (tmpInfos == NULL) {
                        info->gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
                        return;
                    }
                    info->controlBlock = tmpInfos;
                    info->controlBlock[info->gifFilePtr->ImageCount].DelayTime = DEFAULT_FRAME_DURATION_MS;
                    if (readExtensions(ExtFunction, ExtData, info) == GIF_ERROR)
                        return;
                }
                while (ExtData != NULL) {
                    if (DGifGetExtensionNext(info->gifFilePtr, &ExtData,
                                             &ExtFunction) == GIF_ERROR)
                        return;
                    if (!shouldDecode) {
                        if (readExtensions(ExtFunction, ExtData, info) == GIF_ERROR)
                            return;
                    }
                }
                break;

            case TERMINATE_RECORD_TYPE:
                break;

            default: /* Should be trapped by DGifGetRecordType */
                break;
        }
    } while (RecordType != TERMINATE_RECORD_TYPE);

    info->rewindFunction(info);
}
示例#10
0
/******************************************************************************
* Perform the disassembly operation - take one input files into few output.   *
******************************************************************************/
static int DoDisassemblyNum(const char *InFileName, char *OutFileName, int FileNum)
{
    int	ExtCode, CodeSize, FileEmpty;
    GifRecordType RecordType;
    char CrntFileName[80], *p;
    GifByteType *Extension, *CodeBlock;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
	int ErrorCode;

    /* If name has type postfix, strip it out, and make sure name is less    */
    /* or equal to 6 chars, so we will have 2 chars in name for numbers.     */
    //strupr(OutFileName);		      /* Make sure all is upper case */
	#if 0
	printf("OutFileName : %s\n", OutFileName);
	if ((p = strrchr(OutFileName, '.')) != NULL && strlen(p) <= 4) p[0] = 0;
    if ((p = strrchr(OutFileName, '/')) != NULL ||
	(p = strrchr(OutFileName, '\\')) != NULL ||
	(p = strrchr(OutFileName, ':')) != NULL) {
	if (strlen(p) > 7) p[7] = 0;   /* p includes the '/', '\\', ':' char */
    }
    else {
	/* Only name is given for current directory: */
	//if (strlen(OutFileName) > 6) OutFileName[6] = 0;
    }
	printf("OutFileName : %s\n", OutFileName);
	#endif

    /* Open input file: */
    if (InFileName != NULL) {
	if ((GifFileIn = DGifOpenFileName(InFileName, &ErrorCode)) == NULL)
	    return QuitGifError(GifFileIn, GifFileOut);
    }
    else {
	/* Use the stdin instead: */
	if ((GifFileIn = DGifOpenFileHandle(0, &ErrorCode)) == NULL)
	    return QuitGifError(GifFileIn, GifFileOut);
    }

    /* Scan the content of GIF file and dump image(s) to seperate file(s): */
	//sprintf(CrntFileName, "%s_%02d.gif", OutFileName, FileNum);
	sprintf(CrntFileName, "%s", OutFileName);
	if ((GifFileOut = EGifOpenFileName(CrntFileName, TRUE, &ErrorCode)) == NULL)
	    return QuitGifError(GifFileIn, GifFileOut);
	FileEmpty = TRUE;

	/* And dump out its exactly same screen information: */
	if (EGifPutScreenDesc(GifFileOut,
	    GifFileIn->SWidth, GifFileIn->SHeight,
	    GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
	    GifFileIn->SColorMap) == GIF_ERROR)
	    return QuitGifError(GifFileIn, GifFileOut);

	do {
	    if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
			return QuitGifError(GifFileIn, GifFileOut);

	    switch (RecordType) {
		case IMAGE_DESC_RECORD_TYPE:
		    FileEmpty = FALSE;
		    if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);
		    /* Put same image descriptor to out file: */
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height,
			GifFileIn->Image.Interlace,
			GifFileIn->Image.ColorMap) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);

		    /* Now read image itself in decoded form as we dont      */
		    /* really care what is there, and this is much faster.   */
		    if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR
		     || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL)
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
			    EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);
		    break;
		case EXTENSION_RECORD_TYPE:
		    FileEmpty = FALSE;
		    /* Skip any extension blocks in file: */
		    if (DGifGetExtension(GifFileIn, &ExtCode, &Extension)
			== GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);
		    if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
							Extension) == GIF_ERROR)
				return QuitGifError(GifFileIn, GifFileOut);

		    /* No support to more than one extension blocks, discard */
		    while (Extension != NULL)
			if (DGifGetExtensionNext(GifFileIn, &Extension)
			    == GIF_ERROR)
			    return QuitGifError(GifFileIn, GifFileOut);
		    break;
		case TERMINATE_RECORD_TYPE:
		    break;
		default:	     /* Should be traps by DGifGetRecordType */
		    break;
	    }
	}
	while (RecordType != IMAGE_DESC_RECORD_TYPE &&
	       RecordType != TERMINATE_RECORD_TYPE);

	if (EGifCloseFile(GifFileOut, &ErrorCode) == GIF_ERROR)
	    return QuitGifError(GifFileIn, GifFileOut);
	if (FileEmpty) {
	    /* Might happen on last file - delete it if so: */
	    unlink(CrntFileName);
	}

    if (DGifCloseFile(GifFileIn, &ErrorCode) == GIF_ERROR)
		return QuitGifError(GifFileIn, GifFileOut);
}
示例#11
0
/******************************************************************************
* Perform the assembly operation - take few input files into one output.      *
******************************************************************************/
static void DoAssembly(int NumFiles, char **FileNames)
{
    int	i, ExtCode, CodeSize;
    GifRecordType RecordType;
    GifByteType *Extension, *CodeBlock;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    /* Open stdout for the output file: */
    if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
	QuitGifError(GifFileIn, GifFileOut);

    /* Scan the content of the GIF file and load the image(s) in: */
    for (i = 0; i < NumFiles; i++) {
	if ((GifFileIn = DGifOpenFileName(FileNames[i])) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);

	/* And dump out screen descriptor iff its first image.	*/
	if (i == 0)
	    if (EGifPutScreenDesc(GifFileOut,
		GifFileIn -> SWidth, GifFileIn -> SHeight,
		GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
		GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == GIF_ERROR)
		QuitGifError(GifFileIn, GifFileOut);

	do {
	    if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
		QuitGifError(GifFileIn, GifFileOut);

	    switch (RecordType) {
		case IMAGE_DESC_RECORD_TYPE:
		    if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    /* Put image descriptor to out file: */
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn -> ILeft, GifFileIn -> ITop,
			GifFileIn -> IWidth, GifFileIn -> IHeight,
			GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
			GifFileIn -> IColorMap) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		    /* Now read image itself in decoded form as we dont      */
		    /* dont care what is there, and this is much faster.     */
		    if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR
		     || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL)
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
			    EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
		    break;
		case EXTENSION_RECORD_TYPE:
		    /* Skip any extension blocks in file: */
		    if (DGifGetExtension(GifFileIn, &ExtCode, &Extension)
			== GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
						       Extension) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		    /* No support to more than one extension blocks, discard.*/
		    while (Extension != NULL)
			if (DGifGetExtensionNext(GifFileIn, &Extension)
			    == GIF_ERROR)
				QuitGifError(GifFileIn, GifFileOut);
		    break;
		case TERMINATE_RECORD_TYPE:
		    break;
		default:	    /* Should be traps by DGifGetRecordType. */
		    break;
	    }
	}
	while (RecordType != TERMINATE_RECORD_TYPE);

	if (DGifCloseFile(GifFileIn) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    if (EGifCloseFile(GifFileOut) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);
}
示例#12
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, Error, NumFiles, ExtCode, CodeSize, ImageNum = 0,
	ImageFlag = FALSE, ImageNFlag = FALSE, ImageN, ImageX1, ImageY1,
	ImageX2, ImageY2, ImageWidth, ImageDepth,
	Complement = FALSE, HelpFlag = FALSE;
    GifRecordType RecordType;
    GifByteType *Extension, *CodeBlock;
    char **FileName = NULL;
    GifRowType Line;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    /* Same image dimension vars for both Image & ImageN as only one allowed.*/
    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &Complement,
		&ImageFlag, &ImageX1, &ImageY1, &ImageX2, &ImageY2,
		&ImageNFlag, &ImageN, &ImageX1, &ImageY1, &ImageX2, &ImageY2,
		&HelpFlag, &NumFiles, &FileName)) != FALSE ||
		(NumFiles > 1 && !HelpFlag)) {
	if (Error)
	    GAPrintErrMsg(Error);
	else if (NumFiles > 1)
	    GIF_MESSAGE("Error in command line parsing - one GIF file please.");
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

    if (HelpFlag) {
	fprintf(stderr, VersionStr);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    /* Test to make sure exactly one of ImageFlag & ImageNFlag is set: */
    if ((ImageFlag && ImageNFlag) || (!ImageFlag && !ImageNFlag)) {
	GIF_MESSAGE("Exactly one of [-i ...] && [-n ...] please.");
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }
    if (ImageFlag) ImageN = 1;		    /* Its first image we are after. */

    /* Make sure the first coordinates of clipping box are smaller: */
    if (ImageX1 > ImageX2) {
	i = ImageX1;
	ImageX1 = ImageX2;
	ImageX2 = i;
    }
    if (ImageY1 > ImageY2) {
	i = ImageX1;
	ImageY1 = ImageY2;
	ImageY2 = i;
    }

    if (NumFiles == 1) {
	if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }
    else {
	/* Use the stdin instead: */
	if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    /* Open stdout for the output file: */
    if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
	QuitGifError(GifFileIn, GifFileOut);

    /* Width and depth of clipped image. */
    if (!Complement)
	ImageWidth = ImageX2 - ImageX1 + 1;
    else
	ImageWidth = GifFileIn->SWidth
	    - (ImageX2 != ImageX1) * (ImageX2 - ImageX1 + 1);
    if (!Complement)
	ImageDepth = ImageY2 - ImageY1 + 1;
    else
	ImageDepth = GifFileIn->SHeight
	    - (ImageY2 != ImageY1) * (ImageY2 - ImageY1 + 1);

    /* And dump out exactly same screen information: */
    if (EGifPutScreenDesc(GifFileOut,
	GifFileIn->SWidth, GifFileIn->SHeight,
	GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
	GifFileIn->SColorMap) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (++ImageNum == ImageN) {
		    /* We can handle only non interlaced images here: */
		    if (GifFileIn->Image.Interlace)
			GIF_EXIT("Image to clip is interlaced - use GifInter first.");

		    /* This is the image we should clip - test sizes and     */
		    /* dump out new clipped screen descriptor if o.k.	     */
		    if (GifFileIn->Image.Width <= ImageX2 ||
			GifFileIn->Image.Height <= ImageY2)
			GIF_EXIT("Image is smaller than given clip dimensions.");

		    /* Put the image descriptor to out file: */
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			ImageWidth, ImageDepth,
			FALSE, GifFileIn->Image.ColorMap) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		    /* o.k. - read the image and clip it: */
		    Line = (GifRowType) malloc(GifFileIn->Image.Width *
							sizeof(GifPixelType));
		    GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
			PROGRAM_NAME, ImageNum,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height);

		    /* Skip lines below ImageY1: */
		    for (i = 0; i < ImageY1; i++) {
			if (DGifGetLine(GifFileIn, Line, GifFileIn->Image.Width)
			    == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);

			if (Complement) {
			    if (ImageX1 == ImageX2) {
				/* don't remove any vertical band */
				if (EGifPutLine(GifFileOut, Line,
						ImageWidth) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			    else
			    {
				if (EGifPutLine(GifFileOut, Line,
						ImageX1) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);

				if (EGifPutLine(GifFileOut,
						&Line[ImageX2 + 1],
						GifFileIn->SWidth - (ImageX2 + 1)
						) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			}

			GifQprintf("\b\b\b\b%-4d", i);
		    }

		    /* Clip the lines from ImageY1 to ImageY2 (to X1 - X2): */
		    for (i = ImageY1; i <= ImageY2; i++) {
			if (DGifGetLine(GifFileIn, Line, GifFileIn->Image.Width)
			    == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);

			if (!Complement)
			    if (EGifPutLine(GifFileOut, &Line[ImageX1],
					    ImageWidth) == GIF_ERROR)
				QuitGifError(GifFileIn, GifFileOut);

			GifQprintf("\b\b\b\b%-4d", i);
		    }

		    /* Skip lines above ImageY2: */
		    for (i = ImageY2 + 1; i < GifFileIn->Image.Height; i++) {
			if (DGifGetLine(GifFileIn, Line, GifFileIn->Image.Width)
			    == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);

			if (Complement) {
			    if (ImageX1 == ImageX2) {
				/* don't remove any vertical band */
				if (EGifPutLine(GifFileOut, Line,
						ImageWidth) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			    else
			    {
				if (EGifPutLine(GifFileOut, Line,
						ImageX1) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);

				if (EGifPutLine(GifFileOut,
						&Line[ImageX2 + 1],
						GifFileIn->SWidth - (ImageX2 + 1)
						) == GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			}

			GifQprintf("\b\b\b\b%-4d", i);
		    }

		    free((char *) Line);
		}
		else {
		    /* Copy the image as is (we dont modify this one): */
		    if (EGifPutImageDesc(GifFileOut,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height,
			GifFileIn->Image.Interlace,
			GifFileIn->Image.ColorMap) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);

		    /* Now read image itself in decoded form as we dont      */
		    /* really care what is there, and this is much faster.   */
		    if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR
		     || EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL)
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
			    EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
							Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		/* No support to more than one extension blocks, so discard: */
		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    if (DGifCloseFile(GifFileIn) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);
    if (EGifCloseFile(GifFileOut) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);

    return 0;
}
示例#13
0
void DDGifSlurp(GifInfo *info, bool decode, bool exitAfterFrame) {
	GifRecordType RecordType;
	GifByteType *ExtData;
	int ExtFunction;
	GifFileType *gifFilePtr;
	gifFilePtr = info->gifFilePtr;
	uint_fast32_t lastAllocatedGCBIndex = 0;
	do {
		if (DGifGetRecordType(gifFilePtr, &RecordType) == GIF_ERROR)
			return;
		bool isInitialPass = !decode && !exitAfterFrame;
		switch (RecordType) {
			case IMAGE_DESC_RECORD_TYPE:

				if (DGifGetImageDesc(gifFilePtr, isInitialPass) == GIF_ERROR)
					return;

				if (isInitialPass) {
					int_fast32_t widthOverflow = gifFilePtr->Image.Width - gifFilePtr->SWidth;
					int_fast32_t heightOverflow = gifFilePtr->Image.Height - gifFilePtr->SHeight;
					if (widthOverflow > 0 || heightOverflow > 0) {
						gifFilePtr->SWidth += widthOverflow;
						gifFilePtr->SHeight += heightOverflow;
					}
					SavedImage *sp = &gifFilePtr->SavedImages[gifFilePtr->ImageCount - 1];
					int_fast32_t topOverflow = gifFilePtr->Image.Top + gifFilePtr->Image.Height - gifFilePtr->SHeight;
					if (topOverflow > 0) {
						sp->ImageDesc.Top -= topOverflow;
					}

					int_fast32_t leftOverflow = gifFilePtr->Image.Left + gifFilePtr->Image.Width - gifFilePtr->SWidth;
					if (leftOverflow > 0) {
						sp->ImageDesc.Left -= leftOverflow;
					}
					if (!updateGCB(info, &lastAllocatedGCBIndex)) {
						return;
					}
				}

				if (decode) {
					int_fast32_t widthOverflow = gifFilePtr->Image.Width - info->originalWidth;
					int_fast32_t heightOverflow = gifFilePtr->Image.Height - info->originalHeight;
					if (widthOverflow > 0 || heightOverflow > 0) {
						void *tmpRasterBits = reallocarray(info->rasterBits, info->originalWidth * info->originalHeight, sizeof(GifPixelType));
						if (tmpRasterBits == NULL) {
							gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
							return;
						}
						info->rasterBits = tmpRasterBits;
					}
					if (gifFilePtr->Image.Interlace) {
						uint_fast16_t i, j;
						/*
						 * The way an interlaced image should be read -
						 * offsets and jumps...
						 */
						uint_fast8_t InterlacedOffset[] = {0, 4, 2, 1};
						uint_fast8_t InterlacedJumps[] = {8, 8, 4, 2};
						/* Need to perform 4 passes on the image */
						for (i = 0; i < 4; i++)
							for (j = InterlacedOffset[i]; j < gifFilePtr->Image.Height; j += InterlacedJumps[i]) {
								if (DGifGetLine(gifFilePtr, info->rasterBits + j * gifFilePtr->Image.Width, gifFilePtr->Image.Width) == GIF_ERROR)
									return;
							}
					} else {
						if (DGifGetLine(gifFilePtr, info->rasterBits, gifFilePtr->Image.Width * gifFilePtr->Image.Height) == GIF_ERROR) {
							return;
						}
					}

					if (info->sampleSize > 1) {
						unsigned char *dst = info->rasterBits;
						unsigned char *src = info->rasterBits;
						unsigned char *const srcEndImage = info->rasterBits + gifFilePtr->Image.Width * gifFilePtr->Image.Height;
						do {
							unsigned char *srcNextLineStart = src + gifFilePtr->Image.Width * info->sampleSize;
							unsigned char *const srcEndLine = src + gifFilePtr->Image.Width;
							unsigned char *dstEndLine = dst + gifFilePtr->Image.Width / info->sampleSize;
							do {
								*dst = *src;
								dst++;
								src += info->sampleSize;
							} while (src < srcEndLine);
							dst = dstEndLine;
							src = srcNextLineStart;
						} while (src < srcEndImage);
					}
					return;
				} else {
					do {
						if (DGifGetCodeNext(gifFilePtr, &ExtData) == GIF_ERROR) {
							return;
						}
					} while (ExtData != NULL);
					if (exitAfterFrame) {
						return;
					}
				}
				break;

			case EXTENSION_RECORD_TYPE:
				if (DGifGetExtension(gifFilePtr, &ExtFunction, &ExtData) == GIF_ERROR) {
					return;
				}
				if (isInitialPass) {
					updateGCB(info, &lastAllocatedGCBIndex);
					if (readExtensions(ExtFunction, ExtData, info) == GIF_ERROR) {
						return;
					}
				}
				while (ExtData != NULL) {
					if (DGifGetExtensionNext(gifFilePtr, &ExtData) == GIF_ERROR) {
						return;
					}
					if (isInitialPass) {
						if (readExtensions(ExtFunction, ExtData, info) == GIF_ERROR)
							return;
					}
				}
				break;

			case TERMINATE_RECORD_TYPE:
				break;

			default: /* Should be trapped by DGifGetRecordType */
				break;
		}
	} while (RecordType != TERMINATE_RECORD_TYPE);

	info->rewindFunction(info);
}
示例#14
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, Size, Error, NumFiles, ExtCode, CodeSize, NumColors = 2, Color,
	Count, ImageNum = 0, TextFlag = FALSE, SizeFlag = FALSE,
	ImageNFlag = FALSE, BackGroundFlag = FALSE, HelpFlag = FALSE;
    long Scaler, Histogram[256];
    GifRecordType RecordType;
    GifByteType *Extension, *CodeBlock;
    char **FileName = NULL;
    GifRowType Line;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    /* Same image dimension vars for both Image & ImageN as only one allowed */
    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint,
		&TextFlag, &SizeFlag, &ImageWidth, &ImageHeight,
		&ImageNFlag, &ImageN, &BackGroundFlag,
		&HelpFlag, &NumFiles, &FileName)) != FALSE ||
		(NumFiles > 1 && !HelpFlag)) {
	if (Error)
	    GAPrintErrMsg(Error);
	else if (NumFiles > 1)
	    GIF_MESSAGE("Error in command line parsing - one GIF file please.");
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

    if (HelpFlag) {
	fprintf(stderr, VersionStr);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    if (NumFiles == 1) {
	if ((GifFileIn = DGifOpenFileName(*FileName)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }
    else {
	/* Use the stdin instead: */
	if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    for (i = 0; i < 256; i++) Histogram[i] = 0;		  /* Reset counters. */

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);

	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		if (GifFileIn->Image.ColorMap)
		    NumColors = GifFileIn->Image.ColorMap->ColorCount;
		else if (GifFileIn->SColorMap)
		    NumColors = GifFileIn->SColorMap->ColorCount;
		else
		    GIF_EXIT("Neither Screen nor Image color map exists.");

		if ((ImageHeight / NumColors) * NumColors != ImageHeight)
		    GIF_EXIT("Image height specified not dividable by #colors.");

		if (++ImageNum == ImageN) {
		    /* This is the image we should make histogram for:       */
		    Line = (GifRowType) malloc(GifFileIn->Image.Width *
							sizeof(GifPixelType));
		    GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
			PROGRAM_NAME, ImageNum,
			GifFileIn->Image.Left, GifFileIn->Image.Top,
			GifFileIn->Image.Width, GifFileIn->Image.Height);

		    for (i = 0; i < GifFileIn->Image.Height; i++) {
			if (DGifGetLine(GifFileIn, Line, GifFileIn->Image.Width)
			    == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
			for (j = 0; j < GifFileIn->Image.Width; j++)
			    Histogram[Line[j]]++;
			GifQprintf("\b\b\b\b%-4d", i);
		    }

		    free((char *) Line);
		}
		else {
		    /* Skip the image: */
		    /* Now read image itself in decoded form as we dont      */
		    /* really care what is there, and this is much faster.   */
		    if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		    while (CodeBlock != NULL)
			if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR)
			QuitGifError(GifFileIn, GifFileOut);
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    /* We we requested to kill back ground count: */
    if (BackGroundFlag) Histogram[GifFileIn->SBackGroundColor] = 0;

    if (DGifCloseFile(GifFileIn) == GIF_ERROR)
	QuitGifError(GifFileIn, GifFileOut);


    /* We may required to dump out the histogram as text file: */
    if (TextFlag) {
	for (i = 0; i < NumColors; i++)
	    printf("%12ld  %3d\n", Histogram[i], i);
    }
    else {
	/* Open stdout for the histogram output file: */
	if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
	    QuitGifError(GifFileIn, GifFileOut);

	/* Dump out screen descriptor to fit histogram dimensions: */
	if (EGifPutScreenDesc(GifFileOut,
	    ImageWidth, ImageHeight, HISTO_BITS_PER_PIXEL, 0,
	    MakeMapObject(4, HistoColorMap)) == GIF_ERROR)
		QuitGifError(GifFileIn, GifFileOut);

	/* Dump out image descriptor to fit histogram dimensions: */
	if (EGifPutImageDesc(GifFileOut,
			     0, 0, ImageWidth, ImageHeight, FALSE, NULL) == GIF_ERROR)
		QuitGifError(GifFileIn, GifFileOut);

	/* Prepare scan line for histogram file, and find scaler to scale    */
	/* histogram to be between 0 and ImageWidth:			     */
	Line = (GifRowType) malloc(ImageWidth * sizeof(GifPixelType));
	for (Scaler = 0, i = 0; i < NumColors; i++) if (Histogram[i] > Scaler)
	    Scaler = Histogram[i];
	Scaler /= ImageWidth;
	if (Scaler == 0) Scaler = 1;  /* In case maximum is less than width. */

	/* Dump out the image itself: */
	for (Count = ImageHeight, i = 0, Color = 1; i < NumColors; i++) {
	    if ((Size = Histogram[i] / Scaler) > ImageWidth) Size = ImageWidth;
	    for (j = 0; j < Size; j++)
		Line[j] = Color;
	    for (j = Size; j < ImageWidth; j++)
		Line[j] = GifFileOut->SBackGroundColor;

	    /* Move to next color: */
	    if (++Color >= (1 << HISTO_BITS_PER_PIXEL)) Color = 1;

	    /* Dump this histogram entry as many times as required: */
	    for (j = 0; j < ImageHeight / NumColors; j++) {
		if (EGifPutLine(GifFileOut, Line, ImageWidth) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		GifQprintf("\b\b\b\b%-4d", Count--);
	    }
	}

	if (EGifCloseFile(GifFileOut) == GIF_ERROR)
	    QuitGifError(GifFileIn, GifFileOut);
    }

    return 0;
}
示例#15
0
/******************************************************************************
 Interpret the command line and scan the given GIF file.
******************************************************************************/
int main(int argc, char **argv)
{
    int i, j, ExtCode, ErrorCode, CodeSize, NumFiles, Len, ImageNum = 1;
    bool Error,
	ColorMapFlag = false, EncodedFlag = false, LZCodesFlag = false,
	PixelFlag = false, HelpFlag = false, RawFlag = false; 
    char *GifFileName, **FileName = NULL;
    GifPixelType *Line;
    GifRecordType RecordType;
    GifByteType *CodeBlock, *Extension;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifNoisyPrint, &ColorMapFlag, &EncodedFlag,
		&LZCodesFlag, &PixelFlag, &RawFlag, &HelpFlag,
		&NumFiles, &FileName)) != false ||
	(NumFiles > 1 && !HelpFlag)) {
	if (Error)
	    GAPrintErrMsg(Error);
	else if (NumFiles > 1)
	    GIF_MESSAGE("Error in command line parsing - one GIF file please.");
	GAPrintHowTo(CtrlStr);
	exit(EXIT_FAILURE);
    }

    if (HelpFlag) {
	(void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR);
	GAPrintHowTo(CtrlStr);
	exit(EXIT_SUCCESS);
    }

    if (NumFiles == 1) {
	GifFileName = *FileName;
	if ((GifFile = DGifOpenFileName(*FileName, &ErrorCode)) == NULL) {
	    PrintGifError(ErrorCode);
	    exit(EXIT_FAILURE);
	}
    }
    else {
	/* Use stdin instead: */
	GifFileName = "Stdin";
	if ((GifFile = DGifOpenFileHandle(0, &ErrorCode)) == NULL) {
	    PrintGifError(ErrorCode);
	    exit(EXIT_FAILURE);
	}
    }

    /* Because we write binary data - make sure no text will be written. */
    if (RawFlag) {
	ColorMapFlag = EncodedFlag = LZCodesFlag = PixelFlag = false;
#ifdef _WIN32
	_setmode(1, O_BINARY);             /* Make sure it is in binary mode. */
#endif /* _WIN32 */
    }
    else {
	printf("\n%s:\n\n\tScreen Size - Width = %d, Height = %d.\n",
	       GifFileName, GifFile->SWidth, GifFile->SHeight);
	printf("\tColorResolution = %d, BitsPerPixel = %d, BackGround = %d, Aspect = %d.\n",
	       GifFile->SColorResolution,
	       GifFile->SColorMap ? GifFile->SColorMap->BitsPerPixel : 0,
	       GifFile->SBackGroundColor,
	       GifFile->AspectByte);
	if (GifFile->SColorMap)
	    printf("\tHas Global Color Map.\n\n");
	else
	    printf("\tNo Global Color Map.\n\n");
	if (ColorMapFlag && GifFile->SColorMap) {
	    printf("\tGlobal Color Map:\n");
	    Len = GifFile->SColorMap->ColorCount;
	    printf("\tSort Flag: %s\n", 
		   GifFile->SColorMap->SortFlag ? "on":"off");
	    for (i = 0; i < Len; i+=4) {
		for (j = 0; j < 4 && j < Len; j++) {
		    printf("%3d: %02xh %02xh %02xh   ", i + j,
			   GifFile->SColorMap->Colors[i + j].Red,
			   GifFile->SColorMap->Colors[i + j].Green,
			   GifFile->SColorMap->Colors[i + j].Blue);
		}
		printf("\n");
	    }
	}
    }

    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
	    PrintGifError(GifFile->Error);
	    exit(EXIT_FAILURE);
	}
	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
		    PrintGifError(GifFile->Error);
		    exit(EXIT_FAILURE);
		}
		if (!RawFlag) {
		    printf("\nImage #%d:\n\n\tImage Size - Left = %d, Top = %d, Width = %d, Height = %d.\n",
			   ImageNum++, GifFile->Image.Left, GifFile->Image.Top,
			   GifFile->Image.Width, GifFile->Image.Height);
		    printf("\tImage is %s",
			   GifFile->Image.Interlace ? "Interlaced" :
						    "Non Interlaced");
		    if (GifFile->Image.ColorMap != NULL)
			printf(", BitsPerPixel = %d.\n",
				GifFile->Image.ColorMap->BitsPerPixel);
		    else
			printf(".\n");
		    if (GifFile->Image.ColorMap)
			printf("\tImage Has Color Map.\n");
		    else
			printf("\tNo Image Color Map.\n");
		    if (ColorMapFlag && GifFile->Image.ColorMap) {
			printf("\tSort Flag: %s\n", 
			       GifFile->Image.ColorMap->SortFlag ? "on":"off");
			Len = 1 << GifFile->Image.ColorMap->BitsPerPixel;
			for (i = 0; i < Len; i+=4) {
			    for (j = 0; j < 4 && j < Len; j++) {
				printf("%3d: %02xh %02xh %02xh   ", i + j,
				       GifFile->Image.ColorMap->Colors[i + j].Red,
				       GifFile->Image.ColorMap->Colors[i + j].Green,
				       GifFile->Image.ColorMap->Colors[i + j].Blue);
			    }
			    printf("\n");
			}
		    }
		}

		if (EncodedFlag) {
		    if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
			PrintGifError(GifFile->Error);
			exit(EXIT_FAILURE);
		    }
		    printf("\nImage LZ compressed Codes (Code Size = %d):\n",
			   CodeSize);
		    PrintCodeBlock(GifFile, CodeBlock, true);
		    while (CodeBlock != NULL) {
			if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
			PrintCodeBlock(GifFile, CodeBlock, false);
		    }
		}
		else if (LZCodesFlag) {
		    PrintLZCodes(GifFile);
		}
		else if (PixelFlag) {
		    Line = (GifPixelType *) malloc(GifFile->Image.Width *
						sizeof(GifPixelType));
		    for (i = 0; i < GifFile->Image.Height; i++) {
			if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
			    == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
			PrintPixelBlock(Line, GifFile->Image.Width, i == 0);
		    }
		    PrintPixelBlock(NULL, GifFile->Image.Width, false);
		    free((char *) Line);
		}
		else if (RawFlag) {
		    Line = (GifPixelType *) malloc(GifFile->Image.Width *
						sizeof(GifPixelType));
		    for (i = 0; i < GifFile->Image.Height; i++) {
			if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
			    == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
			fwrite(Line, 1, GifFile->Image.Width, stdout);
		    }
		    free((char *) Line);
		}
		else {
		    /* Skip the image: */
		    if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
			PrintGifError(GifFile->Error);
			exit(EXIT_FAILURE);
		    }
		    while (CodeBlock != NULL) {
			if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
		    }

		}
		break;
	    case EXTENSION_RECORD_TYPE:
		if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
		    PrintGifError(GifFile->Error);
		    exit(EXIT_FAILURE);
		}
		if (!RawFlag) {
		    putchar('\n');
		    switch (ExtCode)
		    {
		    case COMMENT_EXT_FUNC_CODE:
			printf("GIF89 comment");
			break;
		    case GRAPHICS_EXT_FUNC_CODE:
			printf("GIF89 graphics control");
			break;
		    case PLAINTEXT_EXT_FUNC_CODE:
			printf("GIF89 plaintext");
			break;
		    case APPLICATION_EXT_FUNC_CODE:
			printf("GIF89 application block");
			break;
		    default:
			printf("Extension record of unknown type");
			break;
		    }
		    printf(" (Ext Code = %d [%c]):\n",
			   ExtCode, MAKE_PRINTABLE(ExtCode));
		    PrintExtBlock(Extension, true);

		    if (ExtCode == GRAPHICS_EXT_FUNC_CODE) {
			GraphicsControlBlock gcb;
			if (DGifExtensionToGCB(Extension[0], Extension+1, &gcb) == GIF_ERROR) {
			    PrintGifError(GifFile->Error);
			    exit(EXIT_FAILURE);
			}
			printf("\tDisposal Mode: %d\n", gcb.DisposalMode);
			printf("\tUser Input Flag: %d\n", gcb.UserInputFlag);
			printf("\tTransparency on: %s\n",
			       gcb.TransparentColor != -1 ? "yes" : "no");
			printf("\tDelayTime: %d\n", gcb.DelayTime);
			printf("\tTransparent Index: %d\n", gcb.TransparentColor);
		    }
		}
		for (;;) {
		    if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
			PrintGifError(GifFile->Error);
			exit(EXIT_FAILURE);
		    }
		    if (Extension == NULL)
			break;
		    PrintExtBlock(Extension, false);
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:	     /* Should be trapped by DGifGetRecordType */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) {
	PrintGifError(ErrorCode);
	exit(EXIT_FAILURE);
    }

    if (!RawFlag) printf("\nGIF file terminated normally.\n");

    return 0;
}
示例#16
0
文件: dgif_lib.c 项目: 0x0all/ROOT
/******************************************************************************
*  Get one full scanned line (Line) of length LineLen from GIF file.	      *
******************************************************************************/
int DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
{
    GifByteType *Dummy;
    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
	/* This file was NOT open for reading: */
	_GifError = D_GIF_ERR_NOT_READABLE;
	return GIF_ERROR;
    }

    if (!LineLen) LineLen = GifFile->Image.Width;

#if defined(__MSDOS__) || defined(__GNUC__)
    if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
#else
    if ((Private->PixelCount -= LineLen) > 0xffff0000) {
#endif /* __MSDOS__ */
	_GifError = D_GIF_ERR_DATA_TOO_BIG;
	return GIF_ERROR;
    }

    if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
	if (Private->PixelCount == 0) {
	    /* We probably would not be called any more, so lets clean 	     */
	    /* everything before we return: need to flush out all rest of    */
	    /* image until empty block (size 0) detected. We use GetCodeNext.*/
	    do if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
		return GIF_ERROR;
	    while (Dummy != NULL);
	}
	return GIF_OK;
    }
    else
	return GIF_ERROR;
}

/******************************************************************************
*   Get an extension block (see GIF manual) from gif file. This routine only  *
* returns the first data block, and DGifGetExtensionNext shouldbe called      *
* after this one until NULL extension is returned.			      *
*   The Extension should NOT be freed by the user (not dynamically allocated).*
*   Note it is assumed the Extension desc. header ('!') has been read.	      *
******************************************************************************/
int DGifGetExtension(GifFileType *GifFile, int *ExtCode,
						    GifByteType **Extension)
{
    GifByteType Buf;
    GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

    if (!IS_READABLE(Private)) {
	/* This file was NOT open for reading: */
	_GifError = D_GIF_ERR_NOT_READABLE;
	return GIF_ERROR;
    }

    if (READ(GifFile,&Buf, 1) != 1) {
	_GifError = D_GIF_ERR_READ_FAILED;
	return GIF_ERROR;
    }
    *ExtCode = Buf;

    return DGifGetExtensionNext(GifFile, Extension);
}