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])
282 283 284 285 286 287 288 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 |
# File 'ext/oil/jpeg.c', line 282
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.
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 |
# File 'ext/oil/jpeg.c', line 833
static VALUE each(int argc, VALUE *argv, VALUE self)
{
struct readerdata *reader;
struct writerdata writer;
int cmp, state;
struct write_jpeg_args args;
unsigned char *inwidthbuf, *outwidthbuf;
struct yscaler ys;
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);
cmp = reader->dinfo.output_components;
inwidthbuf = malloc(reader->dinfo.output_width * cmp);
outwidthbuf = malloc(reader->scale_width * cmp);
yscaler_init(&ys, reader->dinfo.output_height, reader->scale_height,
reader->scale_width * cmp);
args.reader = reader;
args.opts = opts;
args.writer = &writer;
args.inwidthbuf = inwidthbuf;
args.outwidthbuf = outwidthbuf;
args.ys = &ys;
reader->locked = 1;
rb_protect((VALUE(*)(VALUE))each2, (VALUE)&args, &state);
yscaler_free(&ys);
free(inwidthbuf);
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.
469 470 471 472 473 474 |
# File 'ext/oil/jpeg.c', line 469
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.
452 453 454 455 456 457 |
# File 'ext/oil/jpeg.c', line 452
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.
393 394 395 396 397 398 399 400 401 402 |
# File 'ext/oil/jpeg.c', line 393
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.
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
# File 'ext/oil/jpeg.c', line 516
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.
338 339 340 341 342 343 |
# File 'ext/oil/jpeg.c', line 338
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.
372 373 374 375 376 377 |
# File 'ext/oil/jpeg.c', line 372
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.
412 413 414 415 416 417 418 419 420 421 |
# File 'ext/oil/jpeg.c', line 412
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.
430 431 432 433 434 435 436 437 438 439 440 |
# File 'ext/oil/jpeg.c', line 430
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.
355 356 357 358 359 360 |
# File 'ext/oil/jpeg.c', line 355
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.
497 498 499 500 501 502 |
# File 'ext/oil/jpeg.c', line 497
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.
483 484 485 486 487 488 |
# File 'ext/oil/jpeg.c', line 483
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.
586 587 588 589 590 591 |
# File 'ext/oil/jpeg.c', line 586
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.
605 606 607 608 609 610 611 612 613 614 615 |
# File 'ext/oil/jpeg.c', line 605
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.
657 658 659 660 661 662 |
# File 'ext/oil/jpeg.c', line 657
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.
672 673 674 675 676 677 678 679 |
# File 'ext/oil/jpeg.c', line 672
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.
549 550 551 552 553 554 |
# File 'ext/oil/jpeg.c', line 549
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.
565 566 567 568 569 570 571 572 573 574 575 |
# File 'ext/oil/jpeg.c', line 565
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.
625 626 627 628 629 630 |
# File 'ext/oil/jpeg.c', line 625
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.
640 641 642 643 644 645 646 647 |
# File 'ext/oil/jpeg.c', line 640
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;
}
|