BmpLoader::BmpLoader(IO::Base &i, unsigned sb):
io(i),
- sig_bytes(sb)
+ sig_bytes(sb),
+ invert_row_order(false)
{
// Image data location is stored at offset 10 and can't be skipped
if(sig_bytes>10)
return !sig.compare(0, sizeof(bmp_sig), bmp_sig, sizeof(bmp_sig));
}
-void BmpLoader::load_(Image::Data &data)
+void BmpLoader::load_headers_(Image::Data &data)
{
char bm_header[14];
read_full(io, bm_header+sig_bytes, sizeof(bm_header)-sig_bytes);
skip -= size;
}
+ invert_row_order = (height<0);
+}
+
+void BmpLoader::load_pixels_(Image::Data &data)
+{
data.pixels = new char[data.stride*data.height];
- if(height<0)
+ if(invert_row_order)
{
for(unsigned y=0; y<data.height; ++y)
read_full(io, data.pixels+(data.height-1-y)*data.stride, data.stride);
private:
IO::Base &io;
unsigned sig_bytes;
+ bool invert_row_order;
public:
BmpLoader(IO::Base &, unsigned = 0);
static unsigned get_signature_size() { return 2; }
static bool detect(const std::string &);
- virtual void load_(Image::Data &);
+ virtual void load_headers_(Image::Data &);
+ virtual void load_pixels_(Image::Data &);
};
} // namespace Graphics
return type!=IL_TYPE_UNKNOWN;
}
-void DevilLoader::load_(Image::Data &data)
+void DevilLoader::load_headers_(Image::Data &data)
{
ilSetRead(0, 0, eof, get, read, seek, tell);
ilBindImage(id);
data.width = ilGetInteger(IL_IMAGE_WIDTH);
data.height = ilGetInteger(IL_IMAGE_HEIGHT);
data.stride = data.width*ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
+
+ ilBindImage(0);
+ ilResetRead();
+}
+
+void DevilLoader::load_pixels_(Image::Data &data)
+{
+ ilBindImage(id);
+
unsigned data_size = data.stride*data.height;
data.pixels = new char[data_size];
ILubyte *il_data = ilGetData();
copy(il_data, il_data+data_size, data.pixels);
ilBindImage(0);
- ilResetRead();
}
} // namespace Graphics
static unsigned get_signature_size() { return 128; }
static bool detect(const std::string &);
- virtual void load_(Image::Data &);
+ virtual void load_headers_(Image::Data &);
+ virtual void load_pixels_(Image::Data &);
};
} // namespace Graphics
void Image::load(ImageLoader &loader)
{
- data = Data();
+ if(loader.get_state()==ImageLoader::INITIAL)
+ data = Data();
loader.load(data);
}
+void Image::load_headers(ImageLoader &loader)
+{
+ if(loader.get_state()==ImageLoader::INITIAL)
+ data = Data();
+ loader.load_headers(data);
+}
+
} // namespace Graphics
} // namespace Msp
void load_file(const std::string &);
void load_io(IO::Seekable &);
void load(ImageLoader &);
+ void load_headers(ImageLoader &);
PixelFormat get_format() const { return data.fmt; }
unsigned get_width() const { return data.width; }
if(state>=FINISHED)
throw logic_error("already loaded");
- load_(data);
+ if(state<HEADERS_LOADED)
+ load_headers_(data);
+ load_pixels_(data);
state = FINISHED;
}
+void ImageLoader::load_headers(Image::Data &data)
+{
+ if(state>=HEADERS_LOADED)
+ throw logic_error("headers already loaded");
+
+ load_headers_(data);
+ state = HEADERS_LOADED;
+}
+
ImageLoader::Registry &ImageLoader::get_registry()
{
static Registry registry;
enum State
{
INITIAL,
+ HEADERS_LOADED,
FINISHED
};
static ImageLoader *open_io(IO::Seekable &);
virtual void load(Image::Data &);
+ virtual void load_headers(Image::Data &);
protected:
- virtual void load_(Image::Data &) = 0;
+ virtual void load_headers_(Image::Data &) = 0;
+ virtual void load_pixels_(Image::Data &) = 0;
public:
State get_state() const { return state; }
return !sig.compare(0, sizeof(jpeg_sig), jpeg_sig, sizeof(jpeg_sig));
}
-void JpegLoader::load_(Image::Data &data)
+void JpegLoader::load_headers_(Image::Data &data)
{
if(setjmp(priv->err_mgr.jmp))
throw bad_image_data(priv->err_mgr.message);
data.height = priv->jpeg.output_height;
data.stride = priv->jpeg.output_width*priv->jpeg.output_components;
data.fmt = RGB;
+}
+void JpegLoader::load_pixels_(Image::Data &data)
+{
data.pixels = new char[data.stride*data.height];
JSAMPROW rows[8];
while(priv->jpeg.output_scanline<data.height)
static unsigned get_signature_size() { return 3; }
static bool detect(const std::string &);
- virtual void load_(Image::Data &);
+ virtual void load_headers_(Image::Data &);
+ virtual void load_pixels_(Image::Data &);
};
} // namespace Graphics
std::string message;
png_struct *png;
png_info *info;
+ int interlace;
};
return !png_sig_cmp(reinterpret_cast<png_byte *>(const_cast<char*>(sig.data())), 0, sig.size());
}
-void PngLoader::load_(Image::Data &data)
+void PngLoader::load_headers_(Image::Data &data)
{
- png_byte **rows = 0;
-
if(setjmp(png_jmpbuf(priv->png)))
{
- delete[] rows;
throw bad_image_data(priv->message);
}
png_uint_32 height;
int depth;
int color;
- int interlace;
- png_get_IHDR(priv->png, priv->info, &width, &height, &depth, &color, &interlace, 0, 0);
+ png_get_IHDR(priv->png, priv->info, &width, &height, &depth, &color, &priv->interlace, 0, 0);
unsigned nchans = png_get_channels(priv->png, priv->info);
if(depth!=8)
case PNG_COLOR_TYPE_RGB_ALPHA: data.fmt = RGBA; break;
default: throw unsupported_image_format("unknown color type");
}
+}
+
+void PngLoader::load_pixels_(Image::Data &data)
+{
+ png_byte **rows = 0;
+
+ if(setjmp(png_jmpbuf(priv->png)))
+ {
+ delete[] rows;
+ throw bad_image_data(priv->message);
+ }
data.pixels = new char[data.stride*data.height];
- if(interlace==PNG_INTERLACE_ADAM7)
+ if(priv->interlace==PNG_INTERLACE_ADAM7)
{
// ADAM7 requires all rows to be loaded at once
unsigned n_passes = png_set_interlace_handling(priv->png);
static unsigned get_signature_size() { return 8; }
static bool detect(const std::string &);
- virtual void load_(Image::Data &);
+ virtual void load_headers_(Image::Data &);
+ virtual void load_pixels_(Image::Data &);
};
} // namespace Graphics
}
else
throw unsupported_image_format("unknown colorspace");
-
- CGDataProviderRef dp = CGImageGetDataProvider(image);
- CFDataRef image_data = CGDataProviderCopyData(dp);
- data.pixels = new char[data.height*data.stride];
- unsigned offset = (alpha==kCGImageAlphaNoneSkipFirst);
- CFRange range = CFRangeMake(offset, CFDataGetLength(image_data)-offset);
- CFDataGetBytes(image_data, range, reinterpret_cast<UInt8 *>(data.pixels));
- CFRelease(image_data);
-
- CFRelease(image);
}
catch(...)
{
}
}
+void QuartzLoader::load_(Image::Data &data)
+{
+ CGDataProviderRef dp = CGImageGetDataProvider(image);
+ CFDataRef image_data = CGDataProviderCopyData(dp);
+ data.pixels = new char[data.height*data.stride];
+ unsigned offset = (alpha==kCGImageAlphaNoneSkipFirst);
+ CFRange range = CFRangeMake(offset, CFDataGetLength(image_data)-offset);
+ CFDataGetBytes(image_data, range, reinterpret_cast<UInt8 *>(data.pixels));
+ CFRelease(image_data);
+
+ CFRelease(image);
+}
+
} // namespace Graphics
} // namespace Msp
static unsigned get_signature_size() { return 12; }
static bool detect(const std::string &);
- virtual void load_(Image::Data &);
+ virtual void load_headers_(Image::Data &);
+ virtual void load_pixels_(Image::Data &);
};
} // namespace Graphics