image_science-1.3.0/0000755000004100000410000000000013314511215014312 5ustar www-datawww-dataimage_science-1.3.0/bench.rb0000555000004100000410000000247213314511215015724 0ustar www-datawww-data#!/usr/local/bin/ruby -w require 'benchmark' require 'rubygems' require 'image_science' max = (ARGV.shift || 100).to_i ext = ARGV.shift || "png" file = "blah_big.#{ext}" if RUBY_PLATFORM =~ /darwin/ then # how fucking cool is this??? puts "taking screenshot for thumbnailing benchmarks" system "screencapture -SC #{file}" else abort "You need to plonk down #{file} or buy a mac" end unless test ?f, "#{file}" ImageScience.with_image(file.sub(/#{ext}$/, 'png')) do |img| img.save(file) end if ext != "png" puts "# of iterations = #{max}" Benchmark::bm(20) do |x| x.report("null_time") { for i in 0..max do # do nothing end } x.report("cropped") { for i in 0..max do ImageScience.with_image(file) do |img| img.cropped_thumbnail(100) do |thumb| thumb.save("blah_cropped.#{ext}") end end end } x.report("proportional") { for i in 0..max do ImageScience.with_image(file) do |img| img.thumbnail(100) do |thumb| thumb.save("blah_thumb.#{ext}") end end end } x.report("resize") { for i in 0..max do ImageScience.with_image(file) do |img| img.resize(200, 200) do |resize| resize.save("blah_resize.#{ext}") end end end } end # File.unlink(*Dir["blah*#{ext}"]) image_science-1.3.0/test/0000755000004100000410000000000013314511215015271 5ustar www-datawww-dataimage_science-1.3.0/test/portrait.jpg0000444000004100000410000001516413314511215017644 0ustar www-datawww-dataJFIFHHExifMM*  (16.02iAppleiPhone 4SHH2012:10:15 09:56:18삝"'0221 $, 4  <D0100  L# 2012:10:15 09:56:182012:10:15 09:56:18  kv-bd&CC&2" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?h^G p.~;CSX U奚g8!_ia(KA#ӦL)>ӓ`{=W~+]嫴IiZ8}$_,ZA$>DM7Gj &(+gAQg_ `BBjTW`q:Uq1:uiќ MKug8Q 6*#)'Q5 q-uQm5x㏍\\ZAc$&PdP\ !]fWTbD1k;nICybFS1IR) E˘xf:TLsy<7 -HDZXZɞ8ȍ{&Ǭj Kմ:mBEMLyng/vK)&X&[ I?O[|G{f'1|K6*ik;aP IƝ(SW⸞3=<ʵӥm^1T%ICM&m?/ߴ~1r-({qFW1fK9H䀲r+ =’lXd1Z_|B:摩$rd1ƚƉ+qkjbʑUf{$-Ttm+Ya%YVw{mC>\0 3kXf)xrȱ8oq~*̿Nab(S"x?o(BUpؚj}*r9Ǝ.0Nx)үj5RwiS+5pO !qv4Ry~֊1;u-?g!qxa}2y5XK6Gy&[u)nf$ƒ$w˴6?ےDX*1;<tW|\sjS/|/lՕuۿ\I1iR4^f)%r4'!ŤC/8%pLT<._cF2U %\FUԵ,lb*PN' 58OIGݔ\\g&+6%e'{x:;[m4kq&mᅰXnmuK W+s.VIeY>|>iw:?UoXxGCKyX@yʂ:tosGUt4$B[EZDqZHFEWX ñVՙ%cD$UH8TDUEUzr/~6KC/g:rm~'h@?N1E쿫y._/^^~dpsӏQn>T\ޤc:QES]jpz{6im{~rG%^+_XA%S*p y^xW_ L.X"% D*$P@H `q &+?wgCֶ^*HvgzSUSU=MD"+z zz,"惏<P=GX>k` 8` 8zz0 bx auS"@@Ŷ/ fSMn(k֫[?./G|iOs B`'[jhJ1 >XiοJ\ s"vw[}erf_|7?۸s_<ؓG[?Iޮ0@l֚ۛ֒;mލp" 43 B:*̖\A%.̕HERef{@Ȝ#[`he‚sj5uN@Wkt&ظZ|nlp)9t[@z2B"֫>~҂9p~f jr9f3Zx-"&mSIzpCM> UO 1 require 'rubygems' require 'image_science' max_length = ARGV.shift.to_i msg = $s ? :cropped_thumbnail : :thumbnail ARGV.each do |file| begin result = ImageScience.with_image file do |img| begin img.send(msg, max_length) do |thumb| # add _thumb and switch from gif to png. Really. gif just sucks. out = file.sub(/(\.[^\.]+)$/, '_thumb\1').sub(/gif$/, 'png') thumb.save(out) end rescue => e warn "Exception thumbnailing #{file}: #{e}" end end p file => result rescue => e warn "Exception opening #{file}: #{e}" end end image_science-1.3.0/data.tar.gz.sig0000444000004100000410000000040013314511215017123 0ustar www-datawww-dataX5]o9xvUif.?>Gt+ǒ9/D̹V4}O47$u<8:>bh䯗)ݢI,iQdf&P$TUq ߈Q\OJ+9Rwď:HdRe+ !m ԴY>u}A-m7;dCQr +#3iݓDu-5v%) g!̐4tRQimage_science-1.3.0/metadata.gz.sig0000444000004100000410000000040013314511215017205 0ustar www-datawww-data".}`1Q%T(J@XgP2T*l<jptgT񺯸dm0!B_/@Bֵ"a_o8&T.N34u& e`~"3_Zm'wR2T?v2pЏn$>nDf6˝m`?Y!<]~k9vv~g= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Ryan Davis".freeze] s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIDPjCCAiagAwIBAgIBAzANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu\nZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB\nGRYDY29tMB4XDTE1MDkxOTIwNTEyMloXDTE2MDkxODIwNTEyMlowRTETMBEGA1UE\nAwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS\nJomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda\nb9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx\ntaCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT\noOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh\nGiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt\nqhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV\ngBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB\nAQB+Hx8xUgrpZa4P8H8gR8zme5kISwQrG80MbpqJV6/G3/ZicRFhN5sjwu0uHGue\nbd9Cymf6oIRwHVarJux2M32T6bL07Hmi07w2QaPc3MnMKB/D46SRZ2JSSGPFRBTc\nSilobMRoGs/7B15uGFUEnNrCB/ltMqhwwSx1r++UQPfeySHEV9uqu03E5Vb7J37O\n2Er6PLXHRiYsIycD1LkMi6YnixdITRHmrqJYE2rsjaIfpIehiusVAPHkNf7qbpHq\nqx3h45R1CAsObX0SQDIT+rRbQrtKz1GHIZTOFYvEJjUY1XmRTZupD3CJ8Q7sDqSy\nNLq5jm1fq6Y9Uolu3RJbmycf\n-----END CERTIFICATE-----\n".freeze] s.date = "2016-05-16" s.description = "ImageScience is a clean and happy Ruby library that generates\nthumbnails -- and kicks the living crap out of RMagick. Oh, and it\ndoesn't leak memory like a sieve. :)\n\nFor more information including build steps, see http://seattlerb.rubyforge.org/".freeze s.email = ["ryand-ruby@zenspider.com".freeze] s.executables = ["image_science_thumb".freeze] s.extra_rdoc_files = ["History.txt".freeze, "Manifest.txt".freeze, "README.txt".freeze] s.files = ["History.txt".freeze, "Manifest.txt".freeze, "README.txt".freeze, "Rakefile".freeze, "bench.rb".freeze, "bin/image_science_thumb".freeze, "lib/image_science.rb".freeze, "test/pix.png".freeze, "test/portrait.jpg".freeze, "test/test_image_science.rb".freeze] s.homepage = "http://seattlerb.rubyforge.org/ImageScience.html".freeze s.licenses = ["MIT".freeze] s.rdoc_options = ["--main".freeze, "README.txt".freeze] s.rubygems_version = "2.5.2.1".freeze s.summary = "ImageScience is a clean and happy Ruby library that generates thumbnails -- and kicks the living crap out of RMagick".freeze if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q.freeze, ["~> 3.9"]) s.add_development_dependency(%q.freeze, ["~> 3.15"]) s.add_development_dependency(%q.freeze, ["~> 4.0"]) else s.add_dependency(%q.freeze, ["~> 3.9"]) s.add_dependency(%q.freeze, ["~> 3.15"]) s.add_dependency(%q.freeze, ["~> 4.0"]) end else s.add_dependency(%q.freeze, ["~> 3.9"]) s.add_dependency(%q.freeze, ["~> 3.15"]) s.add_dependency(%q.freeze, ["~> 4.0"]) end end image_science-1.3.0/History.txt0000444000004100000410000000551013314511215016513 0ustar www-datawww-data=== 1.3.0 / 2016-05-16 * 1 minor enhancement: * Add rotate method. (bhenderson) * 1 bug fix: * Fixed error-raising behaviour. (omp) === 1.2.6 / 2014-01-15 * 1 bug fix: * Defer raising exception until wrapped by rb_ensure. (nocode) === 1.2.5 / 2013-06-20 * 1 bug fix: * Fixed memory leak in the ReOrient function. (Blargel/abnerqian) === 1.2.4 / 2012-11-23 * 1 minor enhancement: * Extract out orientation logic and add it to with_image_from_memory. (bhenderson) === 1.2.3 / 2012-05-07 * 2 bug fixes: * Fixed thumbnail float imprecision errors. (jdelStrother) * Switched to using tmpdir for INLINEDIR to avoid failures in CI environments w/o homedirs === 1.2.2 / 2012-03-13 * 1 minor enhancement: * Extended build to look for homebrew setup (hcatlin) * 2 bug fixes: * Fixed 1.9 warnings, clang warnings, etc... * Fixed compilation error when ruby's config mandates C89 style decls. (nocode) === 1.2.1 / 2009-08-14 * 2 minor enhancements: * Added luis' patches to make it build properly on windows. * with_image now raises on missing/bad files. === 1.2.0 / 2009-06-23 * 7 minor enhancements: * Moved quick_thumb to bin/image_science_thumb and properly added. * Added -s (square) flag to bin/image_science_thumb * Added autorotating on image load. (choonkeat) * Added ruby_inline to clean globs * Added with_image_from_memory. (sumbach) * Switched to minitest. * Updated rakefile for now hoe capabilities. * 3 bug fixes: * Check and convert to 24 BPP if save type is jpg. Caused by 32bpp png to jpg. * Fixed 1.9isms * Fixed BMP support. Tweaked whitespace. === 1.1.3 / 2007-05-30 * 2 minor enhancements: * Added quick_thumb as an example to look at. * Error handler doesn't raise by default. Raises if $DEBUG==true. === 1.1.2 / 2007-04-18 * 2 bug fixes: * reports bad height/width values for resize * explicitly removes ICC color profiles from PNGs (bug in freeimage). === 1.1.1 / 2007-03-08 * 5 minor enhancements: * Added error handler that raises with information about what went wrong. * thumbnail is now pure ruby, everything now uses resize. * Produces cleaner JPEG files, with a small cost to file size/speed. * resize now uses Catmull-Rom spline filter for better quality. * resize copies existing ICC Profile to thumbnail, producing better color. * ICC Profile NOT copied for PNG as it seems to be buggy. * 1 bug fix: * Fixed rdoc === 1.1.0 / 2007-01-05 * 3 major enhancements: * Added resize(width, height) * Added save(path) * All thumbnail and resize methods yield instead of saving directly. * 1 minor enhancement: * Will now try to use FreeImage from ports if /opt/local exists. * 2 bug fixes: * Fixed the linker issue on PPC. * Rakefile will now clean the image files created by bench.rb === 1.0.0 / 2006-12-01 * 1 major enhancement * Birthday! image_science-1.3.0/README.txt0000444000004100000410000000417213314511215016012 0ustar www-datawww-data= ImageScience * http://seattlerb.rubyforge.org/ImageScience.html * http://rubyforge.org/projects/seattlerb == DESCRIPTION: ImageScience is a clean and happy Ruby library that generates thumbnails -- and kicks the living crap out of RMagick. Oh, and it doesn't leak memory like a sieve. :) For more information including build steps, see http://seattlerb.rubyforge.org/ == FEATURES/PROBLEMS: * Glorious graphics manipulation magi... errr, SCIENCE! in less than 300 LoC! * Supports square and proportional thumbnails, as well as arbitrary resizes. * Pretty much any graphics format you could want. No really. == SYNOPSIS: ImageScience.with_image file do |img| img.cropped_thumbnail 100 do |thumb| thumb.save "#{file}_cropped.png" end img.thumbnail 100 do |thumb| thumb.save "#{file}_thumb.png" end end == REQUIREMENTS: * FreeImage * ImageScience == INSTALL: * Download and install FreeImage. See notes at url above. * sudo gem install -y image_science * see http://seattlerb.rubyforge.org/ImageScience.html for more info. == LICENSE: (The MIT License) Copyright (c) 2006-2009 Ryan Davis, Seattle.rb Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. image_science-1.3.0/Rakefile0000444000004100000410000000074213314511215015760 0ustar www-datawww-data# -*- ruby -*- require 'rubygems' require 'hoe' Hoe.add_include_dirs("../../RubyInline/dev/lib", "../../ZenTest/dev/lib") Hoe.plugin :seattlerb Hoe.plugin :inline Hoe.plugin :isolate Hoe.spec 'image_science' do developer 'Ryan Davis', 'ryand-ruby@zenspider.com' license "MIT" clean_globs << 'blah*png' << 'images/*_thumb.*' end task :debug => :isolate do file = ENV["F"] ruby "-Ilib bin/image_science_thumb 100 #{file}" end # vim: syntax=Ruby image_science-1.3.0/lib/0000755000004100000410000000000013314511215015060 5ustar www-datawww-dataimage_science-1.3.0/lib/image_science.rb0000555000004100000410000002525213314511215020167 0ustar www-datawww-data#!/usr/local/bin/ruby -w require 'rubygems' require 'inline' ## # Provides a clean and simple API to generate thumbnails using # FreeImage as the underlying mechanism. # # For more information or if you have build issues with FreeImage, see # http://seattlerb.rubyforge.org/ImageScience.html class ImageScience VERSION = '1.3.0' ## # The top-level image loader opens +path+ and then yields the image. # # :singleton-method: with_image ## # The top-level image loader, opens an image from the string +data+ # and then yields the image. # # :singleton-method: with_image_from_memory ## # Crops an image to +left+, +top+, +right+, and +bottom+ and then # yields the new image. # # :method: with_crop ## # Returns the width of the image, in pixels. # # :method: width ## # Returns the height of the image, in pixels. # # :method: height ## # Saves the image out to +path+. Changing the file extension will # convert the file type to the appropriate format. # # :method: save ## # Resizes the image to +width+ and +height+ using a cubic-bspline # filter and yields the new image. # # :method: resize ## # Rotate the image to +angle+. Limited to 45 degree skewing only. # # :method: rotate ## # Creates a proportional thumbnail of the image scaled so its longest # edge is resized to +size+ and yields the new image. def thumbnail(size) # :yields: image w, h = width, height scale = size.to_f / (w > h ? w : h) self.resize((w * scale).round, (h * scale).round) do |image| yield image end end ## # Creates a square thumbnail of the image cropping the longest edge # to match the shortest edge, resizes to +size+, and yields the new # image. def cropped_thumbnail(size) # :yields: image w, h = width, height l, t, r, b, half = 0, 0, w, h, (w - h).abs / 2 l, r = half, half + h if w > h t, b = half, half + w if h > w with_crop(l, t, r, b) do |img| img.thumbnail(size) do |thumb| yield thumb end end end inline do |builder| %w[/opt/local /usr/local].each do |dir| if File.directory? "#{dir}/include" then builder.add_compile_flags "-I#{dir}/include" builder.add_link_flags "-L#{dir}/lib" end end builder.add_link_flags "-lfreeimage" unless RUBY_PLATFORM =~ /mswin/ builder.add_link_flags "-lfreeimage" # TODO: detect PPC builder.add_link_flags "-lstdc++" # only needed on PPC for some reason else builder.add_link_flags "freeimage.lib" end builder.include '"FreeImage.h"' builder.prefix <<-"END" #define GET_BITMAP(name) Data_Get_Struct(self, FIBITMAP, (name)); if (!(name)) rb_raise(rb_eTypeError, "Bitmap has already been freed"); static ID err_key; /* used as thread-local key */ static void clear_error(void); static void raise_error(void); END builder.prefix <<-"END" VALUE unload(VALUE self) { FIBITMAP *bitmap; GET_BITMAP(bitmap); FreeImage_Unload(bitmap); DATA_PTR(self) = NULL; clear_error(); return Qnil; } END builder.prefix <<-"END" VALUE wrap_and_yield(FIBITMAP *image, VALUE self, FREE_IMAGE_FORMAT fif) { unsigned int self_is_class = rb_type(self) == T_CLASS; VALUE klass = self_is_class ? self : CLASS_OF(self); VALUE type = self_is_class ? INT2FIX(fif) : rb_iv_get(self, "@file_type"); VALUE obj = Data_Wrap_Struct(klass, NULL, NULL, image); rb_iv_set(obj, "@file_type", type); return rb_ensure(rb_yield, obj, unload, obj); } END builder.prefix <<-"END" void copy_icc_profile(VALUE self, FIBITMAP *from, FIBITMAP *to) { FREE_IMAGE_FORMAT fif = FIX2INT(rb_iv_get(self, "@file_type")); if (fif != FIF_PNG && FreeImage_FIFSupportsICCProfiles(fif)) { FIICCPROFILE *profile = FreeImage_GetICCProfile(from); if (profile && profile->data) { FreeImage_CreateICCProfile(to, profile->data, profile->size); } } } END # we defer raising the error until it we find a safe point to do so # We cannot use rb_ensure in these cases because FreeImage may internally # make allocations via which our code will never see. builder.prefix <<-"END" void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) { VALUE err = rb_sprintf( "FreeImage exception for type %s: %s", (fif == FIF_UNKNOWN) ? "???" : FreeImage_GetFormatFromFIF(fif), message); rb_thread_local_aset(rb_thread_current(), err_key, err); } END # do not call this until necessary variables are wrapped up for GC # otherwise there will be leaks builder.prefix <<-"END" static void raise_error(void) { VALUE err = rb_thread_local_aref(rb_thread_current(), err_key); if (NIL_P(err)) { rb_raise(rb_eRuntimeError, "FreeImage exception"); } else { rb_thread_local_aset(rb_thread_current(), err_key, Qnil); rb_raise(rb_eRuntimeError, "%s", StringValueCStr(err)); } } END builder.prefix <<-"END" static void clear_error(void) { if (!NIL_P(rb_thread_local_aref(rb_thread_current(), err_key))) { rb_thread_local_aset(rb_thread_current(), err_key, Qnil); } } END builder.prefix <<-"END" FIBITMAP* ReOrient(FIBITMAP *bitmap) { FITAG *tagValue = NULL; FIBITMAP *oldBitmap = bitmap; FreeImage_GetMetadata(FIMD_EXIF_MAIN, bitmap, "Orientation", &tagValue); switch (tagValue == NULL ? 0 : *((short *) FreeImage_GetTagValue(tagValue))) { case 6: bitmap = FreeImage_RotateClassic(bitmap, 270); break; case 3: bitmap = FreeImage_RotateClassic(bitmap, 180); break; case 8: bitmap = FreeImage_RotateClassic(bitmap, 90); break; default: bitmap = FreeImage_Clone(bitmap); break; } FreeImage_Unload(oldBitmap); return bitmap; } END builder.add_to_init "FreeImage_SetOutputMessage(FreeImageErrorHandler);" builder.add_to_init 'err_key = rb_intern("__FREE_IMAGE_ERROR");' builder.c_singleton <<-"END" VALUE with_image(char * input) { FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; int flags; fif = FreeImage_GetFileType(input, 0); if (fif == FIF_UNKNOWN) fif = FreeImage_GetFIFFromFilename(input); if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) { FIBITMAP *bitmap; VALUE result = Qnil; flags = fif == FIF_JPEG ? JPEG_ACCURATE : 0; if (!(bitmap = FreeImage_Load(fif, input, flags))) raise_error(); if (!(bitmap = ReOrient(bitmap))) raise_error(); result = wrap_and_yield(bitmap, self, fif); return result; } rb_raise(rb_eTypeError, "Unknown file format"); return Qnil; } END builder.c_singleton <<-"END" VALUE with_image_from_memory(VALUE image_data) { FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; BYTE *image_data_ptr; DWORD image_data_length; FIMEMORY *stream; FIBITMAP *bitmap = NULL; VALUE result = Qnil; int flags; Check_Type(image_data, T_STRING); image_data_ptr = (BYTE*)RSTRING_PTR(image_data); image_data_length = (DWORD)RSTRING_LEN(image_data); stream = FreeImage_OpenMemory(image_data_ptr, image_data_length); if (NULL == stream) { rb_raise(rb_eTypeError, "Unable to open image_data"); } fif = FreeImage_GetFileTypeFromMemory(stream, 0); if ((fif == FIF_UNKNOWN) || !FreeImage_FIFSupportsReading(fif)) { FreeImage_CloseMemory(stream); rb_raise(rb_eTypeError, "Unknown file format"); } flags = fif == FIF_JPEG ? JPEG_ACCURATE : 0; bitmap = FreeImage_LoadFromMemory(fif, stream, flags); FreeImage_CloseMemory(stream); if (!bitmap) raise_error(); if (!(bitmap = ReOrient(bitmap))) raise_error(); result = wrap_and_yield(bitmap, self, fif); return result; } END builder.c <<-"END" VALUE with_crop(int l, int t, int r, int b) { FIBITMAP *copy, *bitmap; GET_BITMAP(bitmap); if (!(copy = FreeImage_Copy(bitmap, l, t, r, b))) raise_error(); copy_icc_profile(self, bitmap, copy); return wrap_and_yield(copy, self, 0); } END builder.c <<-"END" int height() { FIBITMAP *bitmap; GET_BITMAP(bitmap); return FreeImage_GetHeight(bitmap); } END builder.c <<-"END" int width() { FIBITMAP *bitmap; GET_BITMAP(bitmap); return FreeImage_GetWidth(bitmap); } END builder.c <<-"END" VALUE resize(int w, int h) { FIBITMAP *bitmap, *image; if (w <= 0) rb_raise(rb_eArgError, "Width <= 0"); if (h <= 0) rb_raise(rb_eArgError, "Height <= 0"); GET_BITMAP(bitmap); image = FreeImage_Rescale(bitmap, w, h, FILTER_CATMULLROM); if (!image) raise_error(); copy_icc_profile(self, bitmap, image); return wrap_and_yield(image, self, 0); } END builder.c <<-"END" VALUE rotate(int angle) { FIBITMAP *bitmap, *image; if ((angle % 45) != 0) rb_raise(rb_eArgError, "Angle must be 45 degree skew"); GET_BITMAP(bitmap); image = FreeImage_RotateClassic(bitmap, angle); if (image) { copy_icc_profile(self, bitmap, image); return wrap_and_yield(image, self, 0); } return Qnil; } END builder.c <<-"END" VALUE save(char * output) { int flags; FIBITMAP *bitmap; FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(output); if (fif == FIF_UNKNOWN) fif = FIX2INT(rb_iv_get(self, "@file_type")); if ((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsWriting(fif)) { BOOL result = 0, unload = 0; GET_BITMAP(bitmap); flags = fif == FIF_JPEG ? JPEG_QUALITYSUPERB : 0; if (fif == FIF_PNG) FreeImage_DestroyICCProfile(bitmap); if (fif == FIF_JPEG && FreeImage_GetBPP(bitmap) != 24) { bitmap = FreeImage_ConvertTo24Bits(bitmap), unload = 1; // sue me if (!bitmap) raise_error(); } result = FreeImage_Save(fif, bitmap, output, flags); if (unload) FreeImage_Unload(bitmap); if (!result) raise_error(); return Qtrue; } rb_raise(rb_eTypeError, "Unknown file format"); return Qnil; } END end end image_science-1.3.0/Manifest.txt0000444000004100000410000000023513314511215016617 0ustar www-datawww-dataHistory.txt Manifest.txt README.txt Rakefile bench.rb bin/image_science_thumb lib/image_science.rb test/pix.png test/portrait.jpg test/test_image_science.rb