Ejemplo n.º 1
0
GifRecordType GIFAbstractDataset::FindFirstImage( GifFileType* hGifFile )
{
    GifRecordType RecordType = TERMINATE_RECORD_TYPE;

    while( DGifGetRecordType(hGifFile, &RecordType) != GIF_ERROR
           && RecordType != TERMINATE_RECORD_TYPE
           && RecordType != IMAGE_DESC_RECORD_TYPE )
    {
        /* Skip extension records found before IMAGE_DESC_RECORD_TYPE */
        if (RecordType == EXTENSION_RECORD_TYPE)
        {
            int nFunction;
            GifByteType *pExtData = nullptr;
            if (DGifGetExtension(hGifFile, &nFunction, &pExtData) == GIF_ERROR)
                break;
            while (pExtData != nullptr)
            {
                if (DGifGetExtensionNext(hGifFile, &pExtData) == GIF_ERROR)
                    break;
            }
        }
    }

    return RecordType;
}
Ejemplo n.º 2
0
value dGifGetExtension( value hdl )
{
  CAMLparam1(hdl);
  CAMLlocal3(ext,exts,res);
  CAMLlocal1(newres);

  GifFileType *GifFile = (GifFileType*) hdl;
  int func;
  GifByteType *extData;

  exts = Val_int(0);

  if (DGifGetExtension(GifFile,&func, &extData) == GIF_ERROR){
    failwith("DGifGetExtension");
  }

  while( extData != NULL ){
    ext= alloc_string(extData[0]);
    memcpy(String_val(ext), &extData[1], extData[0]);
    newres = alloc_small(2,0);
    caml_modify_field(newres, 0, ext);
    caml_modify_field(newres, 1, exts);
    exts= newres;
    DGifGetExtensionNext(GifFile, &extData);
  }
  res = alloc_small(2,0);
  caml_modify_field(res,0, Val_int(func));
  caml_modify_field(res,1, exts);

  CAMLreturn(res);
}
Ejemplo n.º 3
0
static int readExtensions(int ExtFunction, GifByteType *ExtData, GifInfo *info) {
    if (ExtData == NULL)
        return GIF_OK;
    if (ExtFunction == GRAPHICS_EXT_FUNC_CODE) {
        GraphicsControlBlock *GCB = &info->controlBlock[info->gifFilePtr->ImageCount];
        if (DGifExtensionToGCB(ExtData[0], ExtData + 1, GCB) == GIF_ERROR)
            return GIF_ERROR;

        GCB->DelayTime = GCB->DelayTime > 1 ? GCB->DelayTime * 10 : DEFAULT_FRAME_DURATION_MS;
    }
    else if (ExtFunction == COMMENT_EXT_FUNC_CODE) {
        if (getComment(ExtData, info) == GIF_ERROR) {
            info->gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
            return GIF_ERROR;
        }
    }
    else if (ExtFunction == APPLICATION_EXT_FUNC_CODE) {
        char const *string = (char const *) (ExtData + 1);
        if (strncmp("NETSCAPE2.0", string, ExtData[0]) == 0
            || strncmp("ANIMEXTS1.0", string, ExtData[0]) == 0) {
            if (DGifGetExtensionNext(info->gifFilePtr, &ExtData,
                                     &ExtFunction) == GIF_ERROR)
                return GIF_ERROR;
            if (ExtData[0] == 3 && ExtData[1] == 1) {
                info->loopCount = (uint_fast16_t) (ExtData[2] + (ExtData[3] << 8));
            }
        }
    }
    return GIF_OK;
}
Ejemplo n.º 4
0
static int read_extensions(GifFileType *gf)
{
	uint8_t *gif_ext_ptr;
	int gif_ext_type;

	//TODO: Should we free them?

	if (DGifGetExtension(gf, &gif_ext_type, &gif_ext_ptr) != GIF_OK) {
		GP_DEBUG(1, "DGifGetExtension() error %s (%i)",
		         gif_err_name(gif_err(gf)), gif_err(gf));
		return EIO;
	}

	GP_DEBUG(2, "Have GIF extension type %i (ignoring)", gif_ext_type);

	do {
		if (DGifGetExtensionNext(gf, &gif_ext_ptr) != GIF_OK) {
			GP_DEBUG(1, "DGifGetExtension() error %s (%i)",
			         gif_err_name(gif_err(gf)), gif_err(gf));
			return EIO;
		}

	} while (gif_ext_ptr != NULL);

	return 0;
}
Ejemplo n.º 5
0
static GifRecordType
gif_fileread(struct gif_state *h)
{
    GifRecordType RecordType;
    GifByteType *Extension;
    int ExtCode, rc;
    const char *type;

    for (;;) {
	if (GIF_ERROR == DGifGetRecordType(h->gif,&RecordType)) {
	    if (FbiStuff::fim_filereading_debug())
		FIM_FBI_PRINTF("gif: DGifGetRecordType failed\n");
	    PrintGifError();
	    return (GifRecordType)-1;
	}
	switch (RecordType) {
	case IMAGE_DESC_RECORD_TYPE:
	    if (FbiStuff::fim_filereading_debug())
		FIM_FBI_PRINTF("gif: IMAGE_DESC_RECORD_TYPE found\n");
	    return RecordType;
	case EXTENSION_RECORD_TYPE:
	    if (FbiStuff::fim_filereading_debug())
		FIM_FBI_PRINTF("gif: EXTENSION_RECORD_TYPE found\n");
	    for (rc = DGifGetExtension(h->gif,&ExtCode,&Extension);
		 NULL != Extension;
		 rc = DGifGetExtensionNext(h->gif,&Extension)) {
		if (rc == GIF_ERROR) {
		    if (FbiStuff::fim_filereading_debug())
			FIM_FBI_PRINTF("gif: DGifGetExtension failed\n");
		    PrintGifError();
		    return (GifRecordType)-1;
		}
		if (FbiStuff::fim_filereading_debug()) {
		    switch (ExtCode) {
		    case COMMENT_EXT_FUNC_CODE:     type="comment";   break;
		    case GRAPHICS_EXT_FUNC_CODE:    type="graphics";  break;
		    case PLAINTEXT_EXT_FUNC_CODE:   type="plaintext"; break;
		    case APPLICATION_EXT_FUNC_CODE: type="appl";      break;
		    default:                        type="???";       break;
		    }
		    FIM_FBI_PRINTF("gif: extcode=0x%x [%s]\n",ExtCode,type);
		}
	    }
	    break;
	case TERMINATE_RECORD_TYPE:
	    if (FbiStuff::fim_filereading_debug())
		FIM_FBI_PRINTF("gif: TERMINATE_RECORD_TYPE found\n");
	    return RecordType;
	default:
	    if (FbiStuff::fim_filereading_debug())
		FIM_FBI_PRINTF("gif: unknown record type [%d]\n",RecordType);
	    return (GifRecordType)-1;
	}
    }
}
Ejemplo n.º 6
0
/******************************************************************************
 * Get an extension block (see GIF manual) from gif file. This routine only
 * returns the first data block, and DGifGetExtensionNext should be 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.
 *****************************************************************************/
static int
DGifGetExtension(GifFileType * GifFile,
                 int *ExtCode,
                 GifByteType ** Extension) {

    GifByteType Buf;

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

    return DGifGetExtensionNext(GifFile, Extension);
}
Ejemplo n.º 7
0
int GIFReadLoopCount(GifFileType* const gif, GifByteType** const buf,
                     int* const loop_count) {
  assert(!memcmp(*buf + 1, "NETSCAPE2.0", 11) ||
         !memcmp(*buf + 1, "ANIMEXTS1.0", 11));
  if (DGifGetExtensionNext(gif, buf) == GIF_ERROR) {
    return 0;
  }
  if (*buf == NULL) {
    return 0;  // Loop count sub-block missing.
  }
  if ((*buf)[0] < 3 || (*buf)[1] != 1) {
    return 0;   // wrong size/marker
  }
  *loop_count = (*buf)[2] | ((*buf)[3] << 8);
  return 1;
}
Ejemplo n.º 8
0
int GIFReadMetadata(GifFileType* const gif, GifByteType** const buf,
                    WebPData* const metadata) {
  const int is_xmp = !memcmp(*buf + 1, "XMP DataXMP", 11);
  const int is_icc = !memcmp(*buf + 1, "ICCRGBG1012", 11);
  assert(is_xmp || is_icc);
  (void)is_icc;  // silence unused warning.
  // Construct metadata from sub-blocks.
  // Usual case (including ICC profile): In each sub-block, the
  // first byte specifies its size in bytes (0 to 255) and the
  // rest of the bytes contain the data.
  // Special case for XMP data: In each sub-block, the first byte
  // is also part of the XMP payload. XMP in GIF also has a 257
  // byte padding data. See the XMP specification for details.
  while (1) {
    WebPData subblock;
    const uint8_t* tmp;
    if (DGifGetExtensionNext(gif, buf) == GIF_ERROR) {
      return 0;
    }
    if (*buf == NULL) break;  // Finished.
    subblock.size = is_xmp ? (*buf)[0] + 1 : (*buf)[0];
    assert(subblock.size > 0);
    subblock.bytes = is_xmp ? *buf : *buf + 1;
    // Note: We store returned value in 'tmp' first, to avoid
    // leaking old memory in metadata->bytes on error.
    tmp = (uint8_t*)realloc((void*)metadata->bytes,
                            metadata->size + subblock.size);
    if (tmp == NULL) {
      return 0;
    }
    memcpy((void*)(tmp + metadata->size),
           subblock.bytes, subblock.size);
    metadata->bytes = tmp;
    metadata->size += subblock.size;
  }
  if (is_xmp) {
    // XMP padding data is 0x01, 0xff, 0xfe ... 0x01, 0x00.
    const size_t xmp_pading_size = 257;
    if (metadata->size > xmp_pading_size) {
      metadata->size -= xmp_pading_size;
    }
  }
  return 1;
}
Ejemplo n.º 9
0
int fh_gif_getsize(const char *name,int *x,int *y, int /*wanted_width*/, int /*wanted_height*/)
{
	int px,py;
	GifFileType *gft;
	GifByteType *extension;
	int extcode;
	GifRecordType rt;
#if GIFLIB_MAJOR >= 5
	int error;

	gft=DGifOpenFileName(name, &error);
#else
	gft=DGifOpenFileName(name);
#endif
	if(gft==NULL) gflush;
	do
	{
		if(DGifGetRecordType(gft,&rt) == GIF_ERROR) grflush;
		switch(rt)
		{
			case IMAGE_DESC_RECORD_TYPE:

				if(DGifGetImageDesc(gft)==GIF_ERROR) grflush;
				px=gft->Image.Width;
				py=gft->Image.Height;
				*x=px; *y=py;
				DGIFCLOSEFILE(gft);
				return(FH_ERROR_OK);
				break;
			case EXTENSION_RECORD_TYPE:
				if(DGifGetExtension(gft,&extcode,&extension)==GIF_ERROR)	grflush;
				while(extension!=NULL)
					if(DGifGetExtensionNext(gft,&extension)==GIF_ERROR) grflush;
				break;
			default:
				break;
		}
	}
	while( rt!= TERMINATE_RECORD_TYPE );
	DGIFCLOSEFILE(gft);
	return(FH_ERROR_FORMAT);
}
Ejemplo n.º 10
0
static int DGifGetExtension(GifFileType * GifFile, int *ExtCode, GifByteType ** Extension)
{
	GifByteType Buf;
	GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;

	if (!IS_READABLE(Private))
	{
		_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);
}
Ejemplo n.º 11
0
/******************************************************************************
 Get an extension block (see GIF manual) from GIF file. This routine only
 returns the first data block, and DGifGetExtensionNext should be 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 description 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: */
        GifFile->Error = D_GIF_ERR_NOT_READABLE;
        return GIF_ERROR;
    }

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

    return DGifGetExtensionNext(GifFile, Extension);
}
Ejemplo n.º 12
0
int fh_gif_getsize(char *name,int *x,int *y)
{
    int px,py;
    GifFileType *gft;
    GifByteType *extension;
    int extcode;
    GifRecordType rt;

    gft=DGifOpenFileName(name);
    if(gft==NULL) gflush;
    do
    {
	if(DGifGetRecordType(gft,&rt) == GIF_ERROR) grflush;
	switch(rt)
	{
	    case IMAGE_DESC_RECORD_TYPE:

		if(DGifGetImageDesc(gft)==GIF_ERROR) grflush;
		px=gft->Image.Width;
		py=gft->Image.Height;
		*x=px; *y=py;
		DGifCloseFile(gft);
		return(FH_ERROR_OK);
		break;
	    case EXTENSION_RECORD_TYPE:
		if(DGifGetExtension(gft,&extcode,&extension)==GIF_ERROR) grflush;
		while(extension!=NULL)
		    if(DGifGetExtensionNext(gft,&extension)==GIF_ERROR) grflush;
		break;
	    default:
		break;
	}  
    }
    while( rt!= TERMINATE_RECORD_TYPE );
    DGifCloseFile(gft);
    return(FH_ERROR_FORMAT);
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
0
int
get_gif_saved_images( GifFileType *gif, int subimage, SavedImage **ret, int *ret_images  )
{
    GifRecordType RecordType;
    GifByteType *ExtData;
    SavedImage temp_save;
	int curr_image = 0, ret_count = *ret_images ;
	int status = GIF_OK;

	memset( &temp_save, 0x00, sizeof( temp_save ) );
	do
	{
		if ( (status = DGifGetRecordType(gif, &RecordType)) == GIF_ERROR)
		{
			break;
		}
		switch (RecordType)
		{
	    	case IMAGE_DESC_RECORD_TYPE:
				if ((status = get_gif_image_desc(gif, &temp_save)) == GIF_OK)
				{
					int size = temp_save.ImageDesc.Width*temp_save.ImageDesc.Height ;
					temp_save.RasterBits = realloc( temp_save.RasterBits, size );
					status = DGifGetLine(gif, (unsigned char*)temp_save.RasterBits, size);
					if (status == GIF_OK)
					{
						if( curr_image == subimage || subimage < 0 )
						{
							append_gif_saved_image( &temp_save, ret, &(ret_count));
						}
					}
					++curr_image ;
				}
				break;

	    	case EXTENSION_RECORD_TYPE:
				status = DGifGetExtension(gif,&temp_save.Function,&ExtData);
				while (ExtData != NULL && status == GIF_OK )
				{
            		/* Create an extension block with our data */
            		if ((status = AddExtensionBlock(&temp_save, ExtData[0], (char*)&(ExtData[1]))) == GIF_OK)
				    	status = DGifGetExtensionNext(gif, &ExtData);
            		temp_save.Function = 0;
				}
				break;

	    	case TERMINATE_RECORD_TYPE:
				break;

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

/*	if( status == GIF_OK && *ret == NULL )
		append_gif_saved_image( &temp_save, ret, &(ret_count));
	else
*/
	free_gif_saved_image( &temp_save, True );

	*ret_images = ret_count ;
    return status;
}
Ejemplo n.º 16
0
CPLErr BIGGIFDataset::ReOpen()

{
/* -------------------------------------------------------------------- */
/*      If the file is already open, close it so we can restart.        */
/* -------------------------------------------------------------------- */
    if( hGifFile != NULL )
        DGifCloseFile( hGifFile );

/* -------------------------------------------------------------------- */
/*      If we are actually reopening, then we assume that access to     */
/*      the image data is not strictly once through sequential, and     */
/*      we will try to create a working database in a temporary         */
/*      directory to hold the image as we read through it the second    */
/*      time.                                                           */
/* -------------------------------------------------------------------- */
    if( hGifFile != NULL )
    {
        GDALDriver *poGTiffDriver = (GDALDriver*) GDALGetDriverByName("GTiff");
        
        if( poGTiffDriver != NULL )
        {
            /* Create as a sparse file to avoid filling up the whole file */
            /* while closing and then destroying this temporary dataset */
            const char* apszOptions[] = { "COMPRESS=LZW", "SPARSE_OK=YES", NULL };
            CPLString osTempFilename = CPLGenerateTempFilename("biggif");

            osTempFilename += ".tif";

            poWorkDS = poGTiffDriver->Create( osTempFilename, 
                                              nRasterXSize, nRasterYSize, 1, 
                                              GDT_Byte, const_cast<char**>(apszOptions));
        }
    }

/* -------------------------------------------------------------------- */
/*      Open                                                            */
/* -------------------------------------------------------------------- */
    VSIFSeekL( fp, 0, SEEK_SET );

    nLastLineRead = -1;
#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
    int nError;
    hGifFile = DGifOpen( fp, VSIGIFReadFunc, &nError );
#else
    hGifFile = DGifOpen( fp, VSIGIFReadFunc );
#endif
    if( hGifFile == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "DGifOpen() failed.  Perhaps the gif file is corrupt?\n" );

        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Find the first image record.                                    */
/* -------------------------------------------------------------------- */
    GifRecordType RecordType = TERMINATE_RECORD_TYPE;

    while( DGifGetRecordType(hGifFile, &RecordType) != GIF_ERROR
           && RecordType != TERMINATE_RECORD_TYPE
           && RecordType != IMAGE_DESC_RECORD_TYPE )
    {
        /* Skip extension records found before IMAGE_DESC_RECORD_TYPE */
        if (RecordType == EXTENSION_RECORD_TYPE)
        {
            int nFunction;
            GifByteType *pExtData;
            if (DGifGetExtension(hGifFile, &nFunction, &pExtData) == GIF_ERROR)
                break;
            while (pExtData != NULL)
            {
                if (DGifGetExtensionNext(hGifFile, &pExtData) == GIF_ERROR)
                    break;
            }
        }
    }

    if( RecordType != IMAGE_DESC_RECORD_TYPE )
    {
        DGifCloseFile( hGifFile );
        hGifFile = NULL;

        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to find image description record in GIF file." );
        return CE_Failure;
    }
    
    if (DGifGetImageDesc(hGifFile) == GIF_ERROR)
    {
        DGifCloseFile( hGifFile );
        hGifFile = NULL;

        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Image description reading failed in GIF file." );
        return CE_Failure;
    }
    
    return CE_None;
}
Ejemplo n.º 17
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, j, Error, NumFiles, ExtCode, Row, Col, Width, Height,
	DarkestColor = 0, ColorIntens = 10000, HelpFlag = FALSE;
    GifRecordType RecordType;
    GifByteType *Extension;
    char **FileName = NULL;
    GifRowType LineBuffer;
    ColorMapObject *ColorMap;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &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);
    }

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

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

    if ((LineBuffer = (GifRowType) malloc(GifFileIn->SWidth)) == NULL)
	GIF_EXIT("Failed to allocate memory required, aborted.");

    /* 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.Interlace)
		    GIF_EXIT("Cannt fix interlaced images.");

		Row = GifFileIn->Image.Top; /* Image Position relative to Screen. */
		Col = GifFileIn->Image.Left;
		Width = GifFileIn->Image.Width;
		Height = GifFileIn->Image.Height;
		GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
		    PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);

		/* Put the image descriptor to out file: */
		if (EGifPutImageDesc(GifFileOut, Col, Row, Width, Height,
		    FALSE, GifFileIn->Image.ColorMap) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		/* Find the darkest color in color map to use as a filler. */
		ColorMap = (GifFileIn->Image.ColorMap ? GifFileIn->Image.ColorMap :
						     GifFileIn->SColorMap);
		for (i = 0; i < ColorMap->ColorCount; i++) {
		    j = ((int) ColorMap->Colors[i].Red) * 30 +
			((int) ColorMap->Colors[i].Green) * 59 +
			((int) ColorMap->Colors[i].Blue) * 11;
		    if (j < ColorIntens) {
			ColorIntens = j;
			DarkestColor = i;
		    }
		}

		/* Load the image, and dump it. */
		for (i = 0; i < Height; i++) {
		    GifQprintf("\b\b\b\b%-4d", i);
		    if (DGifGetLine(GifFileIn, LineBuffer, Width)
			== GIF_ERROR) break;
		    if (EGifPutLine(GifFileOut, LineBuffer, Width)
			== GIF_ERROR) QuitGifError(GifFileIn, GifFileOut);
		}

		if (i < Height) {
		    fprintf(stderr, "\nFollowing error occured (and ignored):");
		    PrintGifError();

		    /* Fill in with the darkest color in color map. */
		    for (j = 0; j < Width; j++)
			LineBuffer[j] = DarkestColor;
		    for (; i < Height; i++)
			if (EGifPutLine(GifFileOut, LineBuffer, Width)
			    == 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 (Extension && 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;
}
Ejemplo n.º 18
0
static GifRowType *DGifDecompress(GifFileType *gifFile, short *transparentColor)
{
	static int InterlacedOffset[] =
	{ 0, 4, 2, 1 }, InterlacedJumps[] =
	{ 8, 8, 4, 2 };

	int i, j, row, col, width, height = 0;
	GifRowType *ScreenBuffer = NULL;

	int rowSize = gifFile->SWidth * sizeof(GifPixelType);

	ScreenBuffer = (GifRowType *) gif_malloc(gifFile->SHeight * sizeof(GifRowType *));
	if (ScreenBuffer == NULL)
	{
		return NULL;
	}

	int Size = gifFile->SWidth * sizeof(GifPixelType);
	ScreenBuffer[0] = (GifRowType) gif_malloc(Size);
	if (ScreenBuffer[0] == NULL)
	{
		goto cleanup;
	}

	for (i = 0; i < gifFile->SWidth; i++)
	{
		ScreenBuffer[0][i] = gifFile->SBackGroundColor;
	}
	for (i = 1; i < gifFile->SHeight; i++)
	{
		ScreenBuffer[i] = (GifRowType) gif_malloc(Size);
		if (ScreenBuffer[i] == NULL)
		{
			goto cleanup;
		}
		memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
	}

	*transparentColor = GIF_NOT_TRANSPARENT;

	GifRecordType recordType;
	do
	{
		if (DGifGetRecordType(gifFile, &recordType) == GIF_ERROR)
		{
			goto cleanup;
		}
		switch (recordType)
		{
			case IMAGE_DESC_RECORD_TYPE:
			{
				if (DGifGetImageDesc(gifFile) == GIF_ERROR)
				{
					goto cleanup;
				}

				row = gifFile->Image.Top;
				col = gifFile->Image.Left;
				width = gifFile->Image.Width;
				height = gifFile->Image.Height;

				GifPixelType *gifPixelType;
				int location = 0;
				if (gifFile->Image.Interlace)
				{
					for (i = 0; i < 4; i++)
					{
						for (j = row + InterlacedOffset[i]; j < row + height; j += InterlacedJumps[i])
						{
							gifPixelType = &ScreenBuffer[j][col];
							if (DGifGetLine(gifFile, gifPixelType, width) == GIF_ERROR)
							{
								goto cleanup;
							}
							location += rowSize;
						}
					}
				}
				else
				{
					for (i = 0; i < height; i++)
					{
						if (DGifGetLine(gifFile, &ScreenBuffer[row++][col], width) == GIF_ERROR)
						{
							goto cleanup;
						}
					}
				}
				break;
			}
			case EXTENSION_RECORD_TYPE:
			{
				GifByteType *extension;
				int extCode;
				if (DGifGetExtension(gifFile, &extCode, &extension) == GIF_ERROR)
				{
					goto cleanup;
				}
				switch (extCode)
				{
					case GRAPHICS_EXT_FUNC_CODE:
					{
						int flag = extension[1];
						*transparentColor = (flag & GIF_TRANSPARENT) ? extension[4] : GIF_NOT_TRANSPARENT;
						break;
					}
				}
				while (extension != NULL)
				{
					if (DGifGetExtensionNext(gifFile, &extension) == GIF_ERROR)
					{
						goto cleanup;
					}
				}
				break;
			}
			case TERMINATE_RECORD_TYPE:
			case UNDEFINED_RECORD_TYPE:
			default:
				break;
		}
	} while (recordType != TERMINATE_RECORD_TYPE);

	goto finish;

	cleanup: if (ScreenBuffer != NULL)
	{
		gif_free(ScreenBuffer);
		ScreenBuffer = NULL;
	}
	finish: return ScreenBuffer;
}
GDALDataset *GIFDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( !Identify( poOpenInfo ) )
        return NULL;

    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The GIF driver does not support update access to existing"
                  " files.\n" );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Open the file and ingest.                                       */
/* -------------------------------------------------------------------- */
    GifFileType 	*hGifFile;
    VSILFILE                *fp;
    int                  nGifErr;

    fp = VSIFOpenL( poOpenInfo->pszFilename, "r" );
    if( fp == NULL )
        return NULL;

    hGifFile = GIFAbstractDataset::myDGifOpen( fp, VSIGIFReadFunc );
    if( hGifFile == NULL )
    {
        VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "DGifOpen() failed for %s.\n"
                  "Perhaps the gif file is corrupt?\n",
                  poOpenInfo->pszFilename );

        return NULL;
    }

    /* The following code enables us to detect GIF datasets eligible */
    /* for BIGGIF driver even with an unpatched giflib  */

    /* -------------------------------------------------------------------- */
    /*      Find the first image record.                                    */
    /* -------------------------------------------------------------------- */
    GifRecordType RecordType = TERMINATE_RECORD_TYPE;

    while( DGifGetRecordType(hGifFile, &RecordType) != GIF_ERROR
        && RecordType != TERMINATE_RECORD_TYPE
        && RecordType != IMAGE_DESC_RECORD_TYPE )
    {
        /* Skip extension records found before IMAGE_DESC_RECORD_TYPE */
        if (RecordType == EXTENSION_RECORD_TYPE)
        {
            int nFunction;
            GifByteType *pExtData;
            if (DGifGetExtension(hGifFile, &nFunction, &pExtData) == GIF_ERROR)
                break;
            while (pExtData != NULL)
            {
                if (DGifGetExtensionNext(hGifFile, &pExtData) == GIF_ERROR)
                    break;
            }
        }
    }

    if( RecordType == IMAGE_DESC_RECORD_TYPE  &&
        DGifGetImageDesc(hGifFile) != GIF_ERROR)
    {
        int width = hGifFile->SavedImages[0].ImageDesc.Width;
        int height = hGifFile->SavedImages[0].ImageDesc.Height;
        if ((double) width * (double) height > 100000000.0 )
        {
            CPLDebug( "GIF",
                      "Due to limitations of the GDAL GIF driver we deliberately avoid\n"
                      "opening large GIF files (larger than 100 megapixels).");
            GIFAbstractDataset::myDGifCloseFile( hGifFile );
            VSIFCloseL( fp );
            return NULL;
        }
    }

    GIFAbstractDataset::myDGifCloseFile( hGifFile );

    VSIFSeekL( fp, 0, SEEK_SET);

    hGifFile = GIFAbstractDataset::myDGifOpen( fp, VSIGIFReadFunc );
    if( hGifFile == NULL )
    {
        VSIFCloseL( fp );
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "DGifOpen() failed for %s.\n"
                  "Perhaps the gif file is corrupt?\n",
                  poOpenInfo->pszFilename );

        return NULL;
    }

    nGifErr = DGifSlurp( hGifFile );

    if( nGifErr != GIF_OK || hGifFile->SavedImages == NULL )
    {
        VSIFCloseL( fp );
        GIFAbstractDataset::myDGifCloseFile(hGifFile);

        if( nGifErr == D_GIF_ERR_DATA_TOO_BIG )
        {
             CPLDebug( "GIF",
                       "DGifSlurp() failed for %s because it was too large.\n"
                       "Due to limitations of the GDAL GIF driver we deliberately avoid\n"
                       "opening large GIF files (larger than 100 megapixels).",
                       poOpenInfo->pszFilename );
            return NULL;
         }
         else
            CPLError( CE_Failure, CPLE_OpenFailed, 
                        "DGifSlurp() failed for %s.\n"
                        "Perhaps the gif file is corrupt?\n",
                        poOpenInfo->pszFilename );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    GIFDataset 	*poDS;

    poDS = new GIFDataset();

    poDS->fp = fp;
    poDS->eAccess = GA_ReadOnly;
    poDS->hGifFile = hGifFile;

/* -------------------------------------------------------------------- */
/*      Capture some information from the file that is of interest.     */
/* -------------------------------------------------------------------- */
    poDS->nRasterXSize = hGifFile->SavedImages[0].ImageDesc.Width;
    poDS->nRasterYSize = hGifFile->SavedImages[0].ImageDesc.Height;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    for( int iImage = 0; iImage < hGifFile->ImageCount; iImage++ )
    {
        SavedImage	*psImage = hGifFile->SavedImages + iImage;

        if( psImage->ImageDesc.Width != poDS->nRasterXSize
            || psImage->ImageDesc.Height != poDS->nRasterYSize )
            continue;

        poDS->SetBand( poDS->nBands+1, 
                       new GIFRasterBand( poDS, poDS->nBands+1, psImage,
                                          hGifFile->SBackGroundColor ));
    }

/* -------------------------------------------------------------------- */
/*      Check for georeferencing.                                       */
/* -------------------------------------------------------------------- */
    poDS->DetectGeoreferencing(poOpenInfo);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return poDS;
}
Ejemplo n.º 20
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
void main(int argc, char **argv)
{
    int	i, j, k, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode,
	Count, ColorMapSize, GraphDriver, GraphMode, Sum,
	HelpFlag = FALSE,
	BGIPathFlag = FALSE,
	BGIUserDriverFlag = FALSE,
	ZoomFlag = FALSE;
    GifRecordType RecordType;
    GifByteType *Extension;
    char Str[80], *BGIUserDriverNameMode,
	**FileName = NULL;
    GifRowType *ScreenBuffer;
    GifFileType *GifFile;
    struct text_info TextInfo;      /* So we can restore starting text mode. */

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifQuitePrint, &BGIPathFlag, &BGIPath,
		&BGIUserDriverFlag, &BGIUserDriverNameMode,
		&ZoomFlag, &ZoomFactor,
		&BeepsDisabled, &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(1);
    }

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

    if (BGIUserDriverFlag) {
	/* Use the driver supplied by the user! */
        BGIInstallUserDriver(BGIUserDriverNameMode);
        installuserdriver(BGIUserDriverName, detectVGA);
	GraphDriver = BGI_USER_INSTALL;
    }
    else {
        /* Sense type of display we have and attempt to load right driver. */
        detectgraph(&GraphDriver, &GraphMode);
        if (GraphDriver < 0)
	    GIF_EXIT("BGI Auto detect: No graphics device detected.");
    }

    /* Put in the following any graphic driver specific setup: */
    switch (GraphDriver) {
	case CGA:
	    GraphMode = CGAHI;
	    break;
	case EGA:
	    GraphMode = EGAHI;
	    break;
	case EGA64:
	    GraphMode = EGA64HI;
	    break;
	case EGAMONO:
	    GraphMode = EGAMONOHI;
	    break;
	case HERCMONO:
	    GraphMode = HERCMONOHI;
	    break;
	case VGA:
	    GraphMode = VGAHI;
	    break;
	case BGI_USER_INSTALL:
	    GraphDriver = DETECT;
	    GraphMode = BGIUserDriverMode;
	    break;
	default:
	    GIF_EXIT("Requested graphic device is not supported.");
	    break;
    }

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

    /* Allocate the screen as vector of column of rows. We cannt allocate    */
    /* the all screen at once, as this broken minded CPU can allocate up to  */
    /* 64k at a time and our image can be bigger than that:		     */
    /* Note this screen is device independent - its the screen as defined by */
    /* the GIF file parameters itself.					     */
    if ((ScreenBuffer = (GifRowType *)
	malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");

    Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes of one row.*/
    if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL)    /* First row. */
	GIF_EXIT("Failed to allocate memory required, aborted.");

    for (i = 0; i < GifFile -> SWidth; i++)  /* Set its color to BackGround. */
	ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
    MaximumScreenHeight = GifFile -> SHeight - 1;
    for (i = 1; i < GifFile -> SHeight; i++) {
	/* Allocate the other rows, and set their color to background too: */
	if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL) {
	    if (i > 30) {
		/* Free some memory for the BGI driver and auxilary. */
		for (j = 1; j < 28; j++)
	    	    free((char *) ScreenBuffer[i - j]);
	    	MaximumScreenHeight = i - 28;
	    	fprintf(stderr, "\n%s: Failed to allocate all memory required, last line %d.\n",
			PROGRAM_NAME, MaximumScreenHeight);
	    	break;
	    }
	    else
		GIF_EXIT("Failed to allocate memory required, aborted.");
	}

	memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
    }

    /* Scan the content of the GIF file and load the image(s) in: */
    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
	    PrintGifError();
	    break;
	}
	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
		    PrintGifError();
		    exit(-1);
		}

		Row = GifFile -> ITop; /* Image Position relative to Screen. */
		Col = GifFile -> ILeft;
		Width = GifFile -> IWidth;
		Height = GifFile -> IHeight;
		GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
		    PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
		if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
		   GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
		    fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
		    exit(-2);
		}
		if (GifFile -> IInterlace) {
		    /* Need to perform 4 passes on the images: */
		    for (Count = i = 0; i < 4; i++)
			for (j = Row + InterlacedOffset[i]; j < Row + Height;
						 j += InterlacedJumps[i]) {
			    GifQprintf("\b\b\b\b%-4d", Count++);
			    if (DGifGetLine(GifFile,
				&ScreenBuffer[MIN(j, MaximumScreenHeight)][Col],
				Width) == GIF_ERROR) {
				PrintGifError();
				exit(-1);
			    }
			}
		}
		else {
		    for (i = 0; i < Height; i++, Row++) {
			GifQprintf("\b\b\b\b%-4d", i);
			if (DGifGetLine(GifFile, &ScreenBuffer[MIN(Row, MaximumScreenHeight)][Col],
				Width) == GIF_ERROR) {
			    PrintGifError();
			    MaximumScreenHeight = MIN(i - 1, MaximumScreenHeight);
			}
		    }
		}
		break;
	    case EXTENSION_RECORD_TYPE:
		/* Skip any extension blocks in file: */
		if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
		    PrintGifError();
		    exit(-1);
		}
		while (Extension != NULL) {
		    if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
			PrintGifError();
			exit(-1);
		    }
		}
		break;
	    case TERMINATE_RECORD_TYPE:
		break;
	    default:		    /* Should be traps by DGifGetRecordType. */
		break;
	}
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    /* Lets display it - set the global variables required and do it: */
    BackGround = GifFile -> SBackGroundColor;
    ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
				       GifFile -> SColorMap);
    ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
						GifFile -> SBitsPerPixel);

    gettextinfo(&TextInfo);	     /* Save current mode so we can recover. */

    initgraph(&GraphDriver, &GraphMode, BGIPath);
    if (graphresult() != grOk)	 	       /* Error occured during init. */
	GIF_EXIT("Graphics System Error, failed to initialize driver.");

    if (getmaxcolor() + 1 < ColorMapSize) {
	sprintf(Str, "GIF Image color map (%d) is too big for device (%d).\n",
					      ColorMapSize, getmaxcolor() + 1);
	closegraph();
	GIF_EXIT(Str);
    }

    /* Initialize hardware pallete and also select fore/background color.    */
    BackGround = ForeGround = 1;
    Sum = ((int) ColorMap[1].Red) +
	  ((int) ColorMap[1].Green) +
	  ((int) ColorMap[1].Blue);
    j = k = Sum;
    for (i = 0; i < ColorMapSize; i++) {
	setrgbpalette(i, ColorMap[i].Red >> 2,
			 ColorMap[i].Green >> 2,
			 ColorMap[i].Blue >> 2);

	Sum = ((int) ColorMap[i].Red) +
	      ((int) ColorMap[i].Green) +
	      ((int) ColorMap[i].Blue);
	if (i != 0 && Sum > j) {			/* Dont use color 0. */
	    ForeGround = i;
	    j = Sum;
	}
	if (i != 0 && Sum <= k) {			/* Dont use color 0. */
	    BackGround = i;
	    k = Sum;
	}
    }

    DeviceMaxX = getmaxx();		    /* Read size of physical screen. */
    DeviceMaxY = getmaxy();
    ScreenWidth = GifFile -> SWidth;
    ScreenHeight = MIN(GifFile -> SHeight, MaximumScreenHeight);

    Tone(500, 10);
    DisplayScreen(ScreenBuffer, GifFile);

    if (DGifCloseFile(GifFile) == GIF_ERROR) {
	PrintGifError();
	closegraph();
	exit(-1);
    }

    closegraph();

    textmode(TextInfo.currmode);
}
Ejemplo n.º 21
0
int main(int argc, char **argv) {
   //
   // local vars
   //
   GifFileType *GIFfile;
   GifRecordType GIFtype;
   GifByteType *GIFextension;
   GifPixelType *GIFline;
   uint32_t w[8],**lower_array,**upper_array;
   int x,y,z,i,j,k,n,p,imin,imax;
   int image_width,image_height,image_count,color_resolution,GIFcode,ret;
   float threshold,voxel_size;
   char comment[256],rules[255][20];
   struct fab_vars v;
   init_vars(&v);
   //
   // command line args
   //
   if (!((argc == 3) || (argc == 4) || (argc == 5) || (argc == 6))) {
      printf("command line: gif_stl in.gif out.stl [threshold [size [points [angle]]]]\n");
      printf("   in.gif = input GIF section file\n");
      printf("   out.stl = output STL file\n");
      printf("   threshold: surface intensity threshold (0 = min, 1 = max, default 0.5))\n");
      printf("   size = voxel size (mm, default from file))\n");
      printf("   points = points to interpolate per point (default 0)\n");
      printf("   to be implemented: angle = minimum relative face angle to decimate vertices (default 0)\n");
      exit(-1);
      }
   p = 0;
   threshold = 0.5;
   voxel_size = -1;
   image_width = -1;
   image_height = -1;
   image_count = -1;
   if (argc >= 4)
      sscanf(argv[3],"%f",&threshold);
   if (argc >= 5)
      sscanf(argv[4],"%f",&voxel_size);
   if (argc >= 6)
      sscanf(argv[5],"%d",&p);
   //
   // initialize the rule table
   //
   init_rules(rules);
   //
   // scan the file 
   //
   printf("read %s\n",argv[1]);
   color_resolution = -1;
#if GIFLIB_MAJOR >= 5
   GIFfile = DGifOpenFileName(argv[1], NULL);
#else
   GIFfile = DGifOpenFileName(argv[1]);
#endif
   if (GIFfile == NULL) {
      printf("gif_stl: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   GIFline = malloc(MAX_LINE*sizeof(GifPixelType));
   imin = 256;
   imax = 0;
   do {
      DGifGetRecordType(GIFfile,&GIFtype);
      switch (GIFtype) {
         case IMAGE_DESC_RECORD_TYPE:
            DGifGetImageDesc(GIFfile);
            image_width = GIFfile->SWidth;
            image_height = GIFfile->SHeight;
            image_count = GIFfile->ImageCount;
            color_resolution = GIFfile->SColorResolution;
            for (y = 0; y < GIFfile->SHeight; ++y) {
               ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth);
               if (ret != GIF_OK) {
                  printf("gif_stl: oops -- error reading line\n");
                  exit(-1);
                  }
               for (x = 0; x < GIFfile->SWidth; ++x) {
                  if (GIFline[x] < imin) imin = GIFline[x];
                  if (GIFline[x] > imax) imax = GIFline[x];
                  }
               }
            break;
         case EXTENSION_RECORD_TYPE:
            DGifGetExtension(GIFfile,&GIFcode,&GIFextension);
            if (GIFcode == COMMENT_EXT_FUNC_CODE) {
               n = GIFextension[0];
               for (i = 1; i <= n; ++i)
                  comment[i-1] = GIFextension[i];
               comment[n] = 0;
               if (voxel_size == -1)
                  sscanf(comment,"mm per pixel: %f;",&voxel_size);
               }
            while (GIFextension != NULL)
               DGifGetExtensionNext(GIFfile,&GIFextension);
            break;
         case SCREEN_DESC_RECORD_TYPE:
            DGifGetScreenDesc(GIFfile);
            break;
         case TERMINATE_RECORD_TYPE:
            break;
         case UNDEFINED_RECORD_TYPE:
            printf("gif_stl: oops -- undefined GIF record type\n");
            exit(-1);
            break;
         }
      } while (GIFtype != TERMINATE_RECORD_TYPE);
   if (GIFfile == NULL) {
      printf("gif_stl: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   if (voxel_size == -1) {
      voxel_size = 1.0;
      printf("   no pixel size found, assuming 1 mm\n");
      }
   printf("   voxel size (mm): %f, color resolution (bits): %d\n",voxel_size,color_resolution);
   printf("   intensity min: %d max: %d\n",imin,imax);
   printf("   number of images: %d, image width %d, image height %d\n",image_count,image_width,image_height);
   //
   // set threshold
   //
   threshold = imin + threshold*(imax-imin);
   //
   // add empty border
   //
   image_width += 2;
   image_height += 2;
   image_count += 2;
   //
   // allocate arrays
   //
   lower_array = malloc(image_height*sizeof(uint32_t *));
   for (y = 0; y < image_height; ++y) {
      lower_array[y] = malloc(image_width*sizeof(uint32_t));
      for (x = 0; x < image_width; ++x)
         lower_array[y][x] = 0;
      }
   upper_array = malloc(image_height*sizeof(uint32_t *));
   for (y = 0; y < image_height; ++y) {
      upper_array[y] = malloc(image_width*sizeof(uint32_t));
      for (x = 0; x < image_width; ++x)
         upper_array[y][x] = 0;
      }
   //
   // read the file
   //
   DGifCloseFile(GIFfile);
#if GIFLIB_MAJOR >= 5
   GIFfile = DGifOpenFileName(argv[1], NULL);
#else
   GIFfile = DGifOpenFileName(argv[1]);
#endif
   if (GIFfile == NULL) {
      printf("gif_stl: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   z = 0;
   v.mesh = malloc(sizeof(struct fab_mesh_type));
   v.mesh->triangle = malloc(sizeof(struct fab_mesh_triangle_type));
   v.mesh->first = v.mesh->triangle;
   v.mesh->last = v.mesh->triangle;
   v.mesh->triangle->previous = v.mesh->triangle->next = 0;
   do {
      DGifGetRecordType(GIFfile,&GIFtype);
      switch (GIFtype) {
         case IMAGE_DESC_RECORD_TYPE:
            //
            // read image
            //
            DGifGetImageDesc(GIFfile);
            printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b   layer = %d",z);
            //
            // read layer
            //
            for (y = 0; y < (image_height-2); ++y) {
               ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth);
               if (ret != GIF_OK) {
                  printf("gif_stl: oops -- error reading line\n");
                  exit(-1);
                  }
               for (x = 0; x < (image_width-2); ++x) {
                  lower_array[y+1][x+1] = upper_array[y+1][x+1];
                  upper_array[y+1][x+1] = GIFline[x];
                  }
               }
            if (p == 0) {
               //
               // no interpolation, loop over layer voxels
               //
               for (x = 0; x < (image_width-1); ++x) {
                  for (y = 0; y < (image_height-1); ++y) {
                     w[0] = lower_array[y][x];
                     w[1] = lower_array[y][x+1];
                     w[2] = lower_array[y+1][x];
                     w[3] = lower_array[y+1][x+1];
                     w[4] = upper_array[y][x];
                     w[5] = upper_array[y][x+1];
                     w[6] = upper_array[y+1][x];
                     w[7] = upper_array[y+1][x+1];
                     triangulate(x,y,z,voxel_size,threshold,w,rules,&v);
                     }
                  }
               }
            else {
               //
               // yes interpolation, loop over layer sub-voxels
               //
               for (x = 0; x < (image_width-1); ++x) {
                  for (y = 0; y < (image_height-1); ++y) {
                     for (i = 0; i <= p; ++i) {
                        for (j = 0; j <= p; ++j) {
                           for (k = 0; k <= p; ++k) {
                              w[0] = interp(x,y,i,j,k,lower_array,upper_array,p);
                              w[1] = interp(x,y,i+1,j,k,lower_array,upper_array,p);
                              w[2] = interp(x,y,i,j+1,k,lower_array,upper_array,p);
                              w[3] = interp(x,y,i+1,j+1,k,lower_array,upper_array,p);
                              w[4] = interp(x,y,i,j,k+1,lower_array,upper_array,p);
                              w[5] = interp(x,y,i+1,j,k+1,lower_array,upper_array,p);
                              w[6] = interp(x,y,i,j+1,k+1,lower_array,upper_array,p);
                              w[7] = interp(x,y,i+1,j+1,k+1,lower_array,upper_array,p);
                              triangulate((1+p)*x+i,(1+p)*y+j,(1+p)*z+k,voxel_size,threshold,w,rules,&v);
                              }
                           }
                        }
                     }
                  }
               }
            z += 1;
            break;
         case EXTENSION_RECORD_TYPE:
            DGifGetExtension(GIFfile,&GIFcode,&GIFextension);
            while (GIFextension != NULL)
               DGifGetExtensionNext(GIFfile,&GIFextension);
            break;
         case SCREEN_DESC_RECORD_TYPE:
            DGifGetScreenDesc(GIFfile);
            break;
         case TERMINATE_RECORD_TYPE:
            break;
         case UNDEFINED_RECORD_TYPE:
            printf("gif_stl: oops -- undefined GIF record type\n");
            exit(-1);
            break;
         }
      } while (GIFtype != TERMINATE_RECORD_TYPE);
   //
   // add empty top layer
   //
   printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b   layer = %d",z);
   for (y = 0; y < (image_height-2); ++y) {
      for (x = 0; x < (image_width-2); ++x) {
         lower_array[y+1][x+1] = upper_array[y+1][x+1];
         upper_array[y+1][x+1] = 0;
         }
      }
   if (p == 0) {
      //
      // no interpolation, loop over layer voxels
      //
      for (x = 0; x < (image_width-1); ++x) {
         for (y = 0; y < (image_height-1); ++y) {
            w[0] = lower_array[y][x];
            w[1] = lower_array[y][x+1];
            w[2] = lower_array[y+1][x];
            w[3] = lower_array[y+1][x+1];
            w[4] = upper_array[y][x];
            w[5] = upper_array[y][x+1];
            w[6] = upper_array[y+1][x];
            w[7] = upper_array[y+1][x+1];
            triangulate(x,y,z,voxel_size,threshold,w,rules,&v);
            }
         }
      }
   else {
      //
      // yes interpolation, loop over layer sub-voxels
      //
      for (x = 0; x < (image_width-1); ++x) {
         for (y = 0; y < (image_height-1); ++y) {
            for (i = 0; i <= p; ++i) {
               for (j = 0; j <= p; ++j) {
                  for (k = 0; k <= p; ++k) {
                     w[0] = interp(x,y,i,j,k,lower_array,upper_array,p);
                     w[1] = interp(x,y,i+1,j,k,lower_array,upper_array,p);
                     w[2] = interp(x,y,i,j+1,k,lower_array,upper_array,p);
                     w[3] = interp(x,y,i+1,j+1,k,lower_array,upper_array,p);
                     w[4] = interp(x,y,i,j,k+1,lower_array,upper_array,p);
                     w[5] = interp(x,y,i+1,j,k+1,lower_array,upper_array,p);
                     w[6] = interp(x,y,i,j+1,k+1,lower_array,upper_array,p);
                     w[7] = interp(x,y,i+1,j+1,k+1,lower_array,upper_array,p);
                     triangulate((1+p)*x+i,(1+p)*y+j,(1+p)*z+k,voxel_size,threshold,w,rules,&v);
                     }
                  }
               }
            }
         }
      }
   printf("\n");
   //
   // write STL
   //
   fab_write_stl(&v,argv[2]);
   //
   // exit
   //
   DGifCloseFile(GIFfile);
   exit(0);
   }
Ejemplo n.º 22
0
Archivo: gif.c Proyecto: crmafra/wmaker
/*
 * Partially based on code in gif2rgb from giflib, by Gershon Elber.
 */
RImage *RLoadGIF(const char *file, int index)
{
	RImage *image = NULL;
	unsigned char *cptr;
	GifFileType *gif = NULL;
	GifPixelType *buffer = NULL;
	int i, j, k;
	int width, height;
	GifRecordType recType;
	ColorMapObject *colormap;
	unsigned char rmap[256];
	unsigned char gmap[256];
	unsigned char bmap[256];

	if (index < 0)
		index = 0;

	/* default error message */
	RErrorCode = RERR_BADINDEX;

	gif = DGifOpenFileName(file);

	if (!gif) {
		switch (GifLastError()) {
		case D_GIF_ERR_OPEN_FAILED:
			RErrorCode = RERR_OPEN;
			break;
		case D_GIF_ERR_READ_FAILED:
			RErrorCode = RERR_READ;
			break;
		default:
			RErrorCode = RERR_BADIMAGEFILE;
			break;
		}
		return NULL;
	}

	if (gif->SWidth < 1 || gif->SHeight < 1) {
		DGifCloseFile(gif);
		RErrorCode = RERR_BADIMAGEFILE;
		return NULL;
	}

	colormap = gif->SColorMap;

	i = 0;

	do {
		int extCode;
		GifByteType *extension;

		if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
			goto giferr;
		}
		switch (recType) {
		case IMAGE_DESC_RECORD_TYPE:
			if (i++ != index)
				break;

			if (DGifGetImageDesc(gif) == GIF_ERROR) {
				goto giferr;
			}

			width = gif->Image.Width;
			height = gif->Image.Height;

			if (gif->Image.ColorMap)
				colormap = gif->Image.ColorMap;

			/* the gif specs talk about a default colormap, but it
			 * doesnt say what the heck is this default colormap */
			if (!colormap) {
				/*
				 * Well, since the spec says the colormap can be anything,
				 * lets just render it with whatever garbage the stack
				 * has :)
				 *

				 goto bye;
				 */
			} else {
				for (j = 0; j < colormap->ColorCount; j++) {
					rmap[j] = colormap->Colors[j].Red;
					gmap[j] = colormap->Colors[j].Green;
					bmap[j] = colormap->Colors[j].Blue;
				}
			}

			buffer = malloc(width * sizeof(GifColorType));
			if (!buffer) {
				RErrorCode = RERR_NOMEMORY;
				goto bye;
			}

			image = RCreateImage(width, height, False);
			if (!image) {
				goto bye;
			}

			if (gif->Image.Interlace) {
				int l;
				int pelsPerLine;

				if (RRGBAFormat == image->format)
					pelsPerLine = width * 4;
				else
					pelsPerLine = width * 3;

				for (j = 0; j < 4; j++) {
					for (k = InterlacedOffset[j]; k < height; k += InterlacedJumps[j]) {
						if (DGifGetLine(gif, buffer, width) == GIF_ERROR) {
							goto giferr;
						}
						cptr = image->data + (k * pelsPerLine);
						for (l = 0; l < width; l++) {
							int pixel = buffer[l];
							*cptr++ = rmap[pixel];
							*cptr++ = gmap[pixel];
							*cptr++ = bmap[pixel];
						}
					}
				}
			} else {
				cptr = image->data;
				for (j = 0; j < height; j++) {
					if (DGifGetLine(gif, buffer, width) == GIF_ERROR) {
						goto giferr;
					}
					for (k = 0; k < width; k++) {
						int pixel = buffer[k];
						*cptr++ = rmap[pixel];
						*cptr++ = gmap[pixel];
						*cptr++ = bmap[pixel];
						if (RRGBAFormat == image->format)
							cptr++;
					}
				}
			}
			break;

		case EXTENSION_RECORD_TYPE:
			/* skip all extension blocks */
			if (DGifGetExtension(gif, &extCode, &extension) == GIF_ERROR) {
				goto giferr;
			}
			while (extension) {
				if (DGifGetExtensionNext(gif, &extension) == GIF_ERROR) {
					goto giferr;
				}
			}
			break;

		default:
			break;
		}
	} while (recType != TERMINATE_RECORD_TYPE && i <= index);

	/* yuck! */
	goto did_not_get_any_errors;
 giferr:
	switch (GifLastError()) {
	case D_GIF_ERR_OPEN_FAILED:
		RErrorCode = RERR_OPEN;
		break;
	case D_GIF_ERR_READ_FAILED:
		RErrorCode = RERR_READ;
		break;
	default:
		RErrorCode = RERR_BADIMAGEFILE;
		break;
	}
 bye:
	if (image)
		RReleaseImage(image);
	image = NULL;
 did_not_get_any_errors:

	if (buffer)
		free(buffer);

	if (gif)
		DGifCloseFile(gif);

	return image;
}
Ejemplo n.º 23
0
Archivo: image.c Proyecto: JulioJu/sxiv
bool img_load_gif(img_t *img, const fileinfo_t *file)
{
	GifFileType *gif;
	GifRowType *rows = NULL;
	GifRecordType rec;
	ColorMapObject *cmap;
	DATA32 bgpixel, *data, *ptr;
	DATA32 *prev_frame = NULL;
	Imlib_Image im;
	int i, j, bg, r, g, b;
	int x, y, w, h, sw, sh;
	int px, py, pw, ph;
	int intoffset[] = { 0, 4, 2, 1 };
	int intjump[] = { 8, 8, 4, 2 };
	int transp = -1;
	unsigned int disposal = 0, prev_disposal = 0;
	unsigned int delay = 0;
	bool err = false;

	if (img->multi.cap == 0) {
		img->multi.cap = 8;
		img->multi.frames = (img_frame_t*)
		                    s_malloc(sizeof(img_frame_t) * img->multi.cap);
	}
	img->multi.cnt = img->multi.sel = 0;
	img->multi.length = 0;

#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
	gif = DGifOpenFileName(file->path, NULL);
#else
	gif = DGifOpenFileName(file->path);
#endif
	if (gif == NULL) {
		warn("could not open gif file: %s", file->name);
		return false;
	}
	bg = gif->SBackGroundColor;
	sw = gif->SWidth;
	sh = gif->SHeight;
	px = py = pw = ph = 0;

	do {
		if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
			err = true;
			break;
		}
		if (rec == EXTENSION_RECORD_TYPE) {
			int ext_code;
			GifByteType *ext = NULL;

			DGifGetExtension(gif, &ext_code, &ext);
			while (ext) {
				if (ext_code == GRAPHICS_EXT_FUNC_CODE) {
					if (ext[1] & 1)
						transp = (int) ext[4];
					else
						transp = -1;

					delay = 10 * ((unsigned int) ext[3] << 8 | (unsigned int) ext[2]);
					disposal = (unsigned int) ext[1] >> 2 & 0x7;
				}
				ext = NULL;
				DGifGetExtensionNext(gif, &ext);
			}
		} else if (rec == IMAGE_DESC_RECORD_TYPE) {
			if (DGifGetImageDesc(gif) == GIF_ERROR) {
				err = true;
				break;
			}
			x = gif->Image.Left;
			y = gif->Image.Top;
			w = gif->Image.Width;
			h = gif->Image.Height;

			rows = (GifRowType*) s_malloc(h * sizeof(GifRowType));
			for (i = 0; i < h; i++)
				rows[i] = (GifRowType) s_malloc(w * sizeof(GifPixelType));
			if (gif->Image.Interlace) {
				for (i = 0; i < 4; i++) {
					for (j = intoffset[i]; j < h; j += intjump[i])
						DGifGetLine(gif, rows[j], w);
				}
			} else {
				for (i = 0; i < h; i++)
					DGifGetLine(gif, rows[i], w);
			}

			ptr = data = (DATA32*) s_malloc(sizeof(DATA32) * sw * sh);
			cmap = gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap;
			r = cmap->Colors[bg].Red;
			g = cmap->Colors[bg].Green;
			b = cmap->Colors[bg].Blue;
			bgpixel = 0x00ffffff & (r << 16 | g << 8 | b);

			for (i = 0; i < sh; i++) {
				for (j = 0; j < sw; j++) {
					if (i < y || i >= y + h || j < x || j >= x + w ||
					    rows[i-y][j-x] == transp)
					{
						if (prev_frame != NULL && (prev_disposal != 2 ||
						    i < py || i >= py + ph || j < px || j >= px + pw))
						{
							*ptr = prev_frame[i * sw + j];
						} else {
							*ptr = bgpixel;
						}
					} else {
						r = cmap->Colors[rows[i-y][j-x]].Red;
						g = cmap->Colors[rows[i-y][j-x]].Green;
						b = cmap->Colors[rows[i-y][j-x]].Blue;
						*ptr = 0xff << 24 | r << 16 | g << 8 | b;
					}
					ptr++;
				}
			}

			im = imlib_create_image_using_copied_data(sw, sh, data);

			for (i = 0; i < h; i++)
				free(rows[i]);
			free(rows);
			free(data);

			if (im == NULL) {
				err = true;
				break;
			}

			imlib_context_set_image(im);
			imlib_image_set_format("gif");
			if (transp >= 0)
				imlib_image_set_has_alpha(1);

			if (disposal != 3)
				prev_frame = imlib_image_get_data_for_reading_only();
			prev_disposal = disposal;
			px = x, py = y, pw = w, ph = h;

			if (img->multi.cnt == img->multi.cap) {
				img->multi.cap *= 2;
				img->multi.frames = (img_frame_t*)
				                    s_realloc(img->multi.frames,
				                              img->multi.cap * sizeof(img_frame_t));
			}
			img->multi.frames[img->multi.cnt].im = im;
			img->multi.frames[img->multi.cnt].delay = delay > 0 ? delay : DEF_GIF_DELAY;
			img->multi.length += img->multi.frames[img->multi.cnt].delay;
			img->multi.cnt++;
		}
	} while (rec != TERMINATE_RECORD_TYPE);
Ejemplo n.º 24
0
unsigned char      *
loader_gif(FILE *f, int *w, int *h, int *t)
{
  unsigned char      *data, *ptr;
  GifFileType        *gif;
  GifRowType         *rows;
  GifRecordType       rec;
  ColorMapObject     *cmap;
  int                 i, j, done, bg, csize, r, g, b;
  int                 intoffset[] = {0, 4, 2, 1};
  int                 intjump[] = {8, 8, 4, 2};
  int                 istransp, transp;
  int                 fd;

  done = 0;
  istransp = 0;

  fd = fileno(f);
  /* Apparently rewind(f) isn't sufficient */
  lseek(fd, (long) 0, 0);
  gif = DGifOpenFileHandle(fd);

  transp = -1;
  data = NULL;
  rows = NULL;

  if (!gif)
    return NULL;

  do
    {
      if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
	{
	  PrintGifError();
	  rec = TERMINATE_RECORD_TYPE;
	}
      if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
	{
	  if (DGifGetImageDesc(gif) == GIF_ERROR)
	    {
	      PrintGifError();
	      rec = TERMINATE_RECORD_TYPE;
	    }
	  *w = gif->Image.Width;
	  *h = gif->Image.Height;
	  if(*h > 32767 || *w > 32767)
	    {
	      return NULL;
	    }
	  rows = malloc(*h * sizeof(GifRowType *));
	  if (!rows)
	    {
	      DGifCloseFile(gif);
	      return NULL;
	    }
	  data = _gdk_malloc_image(*w, *h);
	  if (!data)
	    {
	      DGifCloseFile(gif);
	      free(rows);
	      return NULL;
	    }
	  for (i = 0; i < *h; i++)
	    rows[i] = NULL;
	  for (i = 0; i < *h; i++)
	    {
	      rows[i] = malloc(*w * sizeof(GifPixelType));
	      if (!rows[i])
		{
		  DGifCloseFile(gif);
		  for (i = 0; i < *h; i++)
		    if (rows[i])
		      free(rows[i]);
		  free(rows);
		  free(data);
		  return NULL;
		}
	    }
	  if (gif->Image.Interlace)
	    {
	      for (i = 0; i < 4; i++)
		{
		  for (j = intoffset[i]; j < *h; j += intjump[i])
		    DGifGetLine(gif, rows[j], *w);
		}
	    }
	  else
	    {
	      for (i = 0; i < *h; i++)
		DGifGetLine(gif, rows[i], *w);
	    }
	  done = 1;
	}
      else if (rec == EXTENSION_RECORD_TYPE)
	{
	  int                 ext_code;
	  GifByteType        *ext;

	  ext = NULL;
	  DGifGetExtension(gif, &ext_code, &ext);
	  while (ext)
	    {
	      if ((ext_code == 0xf9) && (ext[1] & 1) && (transp < 0))
		{
		  istransp = 1;
		  transp = (int)ext[4];
		}
	      ext = NULL;
	      DGifGetExtensionNext(gif, &ext);
	    }
	}
    }
  while (rec != TERMINATE_RECORD_TYPE);
  bg = gif->SBackGroundColor;
  cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
  csize = cmap->ColorCount;
  ptr = data;
  if (!istransp)
    {
      for (i = 0; i < *h; i++)
	{
	  for (j = 0; j < *w; j++)
	    {
	      r = cmap->Colors[rows[i][j]].Red;
	      g = cmap->Colors[rows[i][j]].Green;
	      b = cmap->Colors[rows[i][j]].Blue;
	      *ptr++ = r;
	      *ptr++ = g;
	      *ptr++ = b;
	    }
	}
    }
  else
    {
      for (i = 0; i < *h; i++)
	{
	  for (j = 0; j < *w; j++)
	    {
	      if (rows[i][j] == transp)
		{
		  *ptr++ = 255;
		  *ptr++ = 0;
		  *ptr++ = 255;
		}
	      else
		{
		  r = cmap->Colors[rows[i][j]].Red;
		  g = cmap->Colors[rows[i][j]].Green;
		  b = cmap->Colors[rows[i][j]].Blue;
		  if (r == 255 && g == 0 && b == 255)
		    r = 254;
		  *ptr++ = r;
		  *ptr++ = g;
		  *ptr++ = b;
		}
	    }
	}
    }
  DGifCloseFile(gif);
  for (i = 0; i < *h; i++)
    free(rows[i]);
  free(rows);
  *t = istransp;
  return data;
}
Ejemplo n.º 25
0
/******************************************************************************
* This routine reads an entire GIF into core, hanging all its state info off  *
* the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle()   *
* first to initialize I/O.  Its inverse is EGifSpew().			      *
* 
 ******************************************************************************/
int DGifSlurp(GifFileType *GifFile)
{
    int i, j, Error, ImageSize;
    GifRecordType RecordType;
    SavedImage *sp;
    GifByteType *ExtData;
    SavedImage temp_save;

    temp_save.ExtensionBlocks=NULL;
    temp_save.ExtensionBlockCount=0;
  
    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
	    return(GIF_ERROR);

	switch (RecordType) {
	    case IMAGE_DESC_RECORD_TYPE:
		if (DGifGetImageDesc(GifFile) == GIF_ERROR)
		    return(GIF_ERROR);

		sp = &GifFile->SavedImages[GifFile->ImageCount-1];
		ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;

		sp->RasterBits
		    = (char *) malloc(ImageSize * sizeof(GifPixelType));

		if (DGifGetLine(GifFile, (GifByteType*)sp->RasterBits, ImageSize)
		    == GIF_ERROR)
		    return(GIF_ERROR);

        if (temp_save.ExtensionBlocks) {
            sp->ExtensionBlocks = temp_save.ExtensionBlocks;
            sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;

            temp_save.ExtensionBlocks = NULL;
            temp_save.ExtensionBlockCount=0;

        /* FIXME: The following is wrong.  It is left in only for backwards
         * compatibility.  Someday it should go away.  Use the
         * sp->ExtensionBlocks->Function variable instead.
         */
            sp->Function = sp->ExtensionBlocks[0].Function;

        }

		break;

	    case EXTENSION_RECORD_TYPE:
		if (DGifGetExtension(GifFile,&temp_save.Function,&ExtData)==GIF_ERROR)
		    return(GIF_ERROR);
		while (ExtData != NULL) {
            
            /* Create an extension block with our data */
            if (AddExtensionBlock(&temp_save, ExtData[0], (char*)&ExtData[1])
               == GIF_ERROR)
                return (GIF_ERROR); 
            
		    if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
			    return(GIF_ERROR);
            temp_save.Function = 0;
		}
		break;

	    case TERMINATE_RECORD_TYPE:
		break;

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

    /* Just in case the Gif has an extension block without an associated
     * image... (Should we save this into a savefile structure with no image
     * instead?  Have to check if the present writing code can handle that as
     * well....
     */
    if (temp_save.ExtensionBlocks)
        FreeExtension(&temp_save);
    
    return(GIF_OK);
}
Ejemplo n.º 26
0
/******************************************************************************
 This routine reads an entire GIF into core, hanging all its state info off
 the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle()
 first to initialize I/O.  Its inverse is EGifSpew().
*******************************************************************************/
int
DGifSlurp(GifFileType *GifFile)
{
    size_t ImageSize;
    GifRecordType RecordType;
    SavedImage *sp;
    GifByteType *ExtData;
    int ExtFunction;

    GifFile->ExtensionBlocks = NULL;
    GifFile->ExtensionBlockCount = 0;

    do {
        if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
            return (GIF_ERROR);

        switch (RecordType) {
          case IMAGE_DESC_RECORD_TYPE:
              if (DGifGetImageDesc(GifFile) == GIF_ERROR)
                  return (GIF_ERROR);

              sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
              /* Allocate memory for the image */
              if (sp->ImageDesc.Width < 0 && sp->ImageDesc.Height < 0 &&
                      sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
                  return GIF_ERROR;
              }
              ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;

              if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
                  return GIF_ERROR;
              }
              sp->RasterBits = (unsigned char *)malloc(ImageSize *
                      sizeof(GifPixelType));

              if (sp->RasterBits == NULL) {
                  return GIF_ERROR;
              }

	      if (sp->ImageDesc.Interlace) {
		  int i, j;
		   /* 
		    * The way an interlaced image should be read - 
		    * offsets and jumps...
		    */
		  int InterlacedOffset[] = { 0, 4, 2, 1 };
		  int InterlacedJumps[] = { 8, 8, 4, 2 };
		  /* Need to perform 4 passes on the image */
		  for (i = 0; i < 4; i++)
		      for (j = InterlacedOffset[i]; 
			   j < sp->ImageDesc.Height;
			   j += InterlacedJumps[i]) {
			  if (DGifGetLine(GifFile, 
					  sp->RasterBits+j*sp->ImageDesc.Width, 
					  sp->ImageDesc.Width) == GIF_ERROR)
			      return GIF_ERROR;
		      }
	      }
	      else {
		  if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
		      return (GIF_ERROR);
	      }

              if (GifFile->ExtensionBlocks) {
                  sp->ExtensionBlocks = GifFile->ExtensionBlocks;
                  sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;

                  GifFile->ExtensionBlocks = NULL;
                  GifFile->ExtensionBlockCount = 0;
              }
              break;

          case EXTENSION_RECORD_TYPE:
              if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
                  return (GIF_ERROR);
	      /* Create an extension block with our data */
	      if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
				       &GifFile->ExtensionBlocks, 
				       ExtFunction, ExtData[0], &ExtData[1])
		  == GIF_ERROR)
		  return (GIF_ERROR);
              while (ExtData != NULL) {
                  if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
                      return (GIF_ERROR);
                  /* Continue the extension block */
		  if (ExtData != NULL)
		      if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
					       &GifFile->ExtensionBlocks,
					       CONTINUE_EXT_FUNC_CODE, 
					       ExtData[0], &ExtData[1]) == GIF_ERROR)
                      return (GIF_ERROR);
              }
              break;

          case TERMINATE_RECORD_TYPE:
              break;

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

    return (GIF_OK);
}
Ejemplo n.º 27
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
int main(int argc, char **argv)
{
    int	i, iy, last_iy, l, t, w, h, Error, NumFiles, ExtCode,
	ImageNum = 0,
	SizeFlag = FALSE,
	ScaleFlag = FALSE,
	XScaleFlag = FALSE,
	YScaleFlag = FALSE,
	HelpFlag = FALSE;
    double Scale, y;
    GifRecordType RecordType;
    char s[80];
    GifByteType *Extension;
    GifRowType LineIn, LineOut;
    char **FileName = NULL;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
		&GifQuietPrint, &SizeFlag, &XSize, &YSize, &ScaleFlag, &Scale,
		&XScaleFlag, &XScale, &YScaleFlag, &YScale,
		&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 specific direction was set, set other direction to 1: */
    if (!XScaleFlag && YScaleFlag) XScale = 1.0;
    if (!YScaleFlag && XScaleFlag) YScale = 1.0;

    /* If the specific direction was not set, but global one did use it: */
    if (!XScaleFlag && ScaleFlag) XScale = Scale;
    if (!YScaleFlag && ScaleFlag) YScale = Scale;

    if (XScale > MAX_SCALE) {
	sprintf(s, "XScale too big, maximum scale selected instead (%f).",
								MAX_SCALE);
	GIF_MESSAGE(s);
	XScale = MAX_SCALE;
    }
    if (YScale > MAX_SCALE) {
	sprintf(s, "YScale too big, maximum scale selected instead (%f).",
								MAX_SCALE);
	GIF_MESSAGE(s);
	YScale = MAX_SCALE;
    }

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

    /* If size was specified, it is used to derive the scale: */
    if (SizeFlag) {
	XScale = XSize / ((double) GifFileIn->SWidth);
	YScale = YSize / ((double) GifFileIn->SHeight);
    }
    else
    {
	XSize = (int) (GifFileIn->SWidth * XScale + 0.5);
	YSize = (int) (GifFileIn->SHeight * YScale + 0.5);
    }

    /* As at this time we know the Screen size of the input gif file, and as */
    /* all image(s) in file must be less/equal to it, we can allocate the    */
    /* scan lines for the input file, and output file. The number of lines   */
    /* to allocate for each is set by ScaleDown & XScale & YScale:	     */
    LineOut = (GifRowType) malloc(XSize * sizeof(GifPixelType));
    LineIn = (GifRowType) malloc(GifFileIn->SWidth * sizeof(GifPixelType));

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

    /* And dump out its new scaled screen information: */
    if (EGifPutScreenDesc(GifFileOut, XSize, YSize,
	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);
		/* Put the image descriptor to out file: */
		l = (int) (GifFileIn->Image.Left * XScale + 0.5);
		w = (int) (GifFileIn->Image.Width * XScale + 0.5);
		t = (int) (GifFileIn->Image.Top * YScale + 0.5);
		h = (int) (GifFileIn->Image.Height * YScale + 0.5);
		if (l < 0) l = 0;
		if (t < 0) t = 0;
		if (l + w > XSize) w = XSize - l;
		if (t + h > YSize) h = YSize - t;

		if (EGifPutImageDesc(GifFileOut, l, t, w, h,
		    GifFileIn->Image.Interlace,
		    GifFileIn->Image.ColorMap) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		if (GifFileIn->Image.Interlace) {
		    GIF_EXIT("Cannt resize interlaced images - use GifInter first.");
		}
		else {
		    GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
			PROGRAM_NAME, ++ImageNum,
			GifFileOut->Image.Left, GifFileOut->Image.Top,
			GifFileOut->Image.Width, GifFileOut->Image.Height);

		    for (i = GifFileIn->Image.Height, y = 0.0, last_iy = -1;
			 i-- > 0;
			 y += YScale) {
			if (DGifGetLine(GifFileIn, LineIn,
					GifFileIn->Image.Width) == GIF_ERROR)
			    QuitGifError(GifFileIn, GifFileOut);

			iy = (int) y;
			if (last_iy < iy && last_iy < YSize) {
			    ResizeLine(LineIn, LineOut,
				       GifFileIn->Image.Width, GifFileOut->Image.Width);

			    for (;
				 last_iy < iy && last_iy < GifFileOut->Image.Height - 1;
				 last_iy++) {
				GifQprintf("\b\b\b\b%-4d", last_iy + 1);
				if (EGifPutLine(GifFileOut, LineOut,
						GifFileOut->Image.Width) ==
								    GIF_ERROR)
				    QuitGifError(GifFileIn, GifFileOut);
			    }
			}
		    }

		    /* If scale is not dividable - dump last lines: */
		    while (++last_iy < GifFileOut->Image.Height) {
			GifQprintf("\b\b\b\b%-4d", last_iy);
			if (EGifPutLine(GifFileOut, LineOut,
					GifFileOut->Image.Width) == 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);

    free(LineOut);
    free(LineIn);

    return 0;
}
Ejemplo n.º 28
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;
}
Ejemplo n.º 29
0
Archivo: image.c Proyecto: kkb7401/sxiv
bool img_load_gif(img_t *img, const fileinfo_t *file)
{
	GifFileType *gif;
	GifRowType *rows = NULL;
	GifRecordType rec;
	ColorMapObject *cmap;
	DATA32 bgpixel, *data, *ptr;
	DATA32 *prev_frame = NULL;
	Imlib_Image im;
	int i, j, bg, r, g, b;
	int x, y, w, h, sw, sh;
	int px, py, pw, ph;
	int intoffset[] = { 0, 4, 2, 1 };
	int intjump[] = { 8, 8, 4, 2 };
	int transp = -1;
	unsigned int disposal = 0, prev_disposal = 0;
	unsigned int delay = 0;
	bool err = false;

	if (img->multi.cap == 0) {
		img->multi.cap = 8;
		img->multi.frames = (img_frame_t*)
		                    s_malloc(sizeof(img_frame_t) * img->multi.cap);
	}
	img->multi.cnt = img->multi.sel = 0;
	img->multi.length = img->multi.repeat = 0;

#if defined(GIFLIB_MAJOR) && GIFLIB_MAJOR >= 5
	gif = DGifOpenFileName(file->path, NULL);
#else
	gif = DGifOpenFileName(file->path);
#endif
	if (gif == NULL) {
		warn("could not open gif file: %s", file->name);
		return false;
	}
	bg = gif->SBackGroundColor;
	sw = gif->SWidth;
	sh = gif->SHeight;
	px = py = pw = ph = 0;

	do {
		if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
			err = true;
			break;
		}
		if (rec == EXTENSION_RECORD_TYPE) {
			int ext_code;
			GifByteType *ext = NULL;

			DGifGetExtension(gif, &ext_code, &ext);
			while (ext) {
				if (ext_code == GRAPHICS_EXT_FUNC_CODE) {
					if (ext[1] & 1)
						transp = (int) ext[4];
					else
						transp = -1;

					delay = 10 * ((unsigned int) ext[3] << 8 | (unsigned int) ext[2]);
					if (delay)
						delay = MAX(delay, MIN_GIF_DELAY);

					disposal = (unsigned int) ext[1] >> 2 & 0x7;
				} else if (ext_code == APPLICATION_EXT_FUNC_CODE) {
					if (ext[0] == 11 && memcmp(ext+1, "NETSCAPE2.0", 11) == 0) {
						DGifGetExtensionNext(gif, &ext);
						if (ext && ext[0] == 3 && ext[1] == 1)
							img->multi.repeat = ((int) ext[3] << 8 | (int) ext[2]) - 1;
					}
				}
				ext = NULL;
				DGifGetExtensionNext(gif, &ext);
			}
		} else if (rec == IMAGE_DESC_RECORD_TYPE) {
Ejemplo n.º 30
0
/******************************************************************************
* Interpret the command line and scan the given GIF file.		      *
******************************************************************************/
void main(int argc, char **argv)
{
    int	Error, NumFiles, ExtCode;
    GifRecordType RecordType;
    GifByteType *Extension;
    char **FileName = NULL;
    GifRowType *ImageBuffer;
    GifFileType *GifFileIn = NULL, *GifFileOut = NULL;

    if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
		&InterlacedFlag, &SequencialFlag, &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(1);
    }

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

    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);

    /* And dump out exactly same screen information: */
    if (EGifPutScreenDesc(GifFileOut,
	GifFileIn -> SWidth, GifFileIn -> SHeight,
	GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
	GifFileIn -> SBitsPerPixel, 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);

		/* Put the image descriptor to out file: */
		if (EGifPutImageDesc(GifFileOut,
		    GifFileIn -> ILeft, GifFileIn -> ITop,
		    GifFileIn -> IWidth, GifFileIn -> IHeight,
		    InterlacedFlag, GifFileIn -> IBitsPerPixel,
		    GifFileIn -> IColorMap) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);

		/* Load the image (either Interlaced or not), and dump it as */
		/* defined in GifFileOut -> IInterlaced.		     */
		if (LoadImage(GifFileIn, &ImageBuffer) == GIF_ERROR)
		    QuitGifError(GifFileIn, GifFileOut);
		if (DumpImage(GifFileOut, ImageBuffer) == 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);
}