Class: Oil::JPEGReader
- Inherits:
-
Object
- Object
- Oil::JPEGReader
- Defined in:
- ext/oil/jpeg.c,
ext/oil/jpeg.c
Overview
Read a compressed JPEG image given an IO object.
Instance Method Summary collapse
-
#each(opts, &block) ⇒ self
Yields a series of binary strings that make up the output JPEG image.
-
#image_height ⇒ Numeric
The height of the image as indicated by the header.
-
#image_width ⇒ Numeric
The width of the of the image as indicated by the header.
-
#new(io_in[, markers]) ⇒ Object
constructor
Creates a new JPEG Reader.
-
#jpeg_color_space ⇒ Object
Returns a symbol representing the color model in which the JPEG is stored, as indicated by the image header.
-
#markers ⇒ Hash
Get a hash of raw marker data from the JPEG.
-
#num_components ⇒ Numeric
Retrieve the number of components per pixel as indicated by the image header.
-
#out_color_components ⇒ Numeric
Retrieve the number of components in the output color space.
-
#out_color_space ⇒ Object
Returns a symbol representing the color model to which the image will be converted on decompress.
-
#out_color_space=(symbol) ⇒ Object
Set the color model to which the image will be converted on decompress.
-
#output_components ⇒ Numeric
Retrieve the number of bytes per pixel that will be in the output image.
-
#image_height ⇒ Numeric
The height of the image that will be output by the decompressor.
-
#output_width ⇒ Numeric
The width of the of the image that will be output by the decompressor.
-
#scale_denom ⇒ Numeric
Retrieve the denominator of the fraction by which the JPEG will be scaled as it is read.
-
#scale_denom=(number) ⇒ Object
Set the denominator of the fraction by which the JPEG will be scaled as it is read.
-
#scale_height ⇒ Numeric
Retrieve the height to which the image will be resized after decompression.
-
#scale_height=(number) ⇒ Object
Set the height to which the image will be resized after decompression.
-
#scale_num ⇒ Numeric
Retrieve the numerator of the fraction by which the JPEG will be scaled as it is read.
-
#scale_num=(number) ⇒ Object
Set the numerator of the fraction by which the JPEG will be scaled as it is read.
-
#scale_width ⇒ Numeric
Retrieve the width to which the image will be resized after decompression.
-
#scale_width=(number) ⇒ Object
Set the width to which the image will be resized after decompression.
Constructor Details
#new(io_in[, markers]) ⇒ Object
Creates a new JPEG Reader. io_in
must be an IO-like object that responds to read(size).
markers
should be an array of valid JPEG header marker symbols. Valid symbols are :APP0 through :APP15 and :COM.
If performance is important, you can avoid reading any header markers by supplying an empty array, [].
When markers are not specified, we read all known JPEG markers.
io = File.open("image.jpg", "r")
reader = Oil::JPEGReader.new(io)
io = File.open("image.jpg", "r")
reader = Oil::JPEGReader.new(io, [:APP1, :APP2])
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'ext/oil/jpeg.c', line 289
static VALUE initialize(int argc, VALUE *argv, VALUE self)
{
struct readerdata *reader;
VALUE io, markers;
struct jpeg_decompress_struct *dinfo;
int i, marker_code;
Data_Get_Struct(self, struct readerdata, reader);
dinfo = &reader->dinfo;
/* If source_io has already been set, then this is a re-used jpeg reader
* object. This means we need to abort the previous decompress to
* prevent memory leaks.
*/
if (reader->source_io) {
jpeg_abort_decompress(dinfo);
} else {
jpeg_create_decompress(dinfo);
}
dinfo->src = &reader->mgr;
rb_scan_args(argc, argv, "11", &io, &markers);
reader->source_io = io;
reader->mgr.bytes_in_buffer = 0;
if(!NIL_P(markers)) {
Check_Type(markers, T_ARRAY);
for (i=0; i<RARRAY_LEN(markers); i++) {
if (!SYMBOL_P(RARRAY_PTR(markers)[i])) {
rb_raise(rb_eTypeError, "Marker code is not a symbol.");
}
marker_code = sym_to_marker_code(RARRAY_PTR(markers)[i]);
jpeg_save_markers(dinfo, marker_code, 0xFFFF);
}
}
/* Be warned that this can raise a ruby exception and longjmp away. */
jpeg_read_header(dinfo, TRUE);
jpeg_calc_output_dimensions(dinfo);
return self;
}
|
Instance Method Details
#each(opts, &block) ⇒ self
Yields a series of binary strings that make up the output JPEG image.
Options is a hash which may have the following symbols:
:quality - JPEG quality setting. Betweein 0 and 100. :markers - Custom markers to include in the output JPEG. Must be a hash where
the keys are :APP[0-15] or :COM and the values are arrays of strings that
will be inserted into the markers.
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 |
# File 'ext/oil/jpeg.c', line 831
static VALUE each(int argc, VALUE *argv, VALUE self)
{
struct readerdata *reader;
struct writerdata writer;
int state, width_out, ret;
struct write_jpeg_args args;
unsigned char *outwidthbuf;
VALUE opts;
rb_scan_args(argc, argv, "01", &opts);
Data_Get_Struct(self, struct readerdata, reader);
if (!reader->scale_width) {
reader->scale_width = reader->dinfo.output_width;
}
if (!reader->scale_height) {
reader->scale_height = reader->dinfo.output_height;
}
writer.cinfo.err = &reader->jerr;
jpeg_create_compress(&writer.cinfo);
width_out = reader->scale_width;
ret = oil_libjpeg_init(&args.ol, &reader->dinfo, width_out,
reader->scale_height);
if (ret!=0) {
jpeg_destroy_compress(&writer.cinfo);
rb_raise(rb_eRuntimeError, "Unable to allocate memory.");
}
outwidthbuf = malloc(width_out * OIL_CMP(args.ol.os.cs));
if (!outwidthbuf) {
oil_libjpeg_free(&args.ol);
jpeg_destroy_compress(&writer.cinfo);
rb_raise(rb_eRuntimeError, "Unable to allocate memory.");
}
args.reader = reader;
args.opts = opts;
args.writer = &writer;
args.outwidthbuf = outwidthbuf;
reader->locked = 1;
rb_protect((VALUE(*)(VALUE))each2, (VALUE)&args, &state);
oil_libjpeg_free(&args.ol);
free(outwidthbuf);
jpeg_destroy_compress(&writer.cinfo);
if (state) {
rb_jump_tag(state);
}
return self;
}
|
#image_height ⇒ Numeric
The height of the image as indicated by the header.
This may differ from the height of the image that will be returned by the decompressor if we request DCT scaling.
476 477 478 479 480 481 |
# File 'ext/oil/jpeg.c', line 476
static VALUE image_height(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->image_height);
}
|
#image_width ⇒ Numeric
The width of the of the image as indicated by the header.
This may differ from the width of the image that will be returned by the decompressor if we request DCT scaling.
459 460 461 462 463 464 |
# File 'ext/oil/jpeg.c', line 459
static VALUE image_width(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->image_width);
}
|
#jpeg_color_space ⇒ Object
Returns a symbol representing the color model in which the JPEG is stored, as indicated by the image header.
Possible color models are: :GRAYSCALE, :RGB, :YCbCr, :CMYK, and :YCCK. This method will return :UNKNOWN if the color model is not recognized.
This may differ from the color space that will be returned by the decompressor if we ask for a color space transformation.
400 401 402 403 404 405 406 407 408 409 |
# File 'ext/oil/jpeg.c', line 400
static VALUE jpeg_color_space(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
ID id;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
id = j_color_space_to_id(dinfo->jpeg_color_space);
return ID2SYM(id);
}
|
#markers ⇒ Hash
Get a hash of raw marker data from the JPEG.
The keys in the hash are the marker codes as symbols. The values are arrays.
Arrays since there may be multiple instances of a single marker in a JPEG marker.
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
# File 'ext/oil/jpeg.c', line 523
static VALUE markers(VALUE self)
{
struct jpeg_decompress_struct *dinfo;
jpeg_saved_marker_ptr marker;
VALUE hash, ary, key, val;
hash = rb_hash_new();
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
for (marker=dinfo->marker_list; marker; marker=marker->next) {
key = marker_code_to_sym(marker->marker);
ary = rb_hash_aref(hash, key);
if (NIL_P(ary)) {
ary = rb_ary_new();
rb_hash_aset(hash, key, ary);
}
val = rb_str_new((char *)marker->data, marker->data_length);
rb_ary_push(ary, val);
}
return hash;
}
|
#num_components ⇒ Numeric
Retrieve the number of components per pixel as indicated by the image header.
This may differ from the number of components that will be returned by the decompressor if we ask for a color space transformation.
345 346 347 348 349 350 |
# File 'ext/oil/jpeg.c', line 345
static VALUE num_components(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->num_components);
}
|
#out_color_components ⇒ Numeric
Retrieve the number of components in the output color space.
Some color spaces have padding, so this may not accurately represent the size of output pixels.
379 380 381 382 383 384 |
# File 'ext/oil/jpeg.c', line 379
static VALUE out_color_components(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->out_color_components);
}
|
#out_color_space ⇒ Object
Returns a symbol representing the color model to which the image will be converted on decompress.
419 420 421 422 423 424 425 426 427 428 |
# File 'ext/oil/jpeg.c', line 419
static VALUE out_color_space(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
ID id;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
id = j_color_space_to_id(dinfo->out_color_space);
return ID2SYM(id);
}
|
#out_color_space=(symbol) ⇒ Object
Set the color model to which the image will be converted on decompress.
437 438 439 440 441 442 443 444 445 446 447 |
# File 'ext/oil/jpeg.c', line 437
static VALUE set_out_color_space(VALUE self, VALUE cs)
{
struct readerdata *reader;
Data_Get_Struct(self, struct readerdata, reader);
raise_if_locked(reader);
reader->dinfo.out_color_space = sym_to_j_color_space(cs);
jpeg_calc_output_dimensions(&reader->dinfo);
return cs;
}
|
#output_components ⇒ Numeric
Retrieve the number of bytes per pixel that will be in the output image.
Not all bytes will necessarily have data, since some color spaces have padding.
362 363 364 365 366 367 |
# File 'ext/oil/jpeg.c', line 362
static VALUE output_components(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->output_components);
}
|
#image_height ⇒ Numeric
The height of the image that will be output by the decompressor.
504 505 506 507 508 509 |
# File 'ext/oil/jpeg.c', line 504
static VALUE output_height(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->output_height);
}
|
#output_width ⇒ Numeric
The width of the of the image that will be output by the decompressor.
490 491 492 493 494 495 |
# File 'ext/oil/jpeg.c', line 490
static VALUE output_width(VALUE self)
{
struct jpeg_decompress_struct * dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->output_width);
}
|
#scale_denom ⇒ Numeric
Retrieve the denominator of the fraction by which the JPEG will be scaled as it is read. This is 1, 2, 4, or 8 for libjpeg version 6b. In version 8b this is always the source DCT size, which is 8 for baseline JPEG.
593 594 595 596 597 598 |
# File 'ext/oil/jpeg.c', line 593
static VALUE scale_denom(VALUE self)
{
struct jpeg_decompress_struct *dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->scale_denom);
}
|
#scale_denom=(number) ⇒ Object
Set the denominator of the fraction by which the JPEG will be scaled as it is read. This can be set to 1, 2, 4, or 8 for libjpeg version 6b. In version 8b this must always be the source DCT size, which is 8 for baseline JPEG.
Prior to version 1.2, libjpeg-turbo will not scale down images on decompression, and this option will do nothing.
612 613 614 615 616 617 618 619 620 621 622 |
# File 'ext/oil/jpeg.c', line 612
static VALUE set_scale_denom(VALUE self, VALUE scale_denom)
{
struct readerdata *reader;
Data_Get_Struct(self, struct readerdata, reader);
raise_if_locked(reader);
reader->dinfo.scale_denom = NUM2INT(scale_denom);
jpeg_calc_output_dimensions(&reader->dinfo);
return scale_denom;
}
|
#scale_height ⇒ Numeric
Retrieve the height to which the image will be resized after decompression. A height of 0 means the image will remain at original height.
664 665 666 667 668 669 |
# File 'ext/oil/jpeg.c', line 664
static VALUE scale_height(VALUE self)
{
struct readerdata *reader;
Data_Get_Struct(self, struct readerdata, reader);
return INT2FIX(reader->scale_height);
}
|
#scale_height=(number) ⇒ Object
Set the height to which the image will be resized after decompression. A height of 0 means the image will remain at original height.
679 680 681 682 683 684 685 686 |
# File 'ext/oil/jpeg.c', line 679
static VALUE set_scale_height(VALUE self, VALUE scale_height)
{
struct readerdata *reader;
Data_Get_Struct(self, struct readerdata, reader);
raise_if_locked(reader);
reader->scale_height = NUM2INT(scale_height);
return scale_height;
}
|
#scale_num ⇒ Numeric
Retrieve the numerator of the fraction by which the JPEG will be scaled as it is read. This is always 1 for libjpeg version 6b. In version 8b this can be 1 to 16.
556 557 558 559 560 561 |
# File 'ext/oil/jpeg.c', line 556
static VALUE scale_num(VALUE self)
{
struct jpeg_decompress_struct *dinfo;
Data_Get_Struct(self, struct jpeg_decompress_struct, dinfo);
return INT2FIX(dinfo->scale_num);
}
|
#scale_num=(number) ⇒ Object
Set the numerator of the fraction by which the JPEG will be scaled as it is read. This must always be 1 for libjpeg version 6b. In version 8b this can be set to 1 through 16.
572 573 574 575 576 577 578 579 580 581 582 |
# File 'ext/oil/jpeg.c', line 572
static VALUE set_scale_num(VALUE self, VALUE scale_num)
{
struct readerdata *reader;
Data_Get_Struct(self, struct readerdata, reader);
raise_if_locked(reader);
reader->dinfo.scale_num = NUM2INT(scale_num);
jpeg_calc_output_dimensions(&reader->dinfo);
return scale_num;
}
|
#scale_width ⇒ Numeric
Retrieve the width to which the image will be resized after decompression. A width of 0 means the image will remain at original width.
632 633 634 635 636 637 |
# File 'ext/oil/jpeg.c', line 632
static VALUE scale_width(VALUE self)
{
struct readerdata *reader;
Data_Get_Struct(self, struct readerdata, reader);
return INT2FIX(reader->scale_width);
}
|
#scale_width=(number) ⇒ Object
Set the width to which the image will be resized after decompression. A width of 0 means the image will remain at original width.
647 648 649 650 651 652 653 654 |
# File 'ext/oil/jpeg.c', line 647
static VALUE set_scale_width(VALUE self, VALUE scale_width)
{
struct readerdata *reader;
Data_Get_Struct(self, struct readerdata, reader);
raise_if_locked(reader);
reader->scale_width = NUM2INT(scale_width);
return scale_width;
}
|