Example #1
0
static void
gif_read(unsigned char *dst, unsigned int line, void *data)
{
    struct gif_state *h = (struct gif_state *) data;
    GifColorType *cmap;
    int x;
    
    if (h->gif->Image.Interlace) {
	if (line % 2) {
	    DGifGetLine(h->gif, h->row, h->w);
	} else {
	    memcpy(h->row, h->il + h->w * line, h->w);
	}
    } else {
	DGifGetLine(h->gif, h->row, h->w);
    }
    cmap = h->gif->Image.ColorMap ?
	h->gif->Image.ColorMap->Colors : h->gif->SColorMap->Colors;
    for (x = 0; x < h->w; x++) {
        dst[0] = cmap[h->row[x]].Red;
	dst[1] = cmap[h->row[x]].Green;
	dst[2] = cmap[h->row[x]].Blue;
	dst += 3;
    }
}
Example #2
0
int GIFReadFrame(GifFileType* const gif, int transparent_index,
                 GIFFrameRect* const gif_rect, WebPPicture* const picture) {
  WebPPicture sub_image;
  const GifImageDesc* const image_desc = &gif->Image;
  uint32_t* dst = NULL;
  uint8_t* tmp = NULL;
  int ok = 0;
  GIFFrameRect rect = {
      image_desc->Left, image_desc->Top, image_desc->Width, image_desc->Height
  };
  *gif_rect = rect;

  // Use a view for the sub-picture:
  if (!WebPPictureView(picture, rect.x_offset, rect.y_offset,
                       rect.width, rect.height, &sub_image)) {
    fprintf(stderr, "Sub-image %dx%d at position %d,%d is invalid!\n",
            rect.width, rect.height, rect.x_offset, rect.y_offset);
    return 0;
  }
  dst = sub_image.argb;

  tmp = (uint8_t*)malloc(rect.width * sizeof(*tmp));
  if (tmp == NULL) goto End;

  if (image_desc->Interlace) {  // Interlaced image.
    // We need 4 passes, with the following offsets and jumps.
    const int interlace_offsets[] = { 0, 4, 2, 1 };
    const int interlace_jumps[]   = { 8, 8, 4, 2 };
    int pass;
    for (pass = 0; pass < 4; ++pass) {
      int y;
      for (y = interlace_offsets[pass]; y < rect.height;
           y += interlace_jumps[pass]) {
        if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End;
        Remap(gif, tmp, rect.width, transparent_index,
              dst + y * sub_image.argb_stride);
      }
    }
  } else {  // Non-interlaced image.
    int y;
    for (y = 0; y < rect.height; ++y) {
      if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End;
      Remap(gif, tmp, rect.width, transparent_index,
            dst + y * sub_image.argb_stride);
    }
  }
  ok = 1;

 End:
  if (!ok) picture->error_code = sub_image.error_code;
  WebPPictureFree(&sub_image);
  free(tmp);
  return ok;
}
Example #3
0
static int ReadSubImage(GifFileType* gif, WebPPicture* pic, WebPPicture* view) {
  const GifImageDesc image_desc = gif->Image;
  const int offset_x = image_desc.Left;
  const int offset_y = image_desc.Top;
  const int sub_w = image_desc.Width;
  const int sub_h = image_desc.Height;
  uint32_t* dst = NULL;
  uint8_t* tmp = NULL;
  int ok = 0;

  // Use a view for the sub-picture:
  if (!WebPPictureView(pic, offset_x, offset_y, sub_w, sub_h, view)) {
    fprintf(stderr, "Sub-image %dx%d at position %d,%d is invalid!\n",
            sub_w, sub_h, offset_x, offset_y);
    goto End;
  }
  dst = view->argb;

  tmp = (uint8_t*)malloc(sub_w * sizeof(*tmp));
  if (tmp == NULL) goto End;

  if (image_desc.Interlace) {  // Interlaced image.
    // We need 4 passes, with the following offsets and jumps.
    const int interlace_offsets[] = { 0, 4, 2, 1 };
    const int interlace_jumps[]   = { 8, 8, 4, 2 };
    int pass;
    for (pass = 0; pass < 4; ++pass) {
      int y;
      for (y = interlace_offsets[pass]; y < sub_h; y += interlace_jumps[pass]) {
        if (DGifGetLine(gif, tmp, sub_w) == GIF_ERROR) goto End;
        Remap(tmp, gif, dst + y * view->argb_stride, sub_w);
      }
    }
  } else {  // Non-interlaced image.
    int y;
    for (y = 0; y < sub_h; ++y) {
      if (DGifGetLine(gif, tmp, sub_w) == GIF_ERROR) goto End;
      Remap(tmp, gif, dst + y * view->argb_stride, sub_w);
    }
  }
  // re-align the view with even offset (and adjust dimensions if needed).
  WebPPictureView(pic, offset_x & ~1, offset_y & ~1,
                  sub_w + (offset_x & 1), sub_h + (offset_y & 1), view);
  ok = 1;

 End:
  free(tmp);
  return ok;
}
Example #4
0
// Read the GIF image frame.
static int ReadFrame(GifFileType* const gif, WebPFrameRect* const gif_rect,
                     WebPPicture* const sub_image, WebPPicture* const curr) {
  const GifImageDesc image_desc = gif->Image;
  uint32_t* dst = NULL;
  uint8_t* tmp = NULL;
  int ok = 0;
  WebPFrameRect rect = {
      image_desc.Left, image_desc.Top, image_desc.Width, image_desc.Height
  };
  *gif_rect = rect;

  // Use a view for the sub-picture:
  if (!WebPPictureView(curr, rect.x_offset, rect.y_offset,
                       rect.width, rect.height, sub_image)) {
    fprintf(stderr, "Sub-image %dx%d at position %d,%d is invalid!\n",
            rect.width, rect.height, rect.x_offset, rect.y_offset);
    goto End;
  }
  dst = sub_image->argb;

  tmp = (uint8_t*)malloc(rect.width * sizeof(*tmp));
  if (tmp == NULL) goto End;

  if (image_desc.Interlace) {  // Interlaced image.
    // We need 4 passes, with the following offsets and jumps.
    const int interlace_offsets[] = { 0, 4, 2, 1 };
    const int interlace_jumps[]   = { 8, 8, 4, 2 };
    int pass;
    for (pass = 0; pass < 4; ++pass) {
      int y;
      for (y = interlace_offsets[pass]; y < rect.height;
           y += interlace_jumps[pass]) {
        if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End;
        Remap(tmp, gif, dst + y * sub_image->argb_stride, rect.width);
      }
    }
  } else {  // Non-interlaced image.
    int y;
    for (y = 0; y < rect.height; ++y) {
      if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End;
      Remap(tmp, gif, dst + y * sub_image->argb_stride, rect.width);
    }
  }
  ok = 1;

 End:
  free(tmp);
  return ok;
}
Example #5
0
int DGifGetLineByte(GifFileType *GifFile, GifPixelType *Line, int LineLen)
{
    GifPixelType LineBuf[240];
    CopyLine(LineBuf, Line, LineLen);
    int result = DGifGetLine(GifFile, LineBuf, LineLen);
    CopyLine(Line, LineBuf, LineLen);
    return result;
}
Example #6
0
/******************************************************************************
* Routine to read Image out. The image can be Interlaced or None interlaced.
* The memory required to hold the image is allocate by the routine itself.
* The image is always loaded sequencially into the buffer.
* Return GIF_OK if succesful, GIF_ERROR otherwise.
******************************************************************************/
static int LoadImage(GifFileType *GifFile, GifRowType **ImageBufferPtr)
{
    int Size, i;
    GifRowType *ImageBuffer;

    /* The following comment was written under DOS on a 286:                 */
    /* Allocate the image as vector of column of rows. We can't allocate the */
    /* whole screen at once, as this broken minded CPU can allocate up to    */
    /* 64k at a time and our image can be bigger than that:		     */
    if ((ImageBuffer = (GifRowType *)
	malloc(GifFile->Image.Height * sizeof(GifRowType))) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");

    Size = GifFile->Image.Width * sizeof(GifPixelType);/* One row size in bytes.*/
    for (i = 0; i < GifFile->Image.Height; i++) {
	/* Allocate the rows: */
	if ((ImageBuffer[i] = (GifRowType) malloc(Size)) == NULL)
	    GIF_EXIT("Failed to allocate memory required, aborted.");
    }

    *ImageBufferPtr = ImageBuffer;

    GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
	PROGRAM_NAME, ++ImageNum, GifFile->Image.Left, GifFile->Image.Top,
				 GifFile->Image.Width, GifFile->Image.Height);
    if (GifFile->Image.Interlace) {
	int j, Count;
	/* Need to perform 4 passes on the images: */
	for (Count = i = 0; i < 4; i++)
	    for (j = InterlacedOffset[i]; j < GifFile->Image.Height;
						 j += InterlacedJumps[i]) {
		GifQprintf("\b\b\b\b%-4d", Count++);
		if (DGifGetLine(GifFile, ImageBuffer[j], GifFile->Image.Width)
		    == GIF_ERROR) return GIF_ERROR;
	    }
    }
    else {
	for (i = 0; i < GifFile->Image.Height; i++) {
	    GifQprintf("\b\b\b\b%-4d", i);
	    if (DGifGetLine(GifFile, ImageBuffer[i], GifFile->Image.Width)
		== GIF_ERROR) return GIF_ERROR;
	}
    }

    return GIF_OK;
}
Example #7
0
CPLErr BIGGifRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
                                     int nBlockYOff,
                                     void * pImage )
{
    BIGGIFDataset *poGDS = (BIGGIFDataset *) poDS;

    CPLAssert( nBlockXOff == 0 );

    if( panInterlaceMap != NULL )
        nBlockYOff = panInterlaceMap[nBlockYOff];

/* -------------------------------------------------------------------- */
/*      Do we already have this line in the work dataset?               */
/* -------------------------------------------------------------------- */
    if( poGDS->poWorkDS != NULL && nBlockYOff <= poGDS->nLastLineRead )
    {
        return poGDS->poWorkDS->
            RasterIO( GF_Read, 0, nBlockYOff, nBlockXSize, 1,
                      pImage, nBlockXSize, 1, GDT_Byte,
                      1, NULL, 0, 0, 0, NULL );
    }

/* -------------------------------------------------------------------- */
/*      Do we need to restart from the start of the image?              */
/* -------------------------------------------------------------------- */
    if( nBlockYOff <= poGDS->nLastLineRead )
    {
        if( poGDS->ReOpen() == CE_Failure )
            return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Read till we get our target line.                               */
/* -------------------------------------------------------------------- */
    CPLErr eErr = CE_None;
    while( poGDS->nLastLineRead < nBlockYOff && eErr == CE_None )
    {
        if( DGifGetLine( poGDS->hGifFile, (GifPixelType*)pImage,
                         nBlockXSize ) == GIF_ERROR )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Failure decoding scanline of GIF file." );
            return CE_Failure;
        }

        poGDS->nLastLineRead++;

        if( poGDS->poWorkDS != NULL )
        {
            eErr = poGDS->poWorkDS->RasterIO( GF_Write,
                                       0, poGDS->nLastLineRead, nBlockXSize, 1,
                                       pImage, nBlockXSize, 1, GDT_Byte,
                                       1, NULL, 0, 0, 0, NULL );
        }
    }

    return eErr;
}
Example #8
0
static void
gif_skipimage(struct gif_state *h)
{
    unsigned char *line;
    int i;

    if (FbiStuff::fim_filereading_debug())
	FIM_FBI_PRINTF("gif: skipping image record ...\n");
    DGifGetImageDesc(h->gif);
    line = fim_malloc(h->gif->SWidth);
    for (i = 0; i < h->gif->SHeight; i++)
	DGifGetLine(h->gif, line, h->gif->SWidth);
    fim_free(line);
}
Example #9
0
bool GifTranscoder::readImage(GifFileType* gifIn, GifByteType* rasterBits) {
    if (gifIn->Image.Interlace) {
        int interlacedOffset[] = { 0, 4, 2, 1 };
        int interlacedJumps[] = { 8, 8, 4, 2 };

        // Need to perform 4 passes on the image
        for (int i = 0; i < 4; i++) {
            for (int j = interlacedOffset[i]; j < gifIn->Image.Height; j += interlacedJumps[i]) {
                if (DGifGetLine(gifIn,
                                rasterBits + j * gifIn->Image.Width,
                                gifIn->Image.Width) == GIF_ERROR) {
                    LOGE("Could not read interlaced raster data");
                    return false;
                }
            }
        }
    } else {
        if (DGifGetLine(gifIn, rasterBits, gifIn->Image.Width * gifIn->Image.Height) == GIF_ERROR) {
            LOGE("Could not read raster data");
            return false;
        }
    }
    return true;
}
Example #10
0
File: ipas.cpp Project: macx0r/ipas
image* load_image (char* file, image_format fmt) {
  image* img = NULL;
  if (fmt == imgIRMID) {
    FILE* fp;
    fp = fopen (file, "r");
    image simage;
    fread (&simage, sizeof(image), 1, fp);
    img = (image*) malloc (simage.size);
    fseek (fp, 0, SEEK_SET);
    fread (img, simage.size, 1, fp);
    fclose (fp);
  } else if (fmt == imgGIF) {
    GifFileType* GifFileIn = DGifOpenFileName (file);
    int size = GifFileIn->SWidth * GifFileIn->SHeight * sizeof (rtbyte) + sizeof (image) - sizeof (rtbyte);
    img = (image*) malloc (size);
    img->size = size;
    img->dimx = GifFileIn->SWidth;
    img->dimy = GifFileIn->SHeight;
    img->dimc = 1;
    img->dimz = 1;
    img->dimt = 1;
    img->xyz = img->xy = img->dimx * img->dimy;
    img->len = img->xy * sizeof (rdword);
    img->clr = clrmGrey;

    GifRecordType record;
    GifRowType pixels = (GifRowType) new GifPixelType[img->xy];
    do {
      DGifGetRecordType(GifFileIn, &record);
      if (record != IMAGE_DESC_RECORD_TYPE)
        continue;
      DGifGetImageDesc (GifFileIn);
      for (int row = 0; row < img->dimy; ++row)
        DGifGetLine (GifFileIn, pixels + row * img->dimx, img->dimx);
    } while (record != TERMINATE_RECORD_TYPE);

    for (uint n = 0; n < img->xy; ++n)
      data(img)[n] = (rtbyte)pixels[n];

    DGifCloseFile (GifFileIn);
  }
  return (img);
}
Example #11
0
value dGifGetLine( value hdl )
{
  CAMLparam1(hdl);
  CAMLlocal1(buf);

  GifFileType *GifFile = (GifFileType*) hdl;

  if( oversized( GifFile->Image.Width, sizeof(GifPixelType) ) ){
    failwith_oversized("gif");
  }
  buf = alloc_string( GifFile->Image.Width * sizeof(GifPixelType) ); 

  if( DGifGetLine(GifFile, String_val(buf), GifFile->Image.Width ) 
      == GIF_ERROR ){
    // PrintGifError ();
    failwith("DGifGetLine");
  }
  CAMLreturn(buf);
}
Example #12
0
static int output_gif_pixels(struct gps_map *map, GifFileType *gf, int x, int y,
			     int width, int height, int row_stride, unsigned char *out)
{
	ColorMapObject *cm;
	unsigned char *scan_line;
	int r, col, line, cm_size;

	cm = gf->Image.ColorMap ? gf->Image.ColorMap : gf->SColorMap;
	cm_size = cm->ColorCount;

	r = -1;
	scan_line = malloc(map->width);
	for (line = 0; line < y + height; line++) {
		if (DGifGetLine(gf, scan_line, map->width) == GIF_ERROR) {
			PrintGifError();
			goto fail;
		}
		if (line < y)
			continue;
		for (col = 0; col < x + width; col++) {
			GifColorType *color;

			if (col < x)
				continue;
			if (scan_line[col] > cm_size)
				scan_line[col] = 0;
			color = &cm->Colors[scan_line[col]];
			*out++ = color->Red;
			*out++ = color->Green;
			*out++ = color->Blue;
		}
		out += row_stride - width * 3;
	}
	r = 0;
fail:
	free(scan_line);
	return r;
}
Example #13
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;
}
Example #14
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);
}
Example #15
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);
   }
Example #16
0
File: image.c Project: 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);
Example #17
0
bool SkGifCodec::readRow() {
    return GIF_ERROR != DGifGetLine(fGif, fSrcBuffer.get(), fFrameRect.width());
}
Example #18
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);
}
Example #19
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);
}
Example #20
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;
}
Example #21
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);
}
Example #22
0
bool CxImageGIF::Decode(CxFile *fp)
{
	if (fp == NULL) return false;

	GifFileType *GifFile = NULL;
	GifRecordType RecordType;
	GifByteType *Extension;
	GifColorType *ColorMap;
	int i, j, Count, Row, Col, Width, Height, ExtCode, ColorMapSize;
	static int InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
	    InterlacedJumps[] = { 8, 8, 4, 2 };    /* be read - offsets and jumps... */

	try
	{
		GifFile = DGifOpen(fp, readCxFile);

		if (!Create(GifFile->SWidth,GifFile->SHeight,8,CXIMAGE_FORMAT_GIF))
			throw "Can't allocate memory";

		do
		{
			DGifGetRecordType(GifFile, &RecordType);

			switch (RecordType)
			{
			case IMAGE_DESC_RECORD_TYPE:
				DGifGetImageDesc(GifFile);

				Row = GifFile->Image.Top; /* Image Position relative to Screen. */
				Col = GifFile->Image.Left;
				Width = GifFile->Image.Width;
				Height = GifFile->Image.Height;

				if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth ||
					GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight)
						throw "Image is not confined to screen dimension, aborted.\n";

				if (GifFile->Image.Interlace)
				{
					/* 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])
								DGifGetLine(GifFile, GetBits(GifFile->SHeight - j - 1) + Col, Width);
				}
				else {
					for (i = 0; i < Height; i++)
						DGifGetLine(GifFile,GetBits(GifFile->SHeight - Row++ - 1) + Col,Width);
			    }
				break;
			case EXTENSION_RECORD_TYPE:
				/* Skip any extension blocks in file: */
				DGifGetExtension(GifFile, &ExtCode, &Extension);
				while (Extension != NULL)
					DGifGetExtensionNext(GifFile, &Extension);
				break;
			default:
				break;
			}
		}while (RecordType != TERMINATE_RECORD_TYPE);

		ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap->Colors : GifFile->SColorMap->Colors);
		ColorMapSize = GifFile->Image.ColorMap ? GifFile->Image.ColorMap->ColorCount : GifFile->SColorMap->ColorCount;

		if(ColorMap && ColorMapSize)
		{
			RGBQUAD* ppal=GetPalette();

			for (i=0; i < ColorMapSize; i++) {
				ppal[i].rgbRed = ColorMap[i].Red;
				ppal[i].rgbGreen = ColorMap[i].Green;
				ppal[i].rgbBlue = ColorMap[i].Blue;
			}

			head.biClrUsed = ColorMapSize;

			if(GifFile->SBackGroundColor)
			{
				info.nBkgndIndex = GifFile->SBackGroundColor;
				info.nBkgndColor.rgbRed = ColorMap[info.nBkgndIndex].Red;
				info.nBkgndColor.rgbGreen = ColorMap[info.nBkgndIndex].Green;
				info.nBkgndColor.rgbBlue = ColorMap[info.nBkgndIndex].Blue;
			}
		}

		DGifCloseFile(GifFile);
		GifFile = NULL;
	} catch (int errid) {
		strncpy(info.szLastError,GifGetErrorMessage(errid),255);
		if(GifFile != NULL) DGifCloseFile(GifFile);
		return false;
	} catch (char *message) {
		strncpy(info.szLastError,message,255);
		if(GifFile != NULL) DGifCloseFile(GifFile);
		return false;
	}

	return true;
}
Example #23
0
int main(int argc, char **argv) {
   //
   // local vars
   //
   GifFileType *GIFfile;
   GifRecordType GIFtype;
   GifByteType *GIFextension;
   GifPixelType *GIFline;
   uint32_t **lower_array,**upper_array;
   double **image_array;
   double f,fmin,fmax;
   int x,y,z,h,i,j,k,n,p;
   int image_width,image_height,image_count,color_resolution,GIFcode,ret;
   float pixel_size,arg,rx,ry,rz;
   char type,comment[256];
   struct fab_vars v;
   init_vars(&v);
   //
   // command line args
   //
   if (!((argc == 3) || (argc == 4) || (argc == 5) || (argc == 6) || (argc == 7) || (argc == 10))) {
      printf("command line: gif_png in.gif out.png [type [arg [points [size [rx ry rz]]]]]\n");
      printf("   in.gif = input gif file\n");
      printf("   out.png = output PNG file\n");
      printf("   type = 'z' of density, 'h' for height (default z)\n");
      printf("   arg = gamma for 'z', threshold for 'h' (default 1)\n");
      printf("   points = points to interpolate per point (linear, default 0)\n");
      printf("   size = voxel size (mm, default from file))\n");
      printf("   to be implemented: rx,ry,rz = x,y,z rotation angles (degrees; default 0)\n");
      exit(-1);
      }
   type = 'z';
   p = 0;
   arg = 1;
   rx = ry = rz = 0;
   pixel_size = -1;
   image_width = -1;
   image_height = -1;
   if (argc >= 4) {
      sscanf(argv[3],"%c",&type);
      if (!((type == 'z') || (type == 'h'))) {
         printf("gif_png: oops -- type must be 'z' or 'h'\n");
         exit(-1);
         }
   if (argc >= 5)
      sscanf(argv[4],"%f",&arg);
      }
   if (argc >= 6)
      sscanf(argv[5],"%d",&p);
   if (argc >= 7)
      sscanf(argv[6],"%f",&pixel_size);
   if (argc >= 10) {
      sscanf(argv[7],"%f",&rx);
      sscanf(argv[8],"%f",&ry);
      sscanf(argv[9],"%f",&rz);
      }
   //
   // scan the file 
   //
   printf("read %s\n",argv[1]);
   color_resolution = -1;
   GIFfile = DGifOpenFileName(argv[1]);
   if (GIFfile == NULL) {
      printf("gif_png: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   GIFline = malloc(MAX_LINE*sizeof(GifPixelType));
   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_png: oops -- error reading line\n");
                  exit(-1);
                  }
               }
            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 (pixel_size == -1)
                  sscanf(comment,"mm per pixel: %f;",&pixel_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_png: oops -- undefined GIF record type\n");
            exit(-1);
            break;
         }
      } while (GIFtype != TERMINATE_RECORD_TYPE);
   if (GIFfile == NULL) {
      printf("gif_png: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   if (pixel_size == -1) {
      pixel_size = 1.0;
      printf("   no pixel size found, assuming 1 mm\n");
      }
   printf("   pixel size (mm): %f, color resolution (bits): %d\n",pixel_size,color_resolution);
   printf("   number of images: %d, image width %d, image height %d\n",image_count,image_width,image_height);
   //
   // check and set limits
   //
   v.nx = image_width + (image_width-1)*p;
   v.ny = image_height + (image_height-1)*p;
   v.nz = image_count + (image_count-1)*p;
   v.dx = v.nx*pixel_size;
   v.dy = v.ny*pixel_size;
   v.dz = v.nz*pixel_size;
   v.xmin = 0;
   v.ymin = 0;
   v.zmin = 0;
   //
   // 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;
      }
   image_array = malloc(v.ny*sizeof(double *));
   for (y = 0; y < v.ny; ++y) {
      image_array[y] = malloc(v.nx*sizeof(double));
      for (x = 0; x < v.nx; ++x)
         image_array[y][x] = 0;
      }
   v.array = malloc(v.ny*sizeof(uint32_t *));
   for (y = 0; y < v.ny; ++y) {
      v.array[y] = malloc(v.nx*sizeof(uint32_t));
      for (x = 0; x < v.nx; ++x)
         v.array[y][x] = 0;
      }
   //
   // read the file
   //
   DGifCloseFile(GIFfile);
   GIFfile = DGifOpenFileName(argv[1]);
   if (GIFfile == NULL) {
      printf("gif_png: oops -- can not open %s\n",argv[1]);
      exit(-1);
      }
   z = 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);
            if (z == 0) {
               //
               // read first layer
               //
               for (y = 0; y < image_height; ++y) {
                  ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth);
                  if (ret != GIF_OK) {
                     printf("gif_png: oops -- error reading first line\n");
                     exit(-1);
                     }
                  for (x = 0; x < image_width; ++x)
                     upper_array[y][x] = GIFline[x];
                  }
               }
            else {
               //
               // read next layer
               //
               for (y = 0; y < image_height; ++y) {
                  ret = DGifGetLine(GIFfile,GIFline,GIFfile->SWidth);
                  if (ret != GIF_OK) {
                     printf("gif_png: oops -- error reading line\n");
                     exit(-1);
                     }
                  for (x = 0; x < image_width; ++x) {
                     lower_array[y][x] = upper_array[y][x];
                     upper_array[y][x] = GIFline[x];
                     }
                  }
               //
               // interpolate layer image
               //
               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) {
                              f = lower_array[y][x]*((p+1.0-i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((p+1.0-k)/(p+1.0))
                                + lower_array[y][x+1]*((i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((p+1.0-k)/(p+1.0))
                                + lower_array[y+1][x]*((p+1.0-i)/(p+1.0))*((j)/(p+1.0))*((p+1.0-k)/(p+1.0))
                                + lower_array[y+1][x+1]*((i)/(p+1.0))*((j)/(p+1.0))*((p+1.0-k)/(p+1.0))
                                + upper_array[y][x]*((p+1.0-i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((k)/(p+1.0))
                                + upper_array[y][x+1]*((i)/(p+1.0))*((p+1.0-j)/(p+1.0))*((k)/(p+1.0))
                                + upper_array[y+1][x]*((p+1.0-i)/(p+1.0))*((j)/(p+1.0))*((k)/(p+1.0))
                                + upper_array[y+1][x+1]*((i)/(p+1.0))*((j)/(p+1.0))*((k)/(p+1.0));
                              if (type == 'z') {
                                 image_array[(1+p)*y+j][(1+p)*x+i] += f;
                                 }
                              else if (type == 'h') {
                                 h = (1+p)*z+k;
                                 if ((f > arg) && (h > image_array[(1+p)*y+j][(1+p)*x+i]))
                                    image_array[(1+p)*y+j][(1+p)*x+i] = h;
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            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_png: oops -- undefined GIF record type\n");
            exit(-1);
            break;
         }
      } while (GIFtype != TERMINATE_RECORD_TYPE);
   printf("\n");
   //
   // scale image and copy to PNG array
   //
   if (type == 'z') {
      fmin = BIG;
      fmax = 0;
      for (x = 0; x < v.nx; ++x) {
         for (y = 0; y < v.ny; ++y) {
            if (image_array[y][x] > fmax) fmax = image_array[y][x];
            if (image_array[y][x] < fmin) fmin = image_array[y][x];
            }
         }
      if (arg == 1) {
         for (x = 0; x < v.nx; ++x)
            for (y = 0; y < v.ny; ++y)
               v.array[y][x] = 65536*(image_array[y][x]-fmin)/(fmax-fmin);
         }
      else {
         for (x = 0; x < v.nx; ++x)
            for (y = 0; y < v.ny; ++y)
               v.array[y][x] = 65536*pow((image_array[y][x]-fmin)/(fmax-fmin),arg);
         }
      }
   else if (type == 'h') {
      for (x = 0; x < v.nx; ++x)
         for (y = 0; y < v.ny; ++y)
            v.array[y][x] = 65536*image_array[y][x]/(v.nz-1.0);
      }
   //
   // write PNG
   //
   v.bit_depth = 16;
   fab_write_png_K(&v,argv[2]);
   //
   // exit
   //
   DGifCloseFile(GIFfile);
   exit(0);
   }
Example #24
0
int FileGIF::read_frame(VFrame *output, VFrame *input)
{
	data = input->get_data();
	offset = 0;
	size = input->get_compressed_size();

	GifFileType *gif_file;
	GifRowType *gif_buffer;
	gif_file = DGifOpen(this, input_func);
	
	
	if(gif_file == 0)
	{
		printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString());
		return 1;
	}
	gif_buffer = (GifRowType*)malloc(sizeof(GifRowType) * gif_file->SHeight);
	int row_size = gif_file->SWidth * sizeof(GifPixelType);
	gif_buffer[0] = (GifRowType)malloc(row_size);

	for(int i = 0; i < gif_file->SWidth; i++)
	{
		gif_buffer[0][i] = gif_file->SBackGroundColor;
	}

	for(int i = 0; i < gif_file->SHeight; i++)
	{
		gif_buffer[i] = (GifRowType)malloc(row_size);
		memcpy(gif_buffer[i], gif_buffer[0], row_size);
	}

	GifRecordType record_type;
	do
	{
		if(DGifGetRecordType(gif_file, &record_type) == GIF_ERROR)
		{
			printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString());
			break;
		}
		
		switch(record_type)
		{
			case IMAGE_DESC_RECORD_TYPE:
			{
				if(DGifGetImageDesc(gif_file) == GIF_ERROR)
				{
					printf("FileGIF::read_frame %d: %s\n", __LINE__, GifErrorString());
					break;
				}

				int row = gif_file->Image.Top;
				int col = gif_file->Image.Left;
				int width = gif_file->Image.Width;
				int height = gif_file->Image.Height;
				if(gif_file->Image.Left + gif_file->Image.Width > gif_file->SWidth ||
		 		  gif_file->Image.Top + gif_file->Image.Height > gif_file->SHeight)
				{
					DGifCloseFile(gif_file);
					for(int k = 0; k < gif_file->SHeight; k++)
					{
						free(gif_buffer[k]);
					}
					free(gif_buffer);
					return 1;
				}
				
				if (gif_file->Image.Interlace) 
				{
				    static int InterlacedOffset[] = { 0, 4, 2, 1 };
				    static int InterlacedJumps[] = { 8, 8, 4, 2 };
/* Need to perform 4 passes on the images: */
		    		for (int i = 0; i < 4; i++)
					{
						for (int j = row + InterlacedOffset[i]; 
							j < row + height;
							j += InterlacedJumps[i]) 
						{
			    			if (DGifGetLine(gif_file, 
								&gif_buffer[j][col],
								width) == GIF_ERROR) 
							{
								DGifCloseFile(gif_file);
								for(int k = 0; k < gif_file->SHeight; k++)
								{
									free(gif_buffer[k]);
								}
								free(gif_buffer);
								return 1;
			    			}
						}
					}
				}
				else 
				{
		    		for (int i = 0; i < height; i++) 
					{
						if (DGifGetLine(gif_file, &gif_buffer[row++][col],
							width) == GIF_ERROR) 
						{
							DGifCloseFile(gif_file);
							for(int k = 0; k < gif_file->SHeight; k++)
							{
								free(gif_buffer[k]);
							}
							free(gif_buffer);
			    			return 1;
						}
		    		}
				}
				
				break;
			}
			
		}
		
	} while(record_type != TERMINATE_RECORD_TYPE);

	
	int background = gif_file->SBackGroundColor;
	ColorMapObject *color_map = (gif_file->Image.ColorMap
		? gif_file->Image.ColorMap
		: gif_file->SColorMap);
	if(!color_map) 
	{
		DGifCloseFile(gif_file);
		for(int k = 0; k < gif_file->SHeight; k++)
		{
			free(gif_buffer[k]);
		}
		free(gif_buffer);
		return 1;
	}

	int screen_width = gif_file->SWidth;
	int screen_height = gif_file->SHeight;
	for(int i = 0; i < screen_height; i++)
	{
		GifRowType gif_row = gif_buffer[i];
		unsigned char *out_ptr = output->get_rows()[i];
		for(int j = 0; j < screen_width; j++)
		{
			GifColorType *color_map_entry = &color_map->Colors[gif_row[j]];
			*out_ptr++ = color_map_entry->Red;
			*out_ptr++ = color_map_entry->Green;
			*out_ptr++ = color_map_entry->Blue;
		}
	}

	
	for(int k = 0; k < gif_file->SHeight; k++)
	{
		free(gif_buffer[k]);
	}
	free(gif_buffer);
	DGifCloseFile(gif_file);
	return 0;
}
Example #25
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;
}
Example #26
0
static void Gif2Icon(char *FileName,
		     int fdin, int fdout,
		     char NameTable[])
{
    int i, ExtCode, ImageNum = 1;
    GifPixelType *Line, *cp;
    GifRecordType RecordType;
    GifByteType *Extension;
    GifFileType *GifFile;

    if (fdin == -1) {
	if ((GifFile = DGifOpenFileName(FileName)) == NULL) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
    }
    else {
	/* Use stdin instead: */
	if ((GifFile = DGifOpenFileHandle(fdin)) == NULL) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
    }

    printf("screen width %d\nscreen height %d\n",
	   GifFile->SWidth, GifFile->SHeight);

    printf("screen colors %d\nscreen background %d\n\n",
	   GifFile->SColorResolution,
	   GifFile->SBackGroundColor);

    if (GifFile->SColorMap)
    {
	if (GifFile->SColorMap->ColorCount >= (int)strlen(NameTable))
	{
	    (void) fprintf(stderr,
			   "%s: global color map has unprintable pixels\n",
			   FileName);
	    exit(EXIT_FAILURE);
	}

	printf("screen map\n");

	for (i = 0; i < GifFile->SColorMap->ColorCount; i++)
	    printf("\trgb %03d %03d %03d is %c\n",
		   GifFile->SColorMap ->Colors[i].Red,
		   GifFile->SColorMap ->Colors[i].Green,
		   GifFile->SColorMap ->Colors[i].Blue,
		   NameTable[i]);
	printf("end\n\n");
    }

    do {
	if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
	    PrintGifError();
	    exit(EXIT_FAILURE);
	}
	switch (RecordType) {
	case IMAGE_DESC_RECORD_TYPE:
	    if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
		PrintGifError();
		exit(EXIT_FAILURE);
	    }
	    printf("image # %d\nimage left %d\nimage top %d\n",
		   ImageNum++,
		   GifFile->Image.Left, GifFile->Image.Top);
	    if (GifFile->Image.Interlace)
		printf("interlaced\n");

	    if (GifFile->Image.ColorMap)
	    {
		if (GifFile->Image.ColorMap->ColorCount >= (int)strlen(NameTable))
		{
		    (void) fprintf(stderr,
				   "%s: global color map has unprintable pixels\n",
				   FileName);
		    exit(EXIT_FAILURE);
		}

		printf("image map\n");

		for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++)
		    printf("\trgb %03d %03d %03d is %c\n",
			   GifFile->Image.ColorMap ->Colors[i].Red,
			   GifFile->Image.ColorMap ->Colors[i].Green,
			   GifFile->Image.ColorMap ->Colors[i].Blue,
			   NameTable[i]);
		printf("end\n\n");
	    }

	    printf("image bits %d by %d\n",
		   GifFile->Image.Width, GifFile->Image.Height);

	    Line = (GifPixelType *) malloc(GifFile->Image.Width *
					   sizeof(GifPixelType));
	    for (i = 0; i < GifFile->Image.Height; i++) {
		if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
		    == GIF_ERROR) {
		    PrintGifError();
		    exit(EXIT_FAILURE);
		}
		for (cp = Line; cp < Line + GifFile->Image.Width; cp++)
		    putchar(NameTable[*cp]);
		putchar('\n');
	    }
	    free((char *) Line);
	    putchar('\n');

	    break;
	case EXTENSION_RECORD_TYPE:
	    if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
		PrintGifError();
		exit(EXIT_FAILURE);
	    }

	    if (ExtCode == COMMENT_EXT_FUNC_CODE)
		printf("comment\n");
	    else if (ExtCode == PLAINTEXT_EXT_FUNC_CODE)
		printf("plaintext\n");
	    else if (isalpha(ExtCode))
		printf("extension %02x    # %c\n", ExtCode, ExtCode);
	    else
		printf("extension %02x\n", ExtCode);

	    while (Extension != NULL) {
		VisibleDumpBuffer((char *)(Extension + 1), Extension[0]);
		putchar('\n');

		if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
		    PrintGifError();
		    exit(EXIT_FAILURE);
		}
	    }
	    printf("end\n\n");

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

    /* Tell EMACS this is a picture... */
    printf("# The following sets edit modes for GNU EMACS\n");
    printf("# Local ");		/* ...break this up, so that EMACS doesn't */
    printf("Variables:\n");	/* get confused when visiting *this* file! */
    printf("# mode:picture\n");
    printf("# truncate-lines:t\n");
    printf("# End:\n");

    if (fdin == -1)
	(void) printf("# End of %s dump\n", FileName);

    if (DGifCloseFile(GifFile) == GIF_ERROR) {
	PrintGifError();
	exit(EXIT_FAILURE);
    }
}
Example #27
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;
}
Example #28
0
File: gif.c Project: 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;
}
Example #29
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;
}
Example #30
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;
}