Module: ImagePack
- Defined in:
- lib/image_pack.rb,
lib/image_pack/errors.rb,
lib/image_pack/backend.rb,
lib/image_pack/version.rb,
lib/image_pack/configuration.rb,
ext/image_pack/image_pack.c
Defined Under Namespace
Modules: Backend Classes: CancelledError, Configuration, EncodeError, Error, InvalidArgumentError, InvalidImageError, LimitExceededError, OutOfMemoryError, QualityConstraintError, UnsupportedError
Constant Summary collapse
- ALGOS =
%i[jpeg_turbo mozjpeg].freeze
- EXECUTION_MODES =
%i[direct nogvl offload auto].freeze
- DEFAULT_QUALITY =
82- VERSION =
"0.2.0"
Class Method Summary collapse
- .__compress_jpeg(input, input_kind, output, output_kind, algo, quality, min_ssim, mozjpeg_trellis, progressive, strip_metadata, execution, cancellable, has_scheduler) ⇒ Object
- .__compress_pixels(buffer, width, height, channels, output, output_kind, algo, quality, progressive, execution, cancellable, has_scheduler) ⇒ Object
- .__inspect_image(input, input_kind) ⇒ Object
- .compress(input, output: nil, algo: :jpeg_turbo, quality: nil, min_ssim: nil, mozjpeg_trellis: true, progressive: false, strip_metadata: true, execution: nil, cancellable: false) ⇒ Object
- .compress_pixels(buffer, width:, height:, channels:, output: nil, algo: :jpeg_turbo, quality: DEFAULT_QUALITY, progressive: false, execution: nil, cancellable: false) ⇒ Object
- .configuration ⇒ Object
- .configure {|configuration| ... } ⇒ Object
- .inspect_image(input) ⇒ Object
Class Method Details
.__compress_jpeg(input, input_kind, output, output_kind, algo, quality, min_ssim, mozjpeg_trellis, progressive, strip_metadata, execution, cancellable, has_scheduler) ⇒ Object
1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 |
# File 'ext/image_pack/image_pack.c', line 1492
static VALUE ip_compress_jpeg_entry(VALUE self, VALUE input, VALUE input_kind, VALUE output,
VALUE output_kind, VALUE algo, VALUE quality, VALUE min_ssim,
VALUE mozjpeg_trellis, VALUE progressive, VALUE strip_metadata,
VALUE execution, VALUE cancellable, VALUE has_scheduler) {
ip_context_t *ctx = ip_context_new();
if (!ctx)
rb_raise(rb_eImagePackOutOfMemoryError, "failed to allocate native context");
ip_output_kind_t out_kind = ip_parse_output_kind(output_kind);
ctx->algo = ip_parse_algo(algo);
ctx->quality = NUM2INT(quality);
ctx->selected_quality = ctx->quality;
ip_validate_quality_or_raise(ctx);
ctx->min_ssim = NUM2DBL(min_ssim);
ctx->ssim_guard_enabled = ctx->min_ssim > 0.0;
ip_validate_min_ssim_or_raise(ctx);
ctx->mozjpeg_trellis_enabled = ip_bool_value(mozjpeg_trellis);
ctx->progressive = ip_bool_value(progressive);
ctx->strip_metadata = ip_bool_value(strip_metadata);
ctx->requested_execution = ip_parse_execution(execution);
ctx->cancellable_requested = ip_bool_value(cancellable);
ctx->has_scheduler = ip_bool_value(has_scheduler);
apply_configuration(self, ctx);
if (!ip_prepare_input_bytes(ctx, input, ip_parse_input_kind(input_kind)) ||
!ip_prepare_output_path(ctx, output, out_kind)) {
VALUE exception = ip_status_to_exception(ctx->status);
char message[512];
snprintf(message, sizeof(message), "%s", ctx->error_message);
ip_context_free(ctx);
rb_raise(exception, "%s", message[0] ? message : "invalid JPEG input");
}
if (ctx->requested_execution == IP_EXEC_AUTO && ctx->input_size < ctx->direct_input_threshold &&
!ip_inspect_jpeg_header(ctx)) {
VALUE exception = ip_status_to_exception(ctx->status);
char message[512];
snprintf(message, sizeof(message), "%s", ctx->error_message);
ip_context_free(ctx);
rb_raise(exception, "%s", message[0] ? message : "invalid JPEG input");
}
ip_run_context(ctx);
VALUE result = ip_finish_output(ctx, out_kind);
ip_context_free(ctx);
return result;
}
|
.__compress_pixels(buffer, width, height, channels, output, output_kind, algo, quality, progressive, execution, cancellable, has_scheduler) ⇒ Object
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 |
# File 'ext/image_pack/image_pack.c', line 1540
static VALUE ip_compress_pixels_entry(VALUE self, VALUE buffer, VALUE width, VALUE height,
VALUE channels, VALUE output, VALUE output_kind, VALUE algo,
VALUE quality, VALUE progressive, VALUE execution,
VALUE cancellable, VALUE has_scheduler) {
ip_context_t *ctx = ip_context_new();
if (!ctx)
rb_raise(rb_eImagePackOutOfMemoryError, "failed to allocate native context");
ip_output_kind_t out_kind = ip_parse_output_kind(output_kind);
ctx->algo = ip_parse_algo(algo);
ctx->quality = NUM2INT(quality);
ip_validate_quality_or_raise(ctx);
ctx->progressive = ip_bool_value(progressive);
ctx->strip_metadata = 1;
ctx->requested_execution = ip_parse_execution(execution);
ctx->cancellable_requested = ip_bool_value(cancellable);
ctx->has_scheduler = ip_bool_value(has_scheduler);
apply_configuration(self, ctx);
if (!ip_prepare_pixels(ctx, buffer, NUM2INT(width), NUM2INT(height), NUM2INT(channels)) ||
!ip_prepare_output_path(ctx, output, out_kind)) {
VALUE exception = ip_status_to_exception(ctx->status);
char message[512];
snprintf(message, sizeof(message), "%s", ctx->error_message);
ip_context_free(ctx);
rb_raise(exception, "%s", message[0] ? message : "invalid pixel input");
}
validate_limits_for_pixels(ctx);
if (ctx->status != IP_OK) {
VALUE exception = ip_status_to_exception(ctx->status);
char message[512];
snprintf(message, sizeof(message), "%s", ctx->error_message);
ip_context_free(ctx);
rb_raise(exception, "%s", message);
}
ip_run_context(ctx);
VALUE result = ip_finish_output(ctx, out_kind);
ip_context_free(ctx);
return result;
}
|
.__inspect_image(input, input_kind) ⇒ Object
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 |
# File 'ext/image_pack/image_pack.c', line 637
static VALUE ip_inspect_image_entry(VALUE self, VALUE input, VALUE input_kind) {
(void)self;
ip_context_t *ctx = ip_context_new();
if (!ctx)
rb_raise(rb_eImagePackOutOfMemoryError, "failed to allocate native context");
if (!ip_prepare_input_bytes(ctx, input, ip_parse_input_kind(input_kind)) ||
!ip_inspect_jpeg_header(ctx)) {
VALUE exception = ip_status_to_exception(ctx->status);
char message[512];
snprintf(message, sizeof(message), "%s", ctx->error_message);
ip_context_free(ctx);
rb_raise(exception, "%s", message[0] ? message : "failed to inspect JPEG image");
}
VALUE hash = rb_hash_new();
rb_hash_aset(hash, ID2SYM(rb_intern("format")), ID2SYM(rb_intern("jpeg")));
rb_hash_aset(hash, ID2SYM(rb_intern("width")), INT2NUM(ctx->width));
rb_hash_aset(hash, ID2SYM(rb_intern("height")), INT2NUM(ctx->height));
rb_hash_aset(hash, ID2SYM(rb_intern("channels")), INT2NUM(ctx->channels));
rb_hash_aset(hash, ID2SYM(rb_intern("bit_depth")), INT2NUM(ctx->bit_depth));
rb_hash_aset(hash, ID2SYM(rb_intern("decoded_bytes")), SIZET2NUM(ctx->decoded_bytes));
ip_context_free(ctx);
return hash;
}
|
.compress(input, output: nil, algo: :jpeg_turbo, quality: nil, min_ssim: nil, mozjpeg_trellis: true, progressive: false, strip_metadata: true, execution: nil, cancellable: false) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/image_pack.rb', line 48 def compress(input, output: nil, algo: :jpeg_turbo, quality: nil, min_ssim: nil, mozjpeg_trellis: true, progressive: false, strip_metadata: true, execution: nil, cancellable: false) validate_algo!(algo) validate_min_ssim!(min_ssim) validate_mozjpeg_trellis!(mozjpeg_trellis) quality_was_given = !quality.nil? effective_quality = quality_was_given ? quality : DEFAULT_QUALITY effective_quality = 1 if min_ssim && !quality_was_given validate_quality!(effective_quality) execution ||= configuration.execution validate_execution!(execution) validate_cancellable!(algo, execution, cancellable) normalized_input_kind = input_kind!(input) normalized_output_kind = output_kind!(output) has_scheduler = fiber_scheduler_active? __compress_jpeg(input, normalized_input_kind, output, normalized_output_kind, algo, effective_quality.to_i, min_ssim ? min_ssim.to_f : 0.0, mozjpeg_trellis ? 1 : 0, progressive ? 1 : 0, ? 1 : 0, execution, cancellable ? 1 : 0, has_scheduler ? 1 : 0) end |
.compress_pixels(buffer, width:, height:, channels:, output: nil, algo: :jpeg_turbo, quality: DEFAULT_QUALITY, progressive: false, execution: nil, cancellable: false) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/image_pack.rb', line 85 def compress_pixels(buffer, width:, height:, channels:, output: nil, algo: :jpeg_turbo, quality: DEFAULT_QUALITY, progressive: false, execution: nil, cancellable: false) validate_algo!(algo) validate_quality!(quality) validate_dimensions!(width, height, channels) execution ||= configuration.execution validate_execution!(execution) validate_cancellable!(algo, execution, cancellable) normalized_output_kind = output_kind!(output) has_scheduler = fiber_scheduler_active? __compress_pixels(buffer, width.to_i, height.to_i, channels.to_i, output, normalized_output_kind, algo, quality.to_i, progressive ? 1 : 0, execution, cancellable ? 1 : 0, has_scheduler ? 1 : 0) end |
.configuration ⇒ Object
37 38 39 |
# File 'lib/image_pack.rb', line 37 def configuration @configuration ||= Configuration.new end |
.configure {|configuration| ... } ⇒ Object
41 42 43 44 45 46 |
# File 'lib/image_pack.rb', line 41 def configure return configuration unless block_given? yield(configuration) configuration end |
.inspect_image(input) ⇒ Object
115 116 117 |
# File 'lib/image_pack.rb', line 115 def inspect_image(input) __inspect_image(input, input_kind!(input)) end |