예제 #1
0
static int
read_logical_screen_descriptor(Gif_Stream *gfs, Gif_Reader *grr)
     /* returns 0 on memory error */
{
  uint8_t packed;

  /* we don't care about logical screen width or height */
  gfs->screen_width = gifgetunsigned(grr);
  gfs->screen_height = gifgetunsigned(grr);

  packed = gifgetbyte(grr);
  gfs->background = gifgetbyte(grr);

  /* don't care about pixel aspect ratio */
  gifgetbyte(grr);

  if (packed & 0x80) { /* have a global color table */
    int ncol = 1 << ((packed & 0x07) + 1);
    gfs->global = read_color_table(ncol, grr);
    if (!gfs->global) return 0;
    gfs->global->refcount = 1;
  }

  return 1;
}
예제 #2
0
파일: bmp.cpp 프로젝트: kakukogou/cmlib
	void BmpReader::init(FILE* f, size_t& w, size_t& h)
	{
		my_file = f;
		my_pixel_offset = read_file_header(f);
		size_t bpp, table_num;
		read_image_header(f, w, h, bpp, table_num);
		if(bpp == 8)
			read_color_table(f, my_color_table, table_num);
		else if(bpp != 24)
			throw InvalidFormat("unexpected bits per pixel in BMP image header");
	}
예제 #3
0
파일: gif.c 프로젝트: deaddodo/byua
void gif_process_image(FILE *fp, image_t *img) {
    logical_screen_descriptor_t lsd;
    color_table_t gct;
    graphic_control_extension_t gce = {0,0,0,0, false};
    bool data_left = true;
    
    lsd = read_header(&fp);
    
    (*img).width = lsd.w;
    (*img).height = lsd.h;
    (*img).frames = 1;
    (*img).animate = false;
    (*img).canvas = malloc(sizeof(rgba_t)); // init one frame right now
    (*img).canvas[0] = malloc(lsd.w * lsd.h * sizeof(rgba_t)); // setup first frame
    
    if(check_nth_bit(lsd.meta, 0)) {
        gct.active = true;
        gct.size = ((0x07&lsd.meta)+1);
        gct.size = gct.size * gct.size;
        read_color_table(&fp, &gct);
    } else {
        gct.active = false;
    }
    
    while(data_left) {
        unsigned char bt;
        fread(&bt, 1, 1, fp);
        
        switch(bt) {
        case 0x21: // extension
            fread(&bt, 1, 1, fp);
            if(bt == 0xF9) {
                fread(&gce, 1, sizeof(graphic_control_extension_t), fp);
                gce.set = true;
            }
            break;
        case 0x2c: // image
            process_image_block(&fp, &gct, (*img).canvas[0], &gce);
            gce.set = false; // no need to overwrite, just ignore
            break;
        case 0x3b: // trailer
            data_left = false;
            break;
        };
    }
    
    if(gct.active) {
        close_color_table(&gct);
    }
}
예제 #4
0
파일: gif.c 프로젝트: deaddodo/byua
void process_image_block(FILE **fp, color_table_t *gct, rgba_t *canvas, graphic_control_extension_t *gce) {
    image_descriptor_t id;
    color_table_t lct;
    color_table_t *ct;
    unsigned char code_size;
    unsigned char block_size;
    
    fread(&id, 1, sizeof(image_descriptor_t), *fp);
    
    if(check_nth_bit(id.meta, 0)) {
        lct.active = true;
        lct.size = ((0x07&id.meta)+1);
        lct.size = lct.size * lct.size;
        read_color_table(fp, &lct);
        ct = &lct;
    } else {
        lct.active = false;
        ct = gct;
    }
    
    fread(&code_size, 1, 1, *fp);
    
    printf("Processing Image block...\n");
    do {
        fread(&block_size, 1, 1, *fp);
    
        if(block_size != 0x00) {
            unsigned char *raw_data;
            unsigned char *processed_data;
            
            raw_data = malloc(sizeof(unsigned char)*block_size);
            for(int i = 0; i < block_size; ++i) {
                fread(&raw_data[i], 1, 1, *fp);
            }
            processed_data = malloc(id.w * id.h);
            decompress(code_size, raw_data, block_size, processed_data);
            for(int i = 0; i < (id.w * id.h); ++i) {
                canvas[i] = (*ct).table[processed_data[i]];
            }
            
            free(raw_data);
            free(processed_data);
        }
    } while(block_size != 0x00);
    printf("Block process complete.\n");
    
    if(lct.active) {
        close_color_table(&lct);
    }
}
예제 #5
0
파일: gifread.c 프로젝트: jaseg/gifsicle
static int
read_image(Gif_Reader *grr, Gif_Context *gfc, Gif_Image *gfi, int read_flags)
/* returns 0 on memory error */
{
    uint8_t packed;

    gfi->left = gifgetunsigned(grr);
    gfi->top = gifgetunsigned(grr);
    gfi->width = gifgetunsigned(grr);
    gfi->height = gifgetunsigned(grr);
    packed = gifgetbyte(grr);
    GIF_DEBUG(("<%ux%u>", gfi->width, gfi->height));

    if (packed & 0x80) { /* have a local color table */
        int ncol = 1 << ((packed & 0x07) + 1);
        gfi->local = read_color_table(ncol, grr);
        if (!gfi->local) return 0;
        gfi->local->refcount = 1;
    }

    gfi->interlace = (packed & 0x40) != 0;

    /* Keep the compressed data if asked */
    if (read_flags & GIF_READ_COMPRESSED) {
        if (!read_compressed_image(gfi, grr, read_flags))
            return 0;
        if (read_flags & GIF_READ_UNCOMPRESSED) {
            Gif_Reader new_grr;
            make_data_reader(&new_grr, gfi->compressed, gfi->compressed_len);
            if (!uncompress_image(gfc, gfi, &new_grr))
                return 0;
        }

    } else if (read_flags & GIF_READ_UNCOMPRESSED) {
        if (!uncompress_image(gfc, gfi, grr))
            return 0;

    } else {
        /* skip over the image */
        uint8_t buffer[GIF_MAX_BLOCK];
        int i = gifgetbyte(grr);
        while (i > 0) {
            gifgetblock(buffer, i, grr);
            i = gifgetbyte(grr);
        }
    }

    return 1;
}
예제 #6
0
static int
read_image(Gif_Reader *grr, Gif_Context *gfc, Gif_Image *gfi, int read_flags)
     /* returns 0 on memory error */
{
  uint8_t packed;

  gfi->left = gifgetunsigned(grr);
  gfi->top = gifgetunsigned(grr);
  gfi->width = gifgetunsigned(grr);
  gfi->height = gifgetunsigned(grr);
  /* Mainline GIF processors (Firefox, etc.) process missing width (height)
     as screen_width (screen_height). */
  if (gfi->width == 0)
      gfi->width = gfc->stream->screen_width;
  if (gfi->height == 0)
      gfi->height = gfc->stream->screen_height;
  /* If still zero, error. */
  if (gfi->width == 0 || gfi->height == 0) {
      gif_read_error(gfc, 1, "image has zero width and/or height");
      Gif_MakeImageEmpty(gfi);
      read_flags = 0;
  }
  /* If position out of range, error. */
  if ((unsigned) gfi->left + (unsigned) gfi->width > 0xFFFF
      || (unsigned) gfi->top + (unsigned) gfi->height > 0xFFFF) {
      gif_read_error(gfc, 1, "image position and/or dimensions out of range");
      Gif_MakeImageEmpty(gfi);
      read_flags = 0;
  }
  GIF_DEBUG(("<%ux%u>", gfi->width, gfi->height));

  packed = gifgetbyte(grr);
  if (packed & 0x80) { /* have a local color table */
    int ncol = 1 << ((packed & 0x07) + 1);
    gfi->local = read_color_table(ncol, grr);
    if (!gfi->local) return 0;
    gfi->local->refcount = 1;
  }

  gfi->interlace = (packed & 0x40) != 0;

  /* Keep the compressed data if asked */
  if (read_flags & GIF_READ_COMPRESSED) {
    if (!read_compressed_image(gfi, grr, read_flags))
      return 0;
    if (read_flags & GIF_READ_UNCOMPRESSED) {
      Gif_Reader new_grr;
      make_data_reader(&new_grr, gfi->compressed, gfi->compressed_len);
      if (!uncompress_image(gfc, gfi, &new_grr))
	return 0;
    }

  } else if (read_flags & GIF_READ_UNCOMPRESSED) {
    if (!uncompress_image(gfc, gfi, grr))
      return 0;

  } else {
    /* skip over the image */
    uint8_t buffer[GIF_MAX_BLOCK];
    int i = gifgetbyte(grr);
    while (i > 0) {
      gifgetblock(buffer, i, grr);
      i = gifgetbyte(grr);
    }
  }

  return 1;
}
예제 #7
0
static Bitmap read_bmp_or_throw(const FilePath& filePath){
  BinaryReader in(filePath);
  if (!in.good()){
    throw ReadBmpError(error_open_file_read(filePath));
  }

  auto bitmapFileHeader = read_struct_or_throw_bmp<BitmapFileHeader>(in);

  if (bitmapFileHeader.fileType != BITMAP_SIGNATURE){
    throw ReadBmpError(error_bitmap_signature(bitmapFileHeader.fileType));
  }

  auto bitmapInfoHeader = read_struct_or_throw_bmp<BitmapInfoHeader>(in);

  if (invalid_header_length(bitmapInfoHeader.headerLen)){
    throw ReadBmpError(error_truncated_bmp_header(bitmapInfoHeader.headerLen));
  }

  if (bitmapInfoHeader.compression != Compression::BI_RGB){
    throw ReadBmpError(error_compression(bitmapInfoHeader.compression));
  }

  if (bitmapInfoHeader.colorPlanes != 1){
    throw ReadBmpError(error_color_planes(bitmapInfoHeader.colorPlanes));
  }

  auto bmpSize = get_size_and_order(bitmapInfoHeader);

  if (bitmapInfoHeader.paletteColors != 0){
    if (bitmapInfoHeader.bitsPerPixel != 8){ // Fixme: Maybe support?
      throw ReadBmpError("Palette for non 8-bpp bitmaps unsupported by Faint.");
    }
    auto colorList = or_throw(read_color_table(in, bitmapInfoHeader.paletteColors),
      "Failed reading color table.");
    in.seekg(bitmapFileHeader.dataOffset);

    auto alphaMap = or_throw(read_8bipp_BI_RGB(in, bmpSize),
      "Failed reading 8-bits-per-pixel data");

    return bitmap_from_indexed_colors(alphaMap, colorList);
  }
  else{
    // No palette
    in.seekg(bitmapFileHeader.dataOffset);
    if (bitmapInfoHeader.bitsPerPixel == 8){
      auto alphaMap = or_throw(read_8bipp_BI_RGB(in, bmpSize),
        "Failed reading 8-bits-per-pixel data");
      return bitmap_from_indexed_colors(alphaMap, grayscale_color_table());
    }
    else if (bitmapInfoHeader.bitsPerPixel == 24){
      return or_throw(read_24bipp_BI_RGB(in, bmpSize),
        "Failed reading 24-bits-per-pixel data.");
    }
    else if (bitmapInfoHeader.bitsPerPixel == 32){
      return or_throw(read_32bipp_BI_RGB(in, bmpSize),
        "Failed reading 32-bits-per-pixel data.");
    }
  }
  throw ReadBmpError(Sentence("Unsupported bits-per-pixel",
    bracketed(str_int(bitmapInfoHeader.bitsPerPixel))));
}