# Copyright (C) 2016-2024 Ruby-GNOME Project Team # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA class TestPixbuf < Test::Unit::TestCase include GdkPixbufTestUtils sub_test_case(".new") do sub_test_case("legacy form") do setup do |&block| suppress_warning do block.call end end test "basic" do colorspace = GdkPixbuf::Colorspace::RGB width = 100 height = 100 has_alpha = true bits_per_sample = 8 pixbuf = GdkPixbuf::Pixbuf.new(colorspace, has_alpha, bits_per_sample, width, height) assert_equal(colorspace, pixbuf.colorspace) assert_equal(width, pixbuf.width) assert_equal(height, pixbuf.height) assert_equal(has_alpha, pixbuf.has_alpha?) assert_equal(bits_per_sample, pixbuf.bits_per_sample) end test "file" do pixbuf = GdkPixbuf::Pixbuf.new(fixture_path("gnome-logo-icon.png")) assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) end test "file: size" do pixbuf = GdkPixbuf::Pixbuf.new(fixture_path("gnome-logo-icon.png"), 32, 48) assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) assert_equal(32, pixbuf.width) assert_equal(32, pixbuf.height) end test "file: scale" do pixbuf = GdkPixbuf::Pixbuf.new(fixture_path("gnome-logo-icon.png"), 32, 48, false) assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) assert_equal(32, pixbuf.width) assert_equal(48, pixbuf.height) end test "subpixbuf" do src_pixbuf = GdkPixbuf::Pixbuf.new(fixture_path("gnome-logo-icon.png")) pixbuf = GdkPixbuf::Pixbuf.new(src_pixbuf, 0, 0, 32, 32) assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) assert_equal(32, pixbuf.width) assert_equal(32, pixbuf.height) end test "data" do src_pixbuf = GdkPixbuf::Pixbuf.new(fixture_path("gnome-logo-icon.png")) data = src_pixbuf.pixels.pack("C*") pixbuf = GdkPixbuf::Pixbuf.new(data, src_pixbuf.colorspace, src_pixbuf.has_alpha?, src_pixbuf.bits_per_sample, src_pixbuf.width, src_pixbuf.height, src_pixbuf.row_stride, ) assert_equal(src_pixbuf.pixels, pixbuf.pixels) end end sub_test_case("Hash form") do test "basic" do colorspace = GdkPixbuf::Colorspace::RGB width = 100 height = 100 has_alpha = true bits_per_sample = 8 pixbuf = GdkPixbuf::Pixbuf.new(:colorspace => colorspace, :has_alpha => has_alpha, :width => width, :height => height, :bits_per_sample => bits_per_sample) assert_equal(colorspace, pixbuf.colorspace) assert_equal(width, pixbuf.width) assert_equal(height, pixbuf.height) assert_equal(has_alpha, pixbuf.has_alpha?) assert_equal(bits_per_sample, pixbuf.bits_per_sample) end test "file" do filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) end test "file: size" do filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => filename, :width => 32, :height => 48) assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) assert_equal(32, pixbuf.width) assert_equal(32, pixbuf.height) end test "file: scale" do filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => filename, :width => 32, :height => 48, :scale => true, :preserve_aspect_ratio => false) assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) assert_equal(32, pixbuf.width) assert_equal(48, pixbuf.height) end test "subpixbuf" do filename = fixture_path("gnome-logo-icon.png") src_pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) pixbuf = suppress_warning do GdkPixbuf::Pixbuf.new(:src_pixbuf => src_pixbuf, :src_x => 0, :src_y => 0, :width => 32, :height => 32) end assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) assert_equal(32, pixbuf.width) assert_equal(32, pixbuf.height) end test "data" do filename = fixture_path("gnome-logo-icon.png") src_pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) data = src_pixbuf.pixels.pack("C*") pixbuf = GdkPixbuf::Pixbuf.new(:data => data, :colorspace => src_pixbuf.colorspace, :has_alpha => src_pixbuf.has_alpha?, :bits_per_sample => src_pixbuf.bits_per_sample, :width => src_pixbuf.width, :height => src_pixbuf.height, :row_stride => src_pixbuf.row_stride, ) assert_equal(src_pixbuf.pixels, pixbuf.pixels) end test "bytes" do only_version(2, 32) filename = fixture_path("gnome-logo-icon.png") src_pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) bytes = src_pixbuf.pixels.flatten.pack("C*") pixbuf = GdkPixbuf::Pixbuf.new(:bytes => bytes, :colorspace => src_pixbuf.colorspace, :has_alpha => src_pixbuf.has_alpha?, :bits_per_sample => src_pixbuf.bits_per_sample, :width => src_pixbuf.width, :height => src_pixbuf.height, :row_stride => src_pixbuf.row_stride, ) assert_equal(src_pixbuf.pixels, pixbuf.pixels) end test "resource" do filename = fixture_path("gnome-logo-icon.png") src_pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) resource = Gio::Resource.load(fixture_path("image.gresource")) Gio::Resources.register(resource) begin resource_path = "/org/ruby/gnome/gnome-logo-icon.png" pixbuf = GdkPixbuf::Pixbuf.new(:resource => resource_path) assert_equal(src_pixbuf.pixels, pixbuf.pixels) ensure Gio::Resources.unregister(resource) end end test "resource: scale" do resource = Gio::Resource.load(fixture_path("image.gresource")) Gio::Resources.register(resource) begin resource_path = "/org/ruby/gnome/gnome-logo-icon.png" pixbuf = GdkPixbuf::Pixbuf.new(:resource => resource_path, :width => 32, :height => 48, :scale => true, :preserve_aspect_ratio => false) assert_equal([ GdkPixbuf::Colorspace::RGB, 32, 48, ], [ pixbuf.colorspace, pixbuf.width, pixbuf.height, ]) ensure Gio::Resources.unregister(resource) end end end def test_subpixbuf filename = fixture_path("gnome-logo-icon.png") src_pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) pixbuf = src_pixbuf.subpixbuf(0, 0, 32, 32) assert_equal(GdkPixbuf::Colorspace::RGB, pixbuf.colorspace) assert_equal(32, pixbuf.width) assert_equal(32, pixbuf.height) end end def test_dup filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) assert_equal(pixbuf.pixels, pixbuf.dup.pixels) end def test_fill! filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) pixbuf.fill!(0xffffffff) assert_equal([0xff] * (pixbuf.row_stride * pixbuf.height), pixbuf.pixels) end def test_rotate filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) inverted_pixbuf = pixbuf.rotate(:upsidedown) assert_not_equal(pixbuf.pixels, inverted_pixbuf.pixels) inverted_twice_pixbuf = inverted_pixbuf.rotate(:upsidedown) assert_equal(pixbuf.pixels, inverted_twice_pixbuf.pixels) end sub_test_case("saturate_and_pixelate") do # Based on the function gdk_pixbuf_saturate_and_pixelate # in gdk-pixbuf-util.c def saturate_and_pixelate_pixels(pixbuf, saturation, pixelate) alpha = pixbuf.has_alpha? width = pixbuf.width height = pixbuf.height pixels = pixbuf.pixels dest_pix = [] dark_factor = 0.7 height.times do |i| width.times do |k| j =((i ) * width + k) * 4 intens = intensity(pixels[j + 0], pixels[j + 1], pixels[j + 2]) if pixelate == true && ( (i + k) % 2 == 0) dest_pix << (intens / 2 + 127).floor dest_pix << (intens / 2 + 127).floor dest_pix << (intens / 2 + 127).floor elsif pixelate == true dest_pix << clamp_uchar(saturate(pixels[j + 0], saturation, intens) * dark_factor).floor dest_pix << clamp_uchar(saturate(pixels[j + 1], saturation, intens) * dark_factor).floor dest_pix << clamp_uchar(saturate(pixels[j + 2], saturation, intens) * dark_factor).floor else dest_pix << clamp_uchar(saturate(pixels[j + 0], saturation, intens)).floor dest_pix << clamp_uchar(saturate(pixels[j + 1], saturation, intens)).floor dest_pix << clamp_uchar(saturate(pixels[j + 2], saturation, intens)).floor end dest_pix << pixels[j + 3] if alpha end end dest_pix end def saturate(value, saturation, intensity) (1.0 - saturation) * intensity + saturation * (1.0 * value) end def clamp_uchar(x) [0, x, 255].sort[1] end def intensity(r, g, b) (r * 0.30 + g * 0.59 + b * 0.11).floor end test "no modifications" do filename = fixture_path("gnome-logo-icon.png") src_pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) pixbuf = src_pixbuf.saturate_and_pixelate(1, false) assert_equal(src_pixbuf.pixels, pixbuf.pixels) end test "normal usage" do if /\Ai\d86-/ === RUBY_PLATFORM omit("floating point calculation result is different on i386") end filename = fixture_path("gnome-logo-icon.png") src_pixbuf = GdkPixbuf::Pixbuf.new(:file => filename) pixbuf = src_pixbuf.saturate_and_pixelate(0, true) ref = saturate_and_pixelate_pixels(src_pixbuf, 0, true) assert_equal(ref, pixbuf.pixels, ref.size) pixbuf = src_pixbuf.saturate_and_pixelate(0.5, true) ref = saturate_and_pixelate_pixels(src_pixbuf, 0.5, true) assert_equal(ref, pixbuf.pixels) end end sub_test_case("#save") do test("no options") do png_filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => png_filename) jpeg = pixbuf.save("jpeg") assert_equal(["image/jpeg", false], Gio::ContentType.guess(nil, jpeg)) end test("filename") do png_filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => png_filename) output = Tempfile.new(["pixbuf", ".jpg"]) pixbuf.save(output) assert_equal(["image/jpeg", false], Gio::ContentType.guess(nil, output.read)) end test(":filename") do png_filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => png_filename) output = Tempfile.new(["pixbuf", ".jpeg"]) pixbuf.save(output.path, "jpeg") assert_equal(["image/jpeg", false], Gio::ContentType.guess(nil, output.read)) end end test("#save_to_buffer") do png_filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => png_filename) jpeg = suppress_warning do pixbuf.save_to_buffer("jpeg") end assert_equal(["image/jpeg", false], Gio::ContentType.guess(nil, jpeg)) end test("#read_pixel_bytes") do only_version(2, 32) png_filename = fixture_path("gnome-logo-icon.png") pixbuf = GdkPixbuf::Pixbuf.new(:file => png_filename) assert_equal(pixbuf.pixels.pack("C*"), pixbuf.read_pixel_bytes.to_s) end end