Permalink
Browse files

Initial commit.

  • Loading branch information...
1 parent be9e77f commit d3cfdb40162a6b5535c1b143fb7854dc87645621 Charlie Savage committed Aug 29, 2011
Showing with 4,388 additions and 0 deletions.
  1. +12 −0 .gitignore
  2. +671 −0 HISTORY
  3. +21 −0 LICENSE
  4. +99 −0 README.rdoc
  5. +34 −0 Rakefile
  6. +225 −0 cookbook.rdoc
  7. +32 −0 free-image.gemspec
  8. +2 −0 lib/1.8/.gitignore
  9. +2 −0 lib/1.9/.gitignore
  10. +70 −0 lib/free-image.rb
  11. +142 −0 lib/free-image/bitmap.rb
  12. +24 −0 lib/free-image/enums/color_types.rb
  13. +24 −0 lib/free-image/enums/dithers.rb
  14. +12 −0 lib/free-image/enums/filters.rb
  15. +84 −0 lib/free-image/enums/formats.rb
  16. +36 −0 lib/free-image/enums/image_types.rb
  17. +44 −0 lib/free-image/errors.rb
  18. +166 −0 lib/free-image/modules/conversions.rb
  19. +42 −0 lib/free-image/modules/helper.rb
  20. +41 −0 lib/free-image/modules/icc.rb
  21. +305 −0 lib/free-image/modules/information.rb
  22. +261 −0 lib/free-image/modules/modify.rb
  23. +135 −0 lib/free-image/modules/pixels.rb
  24. +83 −0 lib/free-image/modules/transforms.rb
  25. +44 −0 lib/free-image/palette.rb
  26. +151 −0 lib/free-image/scanline.rb
  27. +172 −0 lib/free-image/sources/abstract_source.rb
  28. +112 −0 lib/free-image/sources/file.rb
  29. +154 −0 lib/free-image/sources/io.rb
  30. +189 −0 lib/free-image/sources/memory.rb
  31. +14 −0 lib/free-image/types/boolean.rb
  32. +9 −0 lib/free-image/types/complex.rb
  33. +14 −0 lib/free-image/types/ffi.rb
  34. +11 −0 lib/free-image/types/rgb16.rb
  35. +82 −0 lib/free-image/types/rgb_quad.rb
  36. +42 −0 lib/free-image/types/rgb_triple.rb
  37. +12 −0 lib/free-image/types/rgba16.rb
  38. +12 −0 lib/free-image/types/rgbaf.rb
  39. +11 −0 lib/free-image/types/rgbf.rb
  40. +46 −0 test/cookbook.rb
  41. BIN test/images/gradient.png
  42. BIN test/images/lena.png
  43. BIN test/images/lena.tiff
  44. BIN test/images/lena_flipped.png
  45. BIN test/images/lena_rescale_bicubic.png
  46. BIN test/images/lena_rescale_bilinear.png
  47. BIN test/images/lena_rescale_box.png
  48. BIN test/images/lena_rescale_bspline.png
  49. BIN test/images/lena_rescale_catmullrom.png
  50. BIN test/images/lena_rescale_lanczos3.png
  51. BIN test/images/lena_rotate_45.png
  52. BIN test/images/lena_rotate_ex_45_masked.png
  53. BIN test/images/lena_rotate_ex_45_mirrored.png
  54. BIN test/images/lena_rotate_ex_45_top_left.png
  55. BIN test/images/lena_thumbnail.png
  56. BIN test/images/lena_thumbnail_border_enlarge.png
  57. BIN test/images/lena_thumbnail_border_paste.png
  58. BIN test/images/lena_thumbnail_border_scanline.png
  59. 0 test/images/not_an_image.txt
  60. BIN test/images/sample.png
  61. BIN test/images/sample_composite_color.png
  62. +16 −0 test/test_bitmap.rb
  63. +86 −0 test/test_conversions.rb
  64. +52 −0 test/test_file.rb
  65. +15 −0 test/test_free_image.rb
  66. +35 −0 test/test_helper.rb
  67. +118 −0 test/test_information.rb
  68. +53 −0 test/test_io.rb
  69. +65 −0 test/test_memory.rb
  70. +59 −0 test/test_modify.rb
  71. +45 −0 test/test_palette.rb
  72. +62 −0 test/test_pixels.rb
  73. +26 −0 test/test_rgb_quad.rb
  74. +65 −0 test/test_scanline.rb
  75. +19 −0 test/test_suite.rb
  76. +30 −0 test/test_transforms.rb
View
12 .gitignore
@@ -0,0 +1,12 @@
+pkg
+nbproject
+web/_site
+*.swp
+*.swo
+
+/ext/vc/libxml_ruby.sdf
+/ext/vc/libxml_ruby_19/Debug
+/ext/vc/libxml_ruby_18/Debug
+/doc
+/tmp
+/.idea
View
671 HISTORY
@@ -0,0 +1,671 @@
+= Release History
+
+== 2.2.1 / 2011-08-13 Charlie Savage
+
+* Packaging fix - include the custom .def file in the gem.
+
+== 2.2.0 / 2011-08-09 Charlie Savage
+
+* Update encoding support for Ruby 1.9 so that libxml-ruby returns
+ strings encoded in UTF-8. This change was required since libxml internally
+ stores strings in UTF-8. The exceptions to this rule are the #to_s methods
+ which return UTF-8 by default but can return other encodings if requested.
+
+== 2.1.2 / 2011-08-03 Charlie Savage
+
+* Fix segmentation fault that could occur when an XPathContext was marked
+ before it was fully initialized (Charlie Savage).
+
+* Add mark method to document to mark all nodes currently being accessed
+ by ruby. This make Ruby Enterprise Edition happy (Charlie Savage).
+
+== 2.1.1 / 2011-07-31 Charlie Savage
+
+* Switch to using def files to control library exports (Charlie Savage).
+
+== 2.1.0 / 2011-07-31 Charlie Savage
+
+* Ruby 1.9.3 compatability (Charlie Savage).
+
+* Added XPath expression <-> Ruby value conversion methods (Jens Wille).
+
+* Extracted rxml_xpath_to_value from rxml_xpath_context_find (Jens Wille).
+
+* Adapted rxml_xpath_from_value from Gregoire Lejeune's ruby-xslt
+ library, see https://github.com/glejeune/ruby-xslt (Jens Wille).
+
+* Allow calling #find on nodes returned from Reader (Charlie Savage).
+
+* Change document handling in XPath::Context to address segmentation fault on
+ Ruby Enterprise Edition (Charlie Savage).
+
+* Update gemspec file to work directly with bundler thereby allowing git
+ repository to be used as gem (Charlie Savage).
+
+* Support gem buld (Charlie Savage).
+
+* Simplify memory management of attributes namespaces to fix
+ segmentation faults that occurred when using Ruby 1.9.3 (Charlie Savage).
+
+
+== 2.0.8 / 2011-06-23 Charlie Savage
+
+* Add in 2 new HTML Parser constants - NODEFDTD and NOIMPLIED.
+
+* Fix compile issue on Ruby 1.9.3
+
+== 2.0.6 / 2011-05-23 Charlie Savage
+
+* Fix segfault that sometimes occurred when looking up encodings on 1.9.
+ In some cases the Ruby encoding infrastructure was not properly
+ initialized (nkriege).
+
+== 2.0.5 / 2011-05-05 Charlie Savage
+
+* Document#validate_dtd would sometimes cause segmentation faults due to
+ an improperly initialized data structure (Charlie Savage)
+
+== 2.0.4 / 2011-05-02 Charlie Savage
+
+* Fix compile issues on platforms using older versions of libxml2.
+ The problem as using a C14N constants that was added to libxml2
+ in July 2009 (Charlie Savage).
+
+== 2.0.3 / 2011-05-01 Charlie Savage
+
+* The biggest change in this release is supporting the use of libxml-ruby in
+ native background Ruby threads. Previously, the use of libxml-ruby in
+ background threads in Ruby 1.9.x and higher would often cause
+ segmentation faults. This has now been fixed (Charlie Savage).
+
+* Update Reader#expand so that returned node correctly remembers its
+ encoding in Ruby 1.9.x (zerebubuth).
+
+* Add check to verify a node has not been deleted. This can happen when
+ a ruby variable holds a reference to a child node that gets freed
+ when its parent gets freed. Previously when this happened a
+ segmentation fault would occur, now an exception is raised (Charlie Savage, fixes
+ RubyForge #26839.
+
+* Do not unlink nodes before internal validations have run - avoids
+ segmentation faults caused by freeing a node twice (Charlie Savage).
+
+* Add support for Document#canonicalization (Victor Lin).
+
+* Fix memory leak in Reader#lookup_namespace (Charlie Savage).
+
+* Fix memory leak in Reader#[] (Nathan Kriege).
+
+* Fix usage of @io instance variable (Jeffrey Taylor)
+
+* Removed old sax error handling code that has been fixed in newer
+ versions of libxml (Charlie Savage).
+
+* Code cleanup - remove unused variables and commented out code (Charlie Savage)
+
+* Minor text changes and documentation fixes (Charlie Savage).
+
+* Fix documentation error (fixes RubyForge #26888).
+
+* Update documentation for Document#validation* methods (fixes RubyForge #24833).
+
+* Update documentation and test (fixes Ruby Forge Issue #28770).
+
+* Updated documentation in README (Anurag Priyam):
+1. rake doc does not work; use rake rdoc.
+2. gem mislav-hanna does not exist; use hanna.
+3. rake rdoc 'depends' on hanna; no need of RDOCOPTS
+4. Point to the github issue tracker instead of Ruby Forge
+5. Point to the github (gh-pages) site for docs
+
+* Add tc_error to test suite (Charlie Savage).
+
+* Add sax test (Stanislav O.Pogrebnyak).
+
+== 2.0.2 / 2011-04-17 Charlie Savage
+
+* Added binaries for windows (Charlie Savage).
+
+* Update Ruby 1.9 encoding handling to support libxml versions older than
+ version 2.6.26 which was released on June 6, 2006 (Charlie Savage).
+
+* Add publish_with_docs rake task - combines publishing the
+ website and docs (Anurag Priyam).
+
+* Correctly copy the documentation directory (Anurag Priyam)
+
+* Use relative link for rdoc so the links are correct on
+ both rubyforge and github (Anurag Priyam).
+
+* Update Rakefile to use Hanna RDco template (Charlie Savage).
+
+* Update dates on license file (Charlie Savage).
+
+* Add api to allow setting of attribute namespaces. Fixes issue #10 (Charlie Savage).
+
+* Remove old hack to call the on_error method. This hack isn't needed anymore
+ since a better workaround was put in place in the parser context. Fixes
+ This fixes issue #12 (Charlie Savage).
+
+* Remove references to passing blocks to validation functions. The blocks are no
+ longer called since the bindings use libxml's structured error handling. See
+ issue #6 (Charlie Savage).
+
+* Fix up comment in Document and Node. See issue #8 (Charlie Savage).
+
+* Update website text (Charlie Savage).
+
+== 2.0.0 / 2011-04-16 Charlie Savage
+
+* Ruby 1.9.2 support. The biggest addition is encoding support.
+ Strings returned by the libxml bindings are now set to the encoding
+ of the underlying xml document (Charlie Savage).
+
+* Rubinius compatability. Removed unnecessary use of RHASH_TBL (Aman Gupta)
+
+* Added .gemspec file (Dudley Flanders).
+
+* Updated Windows checks to take into account mingw32 (Yaohan Chen).
+
+* Fix memory leak in Reader#Expand (Szymon Nowak).
+
+* Fix memory leaks in Reader#read_string, Reader#read_inner_xml
+ and Reader#read_outer_xml (Sean Geoghegan).
+
+* Node#space_preserve= was backwards (Dudley Flanders)
+
+* Fixed typo in readme, added rdoc extension (Loren Sands-Ramshaw).
+
+* Switched to Rake Compiler (Charlie Savage).
+
+* Use xmlMalloc() memory for ctxt->sax structure. Sometimes the ctxt->sax pointer
+ may not be zeroed in rxml_sax_parser_parse(), for example when exception is raised
+ in one of callbacks. This lets xmlFreeParserCtxt() clean this up (Alexey I. Froloff).
+
+* Added a rake task to publish the website to github. Moved the jekyll website to
+ web directory (Anurag Priyam).
+
+* Modernize project metadata and layout (7rans)
+
+
+== 1.1.3 / 2009-03-18 Charlie Savage
+
+* Improve performance 10 to 20% by turning on libxml2's dictionary
+ feature that allows parsers to reuse previously parsed strings.
+
+* Fix XML::Node#remove! to work correctly with libxml's dictionary feature.
+
+* Correctly set up parser context options.
+
+* Simplify DOM modification code (Node#next=, Node#prev=, Node#sibling=) and
+ update documentation.
+
+* Deprecated Node#add_child and Node#child=, use Node#<< instead
+
+* Fix documentation for Node#<<
+
+* Added Document#import to enable moving nodes from one document
+ to another document.
+
+
+== 1.1.2 / 2009-03-12 Charlie Savage
+
+* Added XML::Node#inner_xml helper method.
+
+* Fix segmentation that could occur when calling the mark function on a
+ previously freed node.
+
+== 1.1.1 / 2009-03-10 Charlie Savage
+
+* Fix - Only include extra html parser context methods for versions of libxml
+ older than 2.6.27.
+
+== 1.1.0 / 2009-03-09 Charlie Savage
+
+* Fix bug caused by the mark function being called on partially initialized
+ attributes.
+
+* Revert back to libxml2's internal memory manager.
+
+== 1.0.0 / 2009-03-05 Charlie Savage
+
+* OS X (Charlie Savage). Update bindings to support the default installed
+ version of libxml2 (2.6.16) on OS X 10.5 and the latest version available
+ via MacPorts.
+
+== 0.9.9 / 2009-03-05 Charlie Savage
+
+* Ruby 1.9.1 support (Charlie Savage). libxml-ruby now compiles and runs on either
+ 1.8.6 and 1.9.1. With 1.8.6 all tests should pass while on 1.9.1 all but
+ for encoding tests pass. The port to Ruby 1.9.1 revealed two memory
+ allocation bugs (one with dtds, one with nodes) which are now fixed.
+
+* Better OS X support (Joe Khoobyar). The default version of libxml2
+ on OS X 10.5 is fairly old, resulting in this link error:
+
+ NSLinkModule() error
+ dyld: Symbol not found: _htmlNewParserCtxt
+
+ This can be fixed by using MacPorts to get a newer version of libxml2.
+ To make use of MacPorts, the build script has been updated to use xml2-config.
+ This can be fine-tuned using the new --with-xml2-config / --without-xml2-config
+ options to extconf.rb (default is --without-xml2-config to match existing behavior).
+
+* Greatly reduced memory usage (Joe Khoobyar).
+ See http://rubyforge.org/pipermail/libxml-devel/2009-February/001375.html.
+
+* Add Document#xhtml? and document#node_type methods (Joe Khoobyar)
+
+* Add XPath::Object#last (Joe Khoobyar)
+
+* Provide finer control over CDATA nodes on a parser by parser basis (Joe Khoobyar).
+
+* Bug fix - Namespaces were incorrectly merged with attributes in the new sax2
+ handler (Charlie Savage).
+
+* Bug fix - Support iterating over nodes and attributes even with blocks
+ that call remove! (Charlie Savage)
+
+* Bug fix - If reader.node is NULL, return nil instead of crashing (Charlie Savage)
+
+* Bug fix - Dtd's owned by documents were freed twice in some circumstances (Joe Khoobyar).
+
+* Bug fix - Fix output escaping on attributes nodes (Joe Khoobyar).
+
+* Bug fix - Make sure IO objects are not garbage collected when used
+ as parser sources (Charlie Savage).
+
+== 0.9.8 / 2009-1-24 Charlie Savage
+
+* Refactored XML::Parser, XML::HTMLParser, XML::SaxParser and
+ XML::Reader to have consistent APIs. All the parsers
+ now take a context object in their constructors, allowing fine
+ grained control over the parsers for advanced use cases. These
+ API changes are backwards compatible except
+ for XML::Reader, which now takes an optional hash table as a
+ second parameter in its various constructors versus an optional
+ boolean value.
+
+* Updated all APIs to use the encoding constants defined
+ in XML::Encoding versus string values. This API change
+ is not backwards compatible.
+
+* Added support for attribute declarations in DTD's via the new
+ XML::AttrDecl class (Len Lattanzi)
+
+* Support libxml's content escaping capabilities for text nodes by
+ wrapping libxml's "xmlStringText" and "xmlStringTextNoenc"
+ (Joe Khoobyar).
+
+* Updated XML::Reader#read API to return true if a node was read,
+ false if node was not read and raises an exception on an error.
+ Previously #read returned 1 if a node was read, 0 if a node was
+ not read and -1 for an error. This change is not backwards
+ compatible, but provides a more natural interface for Ruby by
+ allowing code like this:
+
+ while reader.read
+ # do stuff
+ end
+
+* Changed XML::Error exception objects to return copies of nodes that
+ cause parse errors instead of the original node. This prevents
+ segmentation faults when the error is reraised.
+
+* Added XML::Reader#node method.
+
+* Fixed compile errors on OS X which uses an older version of libxml.
+
+* Fixed memory leak when performing XPath searches.
+
+* Fixed rdocs.
+
+* Don't override libxml's default settings for entity substitution and
+ loading external DTDs. This may break some code - you may need to
+ add in a call to XML.default_substitute_entities = true or
+ XML.default_load_external_dtd = true.
+
+
+== 0.9.7 / 2008-12-08 Charlie Savage
+
+* Added SAX2 support. SAX handlers now define two new callbacks,
+ on_start_element_ns and on_end_element_ns methods. These
+ new callbacks support namespaces, making them superior to the older
+ callbacks on_start_element and on_end_element methods. The old callbacks
+ are still supported, but may be deprecated in the future depending
+ on community feedback.
+
+* Added SAX support for libxml's structured error handling.
+ That menas sax handlers now define a new callback, on_error,
+ which takes one parameter, an instance of XML::Error. The older
+ on_parser_error, on_parser_warning and on_parser_fatal_error
+ callbacks are no longer suported so you must port your code.
+ Note that the older callbacks took one string parameter, instead of
+ an XML::Error object.
+
+* Experimental work-around for libxml error handling bug - see
+ http://mail.gnome.org/archives/xml/2008-December/msg00014.html
+ for more information.
+
+* Fix compilation bugs on Solaris.
+
+* Fix Rdoc compilation bug.
+
+
+== 0.9.6 / 2008-12-08 Charlie Savage
+
+* Refactored namespace handling. The existing, and inconsistent,
+ namespace methods defined on XML::Node have been deprecated.
+ They have been replaced by a the new XML::Namespaces class.
+ Use this class to inspect a node's namespace, its default
+ namespace, its namespace definitions and which namespaces
+ are in scope. It can be accessed via the the
+ XML::Node#namespaces method.
+
+* Rationalized XML::Document#save, XML::Document#to_s and
+ XML::Node#to_s to take an optional hash table of parameters
+ that control how output is generated. Supported parameters
+ include setting indentation on or off, the indentation level
+ and the output encoding. This is an API change and may break
+ existing calls to XML::Document#save. However, the previous
+ API was broken - setting the encoding resulted in an error so
+ its unlikely anyone is using it.
+
+* Rationalized XML::Document#debug, XML::Node#debug, XML::XPath::XPathObject#Debug.
+
+* Deprecated a number of duplicate dump* and debug_* methods in
+ XML::Document and XML::Node.
+
+* Additional Ruby 1.9.1 compatability fixes.
+
+* Cleaned up header file guards.
+
+== 0.9.5 / 2008-11-29 Charlie Savage
+
+* Ruby 1.9.1 preview release compatability (Felipe Contreras)
+
+* Update Node#remove! to return the removed node and to set
+ its document to nil. This allows the node to be either
+ moved to another document, another part of the same document
+ or to be freed on the next garbage collection once its
+ references have gone out of scope.
+
+* Fix bug where XPathExpression#compile mistakenly overwrote
+ RegExp#compile.
+
+* Update Node to use standard ruby allocators and initializers.
+
+* Update HTML parser to be more forgiving of invalid documents.
+
+* Update include paths for Darwin Ports on OS X.
+
+* Updated C code base to use BSD/Allman style
+
+
+== 0.9.4 / 2008-11-24 Charlie Savage
+
+* Update HTML parser so that it can read files, strings and io
+ streams.
+
+* Update HTML parser to support user specified encodings.
+
+* Additional C code cleanup.
+
+== 0.9.3 / 2008-11-22 Charlie Savage
+
+* Fixed segmentation fault caused by documents being freed
+ before xpath results that referenced the document (take 2).
+
+* Allowed sax parser to use io stream
+
+* Combined encoding and input classes
+
+* Cleaned up C code - removed remaining legacy structures,
+ added static to most methods, changed C namespace from ruby_xml
+ to rxml
+
+== 0.9.2 / 2008-11-19 Charlie Savage
+
+* Add support for compiled XPath expressions (donated by Pavel Valodzka)
+
+* Fixes for compiling on OS X 10.5.4 and 10.5.5
+
+== 0.9.1 / 2008-11-18 Charlie Savage
+
+* Expose LibXML's encoding support via a new Encoding object.
+
+* Revamp error handling to be much easier to use. Errors are now
+ wrapped by the new XML::Error class and are thrown as exceptions
+ when it is appropriate.
+
+* Fixed segmentation fault caused by documents being freed
+ before xpath results that referenced the document.
+
+* Add Node#register_default_namespace to simplify default namespace handling.
+
+* Significantly improve documentation
+
+* A number of bug fixes and patches.
+
+== 0.9.0 / 2008-11-18 Charlie Savage
+
+* Version 0.9.0 was removed due to packaging errors.
+
+
+== 0.8.3 / 2008-07-21 Charlie Savage
+
+* Missed several files in last release
+
+== 0.8.2 / 2008-07-21 Charlie Savage
+
+* To use LibXML you can either require 'xml' or require 'libxml'.
+ The differences is that require 'xml' mixes the LibXML module into
+ the global namespace, thereby allowing you to write code such
+ as document = XML::Document.new. Note that this is different
+ from 0.8.0 and 0.8.1 and may require updating your code.
+
+* Support RelaxNG validation (thanks to Morus Walter)
+
+* Support passing IO objects to XmlReaders (thanks to Tom Hughes)
+
+* Fix segmentation fault caused by adding an attribute to a CDATA node
+
+* Moved node checking functions from C to Ruby
+
+* Improved Windows support - libxml-ruby should now work out of the box.
+
+* Improved Windows support - turned on libxml's zlib and iconv support.
+
+
+== 0.8.1 / 2008-07-09 Charlie Savage
+
+* Reimplmented Node#each_attr for backwards compatability
+
+* Moved node type test to Ruby.
+
+
+== 0.8.0 / 2008-07-09 Charlie Savage
+
+* Fixed bug in returning attributes from XPath results
+
+* Fixed DOM traversal methods
+
+* Changed Node#children to return an array of nodes
+
+* Fixed bug in returning attributes from XPath results
+
+* Refactored XPath support, providing more user hooks in the XPath::Context class
+
+* Added Node#properties for backwards compatibility
+
+* Updated setup.rb
+
+* Added more tests
+
+* Updated rdocs and README file
+
+* Moved libxml into LibXML namespace
+
+
+== 0.7.0 / 2008-07-09 Charlie Savage
+
+* Added new attributes class to provide a more natural way of working with attributes
+
+* Fixed XML::Attr to better support namespaces
+
+* Added documentation on how to use namespaces with XPath
+
+* Removed allocation of extraneous structures used to wrap nodes, namespaces and attributes
+
+* Cleaned up tests and added new test suite
+
+* Updated rdocs and README file
+
+* Cleaned out most of the bug list
+
+
+== 0.6.0 / 2008-07-01 Charlie Savage
+
+* Fixed memory allocation errors in Windows. On Windows, it is essential that the same library that allocates memory must free it. Thus ALLOC calls must be matched to ruby_xfree calls, which they were not. In addition, in one case Ruby was allocating memory to be freed by libxml. On Windows, that's a segmentation fault. On Linux it might fly, but still seems like a bad idea.
+
+* Fixed segmentation fault in xml reader expand (same xml tree freed twice)
+
+* Applied a number of patches from Tom Bagby, including fixes for xpath segmentation faults and fixes for various memory leaks
+
+* Cleaned up a number of compiler warnings
+
+* Renamed libxml_so.so to libxml_ruby.so (same for xslt). That wasn't actually my original intention, but um, it kind of sort of happened. It should not be noticeable from an end-user perspective.
+
+* Added rake files for building with MingW
+
+* Added rake files for packing gems. Note that I did this outside the existing rake tasks because I didn't see how they were actually building the gems.
+
+* Cleaned up the tests and added a few more based on bug reports from the Tracker and mailing list.
+
+* Cleaned out the patch queue and went through about 1/2 the bug list
+
+
+=== 2007-11-16 "Dan Janowski" <danj at 3skel.com>
+
+* Merged Dan's MEM2 branch to trunk.
+
+== 0.5.3 /
+
+=== 2007-11-16 "Dan Janowski" <danj at 3skel.com>
+
+* Merged Dan's MEM2 branch to trunk.
+
+
+== 0.5.2 / 2007-10-10
+
+=== 2007-10-10 "Dan Janowski" <danj at 3skel.com>
+
+* (Dan, fill in the major points of the changes you made up to here -thanks)
+
+=== 2007-01-14 "Laurent Sansonetti" <lrz at chopine.be>
+
+* Added some preliminary RDoc comments for XML::Reader.
+
+=== 2006-12-05 "Laurent Sansonetti" <lrz at chopine.be>
+
+* Added XML::Reader, a set of bindings to the xmlTextReader API.
+
+
+== 0.3.8.4 / 2006-12-02
+
+=== 2006-04-15 "Ross Bamform" <rosco at roscopeco.co.uk>
+
+* Implemented SAX parser callback handling.
+
+=== 2006-04-12 "Ross Bamford" <rosco at roscopeco.co.uk>
+
+* Integrated and tested community patches.
+* Defined XML::Node (hash) equality in terms of XML representation.
+
+=== 2006-04-12 "Tim Yamin" <plasmaroo at gentoo.org>
+
+* Fixed XML::Node#content inoperable bug (plasmaroo) [patch]
+* Fixed memory leak in same
+
+=== 2006-04-12 "Mark Van Holstyn" <mvette13 at gmail.com>
+
+* Added XML::Node::Set#first (mvette13) [patch]
+* Added XML::Node::Set#empty?
+* Fixed XML::Node::Set#to_a
+* Added XML::Node#find_first
+* Added XML::Node#remove!
+
+=== 2006-03-27 "Ross Bamford" <rosco at roscopeco.co.uk>
+
+* Integrated contributed XML::Parser.register_error_handler patch (rosco)
+
+=== 2006-02-27 "Ross Bamford" <rosco at roscopeco.co.uk>
+
+* Fixed all multiple symbol definitions for -fno-common.
+* Removed OSX -fno-common workaround.
+
+
+== 0.3.6 / 2006-02-23
+
+=== 2006-02-21 "Ross Bamford" <rosco at roscopeco.co.uk>
+
+* Patched extconf.rb with OSX -fno-common workaround
+* Added gem and packaging support to Rakefile
+* Moved version update to Rakefile
+* Removed legacy project utility scripts
+
+=== 2005-02-19 "Ross Bamford" <rosco at roscopeco.co.uk>
+
+* Fixed doublefree bug in ruby_xml_attr.
+* Fixed small leak in parser
+
+=== 2005-12-18 "Ross Bamford" <rosco at roscopeco.co.uk>
+
+* Updated for GCC 4.0 (community patches)
+* Fixed default validation bug
+* Refactored project, removed outdated files, cleaned up tests.
+* Added RDoc documentation across .c files.
+* Fixed up a few strings.
+
+=== 2004-04-04 "Mangler Jurgen" <et@wkv.at>
+
+* ruby_xml_node.cz: fixed ruby_xml_node_property_set. The ill-behaviour
+ was, that there was added a second attribute of the same
+ name, when you were setting the value of an already existing
+ attribute.
+
+=== 2004-03-17 "Lukas Svoboda" <luks@fi.muni.cz>
+
+* ruby_xml_node.c: ruby_xml_node_to_s now returns XML subtree dump.
+
+=== 2004-02-27 "Martin Povolny" <martin@solnet.cz>
+
+* ruby_xml_node.c: added XML::Node.copy, this makes possible building
+ of xml documents from nodes taken from other xml documents
+ without making ruby SIGSEGV (see tests/copy_bug.rb).
+
+=== 2004-02-26 "Martin Povolny" <martin@solnet.cz>
+
+* ruby_xml_dtd.c, ruby_xml_dtd.h, ruby_xml_schema.c, ruby_xml_schema.h:
+ more work on validation, now you can actually validate
+ document using dtd or xml schema, also solved warning and
+ error propagation (see tests/{dtd|schema}-test.rb).
+
+=== 2003-12-30 "Martin Povolny" <martin@solnet.cz>
+
+* ruby_xml_dtd.c, ruby_xml_dtd.h, ruby_xml_schema.c, ruby_xml_schema.h:
+ prelimitary support for dtd and schema validation
+
+=== 2003-09-15 "Martin Povolny" <martin@solnet.cz>
+
+* ruby_xml_input_cbg.c, libxml.c: added class InputCallbacks to make
+ possible registering custom input callbacks
+ handlers (xmlRegisterInputCallbacks) written in ruby
+
+=== 2003-08-01 "Martin Povolny" <martin@solnet.cz>
+
+* ruby_xml_document.c: corrected argument handling in ruby_xml_document_find
+* ruby_xml_node.c: corrected argument handling in ruby_xml_node_find
+
+
+
View
21 LICENSE
@@ -0,0 +1,21 @@
+ Copyright (c) 2008-2011 Charlie Savage and contributors
+ Copyright (c) 2002-2007 Sean Chittenden and contributors
+ Copyright (c) 2001 Wai-Sun "Squidster" Chia
+
+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.
View
99 README.rdoc
@@ -0,0 +1,99 @@
+= free-image
+
+== Overview
+The free-image gem provides Ruby language bindings for the
+FreeImage[http://freeimage.sourceforge.net/] library. It is free software,
+released under the MIT License.
+
+FreeImage is an light-weight, open source image manipulation library that
+supports many popular graphics image {formats}[rdoc-ref:FreeImage.formats]
+such as PNG, JPEG, GIF, BMP, and TIFF.
+
+We think FreeImage is a great library for applications that need to read, write,
+create and modify images and thumbnails because:
+
+* Its easy to use
+* Its supports almost all popular image formats
+* Its a light-weight alternative to larger libraries such as ImageMagick,
+ supporting basic manipulation functions but not advanced functionality
+* Its cross-platform
+* The ruby bindings are implemented using FFI, so work across all Ruby
+ implementations and do not have to be compiled
+* Its much more comprehensive than ImageScience
+* Has comprehensive documentation
+
+Note that FreeImage is not the right library for you if you need:
+* Advanced image processing operations such as convolution and transforms
+* Bitmap drawing
+* Vector graphics
+
+== Installation
+free-image requires Ruby 1.8.7 or higher. The easiest way to install
+free-image is via Ruby Gems. To install:
+
+ gem install free-image
+
+
+== Getting Started
+Using free-image is easy. To get you started, refer to the
+FreeImage cookbook[rdoc-ref:cookbook.rdoc].
+
+
+== Implementation Status
+The FreeImage API is divided into multiple parts. As summarized below, the Ruby ffi
+bindings currently implement a subset of the available api. Patches are welcome to
+extend the coverage.
+
+=== Bitmap functions
+* General - FreeImage::Bitmap
+* Bitmap management - FreeImage::Bitmap
+* Bitmap information - FreeImage::Information, FreeImage::Color::Palette
+* Filetype - FreeImage::File, FreeImage::IO, FreeImage::Memory
+* Pixel access - FreeImage::Pixel
+* Conversion - FreeImage::Conversions
+* Tone mapping - Not Implemented
+* ICC profile - FreeImage::ICC
+* Plugin - Not Implemented
+* Multipage - Not Implemented
+* Memory I/O streams - FreeImage::MemoryStream
+* Compression - Not Implemented
+* Helper functions - FreeImage::Helper
+
+=== Metadata Functions
+* Introduction - Not Implemented
+* Tag creation and destruction - Not Implemented
+* Tag accessors - Not Implemented
+* Metadata iterator - Not Implemented
+* Metadata accessors - Not Implemented
+* Metadata helper functions - Not Implemented
+
+=== Toolkit Functions
+* Rotation and flipping - FreeImage::Transforms
+* Upsampling / downsampling - FreeImage::Modify
+* Color manipulation - Not Implemented
+* Channel processing - Not Implemented
+* Copy / Paste / Composite routines - FreeImage::Modify
+* Background filling - FreeImage::Modify
+* Miscellaneous algorithms - Not Implemented
+
+== Documentation
+Documentation is available via rdoc, and is installed automatically with the
+gem. Note that much of the documentation is directly copied from
+the FreeImage API documentation available
+here[http://downloads.sourceforge.net/freeimage/FreeImage3151.pdf].
+
+free-image's online documentation is generated using Hanna. To generate
+documentation from source:
+
+ gem install hanna-nouveau
+ rake rdoc
+ - or -
+ rdoc -o doc/rdoc -f hanna -m "README.rdoc" lib/**/*.rb README.rdoc
+
+
+== Support
+
+If you have any questions about using free-image, please ?
+
+== License
+See LICENSE for license information.
View
34 Rakefile
@@ -0,0 +1,34 @@
+#!/usr/bin/env ruby
+
+require "rubygems"
+require "rake/testtask"
+require "rubygems/package_task"
+require "rdoc/task"
+
+GEM_NAME = "free-image"
+
+# Read the spec file
+spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
+
+# Setup generic gem
+Gem::PackageTask.new(spec) do |pkg|
+ pkg.package_dir = 'pkg'
+ pkg.need_tar = false
+end
+
+# RDoc Task
+desc "Generate rdoc documentation"
+RDoc::Task.new("rdoc") do |rdoc|
+ rdoc.rdoc_dir = 'doc/rdoc'
+ rdoc.title = "FreeImage"
+ # Show source inline with line numbers
+ rdoc.options << "--line-numbers"
+ # Make the readme file the start page for the generated html
+ rdoc.main = 'README.rdoc'
+end
+
+# Test Task
+Rake::TestTask.new do |t|
+ t.libs << "test"
+ t.verbose = true
+end
View
225 cookbook.rdoc
@@ -0,0 +1,225 @@
+= \FreeImage Cookbook
+Below are various recipes to get you up and running with \FreeImage as quickly
+as possible. Note that the images the recipes use can be found in the
+test/images directory.
+
+== Loading An Image
+The first step in using \FreeImage is to load an image. \FreeImage can load
+images from files[rdoc-ref::FreeImage::File], strings[rdoc-ref::FreeImage::Memory]
+or IO[rdoc-ref::FreeImage::IO] streams. The simplest way to do this is
+via the FreeImage::Bitmap.open method:
+
+ image = FreeImage::Bitmap.open('images/lena.tiff')
+ image = FreeImage::Bitmap.open(io_object)
+ image = FreeImage::Bitmap.open(FreeImage::Memory.new(string))
+
+The open method also takes two additional optional parameters, format and flags,
+that provide greater control over opening images if needed.
+
+Image[link:../../test/images/lena.png]
+
+== Saving An Image
+Now let's say you want to save the image to :png format. This is done
+via the FreeImage::Bitmap.save method. The save method takes a destination,
+which can be a file[rdoc-ref::FreeImage::File], string[rdoc-ref::FreeImage::Memory]
+or IO[rdoc-ref::FreeImage::IO] stream, and an image format.
+
+ image.save('images/lena.png', :png)
+
+== Creating a Thumbnail
+Next, let's assume our application needs to show a list of
+thumbnails for the images it stores. This can be done using
+the make_thumbnail[rdoc-ref:FreeImage::Modify.make_thumbnail] method
+in the Modify[rdoc-ref:FreeImage::Modify] module.
+
+ thumbnail = image.make_thumbnail(100)
+ thumbnail.save('images/lena_thumbnail.png', :png)
+
+Thumbnail[link:../../test/images/lena_thumbnail.png]
+
+== Putting a Border Around a Thumbnail
+Next, let's assume we want to put a red border around our thumbnail. There
+are various approaches to do doing this. In the first approach, we'll use
+the enlarge_canvas[FreeImage::Modify.enlarge_canvas] method.
+
+ # Border size
+ border = 4
+
+ # Specify the red color
+ color = FreeImage::RGBQuad.create(255, 0, 0)
+
+ # Add 4 pixel red border around the thumbnail
+ thumbnail_border = thumbnail.enlarge_canvas(border, border, border, border, color)
+ thumbnail_border.save('images/lena_thumbnail_border_1.png', :png)
+
+ThumbnailBorderEnlarge[link:../../test/images/lena_thumbnail_border_enlarge.png]
+
+In the second approach, let's create a image with a red background
+and then paste ontop of it our thumbnail:
+
+ # Create a red image that is the same size as the thumbnail
+ red_image = FreeImage::Bitmap.create(thumbnail.width, thumbnail.height, thumbnail.bits_per_pixel)
+ red_image_new.fill_background(color)
+
+ # Now copy a subimage from the thumbnail that is 2 borders less wide and tall
+ subimage = thumbnail.copy(border, border, thumbnail.width - border, thumbnail.height - border)
+
+ # Now paste the submimage into the red image. Specify an alpha over 255
+ # to disable alpha blending
+ red_image.paste(subimage, border, border, 300)
+ red_image.save('images/test1.png', :png)
+ thumbnail_border.save('images/lena_thumbnail_border_2.png', :png)
+
+ThumbnailBorderPaste[link:../../test/images/lena_thumbnail_border_paste.png]
+
+== Resampling An Image
+If you need additional control of how an image is resampled, then use the
+FreeImage::Bitmap#rescale method, which lets you specify a filtering
+algorithm. To see how each filter works, let's scale up the thumbnail
+by 400%.
+
+ thumbnail = FreeImage::Bitmap.open('images/lena_thumbnail.png')
+
+ FreeImage.enum_type(:filter).symbols.each do |filter|
+ rescaled = thumbnail.rescale(thumbnail.width * 4, thumbnail.height * 4, filter)
+ rescaled.save("images/lena_rescale_#{filter.to_s}.png", :png)
+ end
+
+RescaleBox[link:../../test/images/lena_rescale_box.png]
+RescaleBicubic[link:../../test/images/lena_rescale_bicubic.png]
+RescaleBilinear[link:../../test/images/lena_rescale_bilinear.png]
+RescaleBspline[link:../../test/images/lena_rescale_bspline.png]
+RescaleCatmullrom[link:../../test/images/lena_rescale_catmullrom.png]
+RescaleLanczos3[link:../../test/images/lena_rescale_lanczos3.png]
+
+== Flipping An Image
+The Transform modules lets you flip or rotate an image. Let's say you want to
+flip and image horizontally:
+
+ image.flip_horizontal
+ image.save('images/lena_flipped.png', :png)
+
+Thumbnail[link:../../test/images/lena_flipped.png]
+
+== Rotating An Image
+Next, let's rotate an image. Two methods are provide, FreeImage::Bitmap#rotate and
+FreeImage::Bitmap#rotate_ex. The #rotate method is simpler to use:
+
+ image = FreeImage::Bitmap.open('images/lena.png', :png)
+
+ # Rotate the image 45 degrees using white as the background fill color
+ color = FreeImage::RGBQuad.create(255, 255, 255, 0)
+ rotated = image.rotate(45, color)
+ rotated.save("images/lena_rotate_45.png", :png)
+
+Thumbnail[link:../../test/images/lena_rotate_45.png]
+
+Note however that the image size and geometry has changed. Thus, the #rotate
+function is best for rotating and image 90, 180 or 270 degrees.
+
+Let's now rotate the image using the #rotate_ex method while using a mask:
+
+ rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, true)
+ rotated.save("images/lena_rotate_ex_45_masked.png", :png)
+
+And now let's rotate the image without a mask, so data is filled in using
+a mirroring algorithm:
+
+ rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, false)
+ rotated.save("images/lena_rotate_ex_45_mirrored.png", :png)
+
+Thumbnail[link:../../test/images/lena_rotate_ex_45_masked.png]
+Thumbnail[link:../../test/images/lena_rotate_ex_45_mirrored.png]
+
+Now lets rotate around the top left corner:
+
+ rotated = image.rotate_ex(45, 0, 0, 0, 0, true)
+ rotated.save("images/lena_rotate_ex_45_top_left.png", :png)
+
+Thumbnail[link:../../test/images/lena_rotate_ex_45_top_left.png]
+
+== Compositing An Image
+\FreeImage also lets you composite an image with a background color or another image.
+Here is an example of compositing the sample image with green.
+
+ image = FreeImage::Bitmap.open('images/sample.png')
+ color = FreeImage::RGBQuad.create(0, 255, 0, 0)
+ composite = image.composite_with_color(color)
+ composite.save("images/sample_composite_color.png", :png)
+
+Sample[link:../../test/images/sample.png]
+SampleCompositeColor[link:../../test/images/sample_composite_color.png]
+
+== Manipulating An Image
+\FreeImage also allows you to directly access each pixel in an image.
+Say for example we want to create an image that has a gradient from
+blue in the top left corner to green in the bottom right
+
+ image = FreeImage::Bitmap.create(300, 300, 24)
+ color = FreeImage::RGBQuad.new
+
+ image.width.times do |x|
+ image.height.times do |y|
+ color[:green] = (x.to_f/image.width) * 255
+ color[:blue] = (y.to_f/image.height) * 255
+ image.set_pixel_color(x, y, color)
+ end
+ end
+
+ image.save('images/gradient.png', :png)
+
+Gradient[link:../../test/images/gradient.png]
+
+Note you can use a similar technique as another way of drawing a border around a
+thumbnail.
+
+== Using Scanlines
+Scanlines[rdoc-ref:FreeImage::Scanline] provide low level access to image data.
+The only lower-level access is working with the actual raw bytes, which you can do
+via the FreeeImage::Bitmap#bytes method, but its not recommended.
+
+A scanline represents one row of image data, starting from the bottom. Let's go back
+to our example above of drawing a red border around a thumbnail.
+
+ # Helper method
+ def set_to_red(color)
+ color[:red] = 255
+ color[:green] = 0
+ color[:blue] = 0
+ end
+
+ # Create a thumbnail
+ image = FreeImage::Bitmap.open('images/lena.png')
+ thumbnail = image.make_thumbnail(100)
+
+ # Draw bottom border
+ (0..3).each do |index|
+ scanline = thumbnail.scanline(index)
+ scanline.each do |color|
+ set_to_red(color)
+ end
+ end
+
+ # Draw top border
+ ((thumbnail.height - 5)..(thumbnail.height - 1)).each do |index|
+ scanline = thumbnail.scanline(index)
+ scanline.each do |color|
+ set_to_red(color)
+ end
+ end
+
+ # Draw left and right borders
+ (1..(thumbnail.height - 2)).each do |index|
+ scanline = thumbnail.scanline(index)
+ (0..4).each do |index|
+ set_to_red(scanline[index])
+ end
+
+ ((thumbnail.width - 5)..(thumbnail.width - 1)).each do |index|
+ set_to_red(scanline[index])
+ end
+ end
+
+ thumbnail.save("images/lena_thumbnail_border_scanline.png", :png)
+
+ThumbnailBorderScanline[link:../../test/images/lena_thumbnail_border_scanline.png]
View
32 free-image.gemspec
@@ -0,0 +1,32 @@
+# encoding: utf-8
+require 'rake'
+
+# ------- Default Package ----------
+FILES = FileList[
+ 'HISTORY',
+ 'LICENSE',
+ 'free-image.gemspec',
+ 'Rakefile',
+ 'README.rdoc',
+ 'lib/**/*.rb',
+ 'test/**/*'
+]
+
+Gem::Specification.new do |spec|
+ spec.name = 'free-image'
+ spec.version = '0.1.0'
+ spec.summary = 'Ruby Bindings for the Free Image Library'
+ spec.description = <<-EOS
+ FreeImage is an Open Source library project for developers who would like to support
+ popular graphics image formats like PNG, BMP, JPEG, TIFF and others as needed by
+ today's multimedia applications. FreeImage is easy to use, fast, multithreading
+ safe, compatible with all 32-bit or 64-bit versions of Windows, and
+ cross-platform (works both with Linux and Mac OS X).
+ EOS
+ spec.authors = [ 'Charlie Savage']
+ spec.platform = Gem::Platform::RUBY
+ spec.files = FILES.to_a
+ spec.test_files = Dir.glob("test/test_*.rb")
+ spec.required_ruby_version = '>= 1.8.7'
+ spec.date = Time.now
+end
View
2 lib/1.8/.gitignore
@@ -0,0 +1,2 @@
+
+*.so
View
2 lib/1.9/.gitignore
@@ -0,0 +1,2 @@
+
+*.so
View
70 lib/free-image.rb
@@ -0,0 +1,70 @@
+# encoding: UTF-8
+require 'ffi'
+require 'rbconfig'
+
+module FreeImage
+ def self.msvc?
+ # If this is windows we assume FreeImage was compiled with
+ # MSVC since that is the binary distibution provided on
+ # the web site. If you have compiled FreeImage yourself
+ # on windows using another compiler, set this to false.
+ #
+ # This is important because FreeImage defines different
+ # type sizes for MSVC - see types/ffi.rb
+ FFI::Platform.windows?
+ end
+
+ def self.library
+ if FFI::Platform.windows?
+ 'FreeImaged'
+ else
+ 'free_image'
+ end
+ end
+
+ extend ::FFI::Library
+ ffi_lib(library)
+ ffi_convention :stdcall if FFI::Platform.windows?
+end
+
+
+# Types
+require 'free-image/types/ffi'
+require 'free-image/types/boolean'
+
+# More types
+require 'free-image/types/rgb_triple'
+require 'free-image/types/rgb_quad'
+require 'free-image/types/rgb16'
+require 'free-image/types/rgba16'
+require 'free-image/types/rgbf'
+require 'free-image/types/rgbaf'
+require 'free-image/types/complex'
+
+# Enums
+require 'free-image/enums/color_types'
+require 'free-image/enums/dithers'
+require 'free-image/enums/filters'
+require 'free-image/enums/formats'
+require 'free-image/enums/image_types'
+
+# Sources
+require 'free-image/sources/abstract_source'
+require 'free-image/sources/io'
+require 'free-image/sources/file'
+require 'free-image/sources/memory'
+
+# Modules
+require 'free-image/modules/conversions'
+require 'free-image/modules/helper'
+require 'free-image/modules/icc'
+require 'free-image/modules/information'
+require 'free-image/modules/modify'
+require 'free-image/modules/pixels'
+require 'free-image/modules/transforms'
+
+# Main classes
+require 'free-image/errors'
+require 'free-image/palette'
+require 'free-image/scanline'
+require 'free-image/bitmap'
View
142 lib/free-image/bitmap.rb
@@ -0,0 +1,142 @@
+module FreeImage
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Allocate(int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
+ attach_function('FreeImage_Allocate', [:int, :int, :int, :uint, :uint, :uint], :pointer)
+
+ # DLL_API FIBITMAP * DLL_CALLCONV FreeImage_Clone(FIBITMAP *dib);
+ attach_function('FreeImage_Clone', [:pointer], :pointer)
+
+ # DLL_API void DLL_CALLCONV FreeImage_Unload(FIBITMAP *dib);
+ attach_function('FreeImage_Unload', [:pointer], :void)
+
+ # == Summary
+ #
+ # Represents an image that has been loaded into memory. Once the image is loaded,
+ # you can get
+ # information[rdoc-ref:FreeImage::Information] about it,
+ # convert[rdoc-ref:FreeImage::Conversions] it,
+ # modify[rdoc-ref:FreeImage::Modify] it.
+ # transform[rdoc-ref:FreeImage::Information] it,
+ #
+ # == Usage
+ #
+ # # Open an image form a file
+ # image = FreeImage::BitmapFile.open('test/fixtures/lena.png')
+ #
+ # # Get information about it
+ # bg = image.background_color
+ #
+ # # Convert it
+ # image = image.convert_to_greyscale
+ #
+ # # Modify it
+ # image = image.convert_to_greyscale
+ #
+ # # Transform it
+ # image = image.rotate(90)
+ #
+ class Bitmap < FFI::AutoPointer
+ include Conversions
+ include ICC
+ include Information
+ include Modify
+ include Pixels
+ include Transforms
+
+ ## The source of the image. May be a File, in Memory string, IO stream or nil.
+ attr_reader :source
+
+ # Creates a new image with the specified width, height and bits per pixel.
+ #
+ # == Parameters
+ # width:: The width of the new image
+ # height:: The height of the new image
+ # bits_per_pixel:: The size in bits of a pixel
+ # red_mask:: The bit-layout of the red color component in a bitmap
+ # green_mask:P: The bit-layout of the green color component in a bitmap
+ # blue_mask:: The bit-layout of the blue color component in a bitmap
+ #
+ # The last three parameter are used to tell FreeImage the bit-layout of
+ # the color components in the bitmap, e.g. where in a pixel the red,
+ # green and blue components are stored.
+ #
+ # To give you an idea about how to interpret the color masks:
+ # when red_mask is 0xFF000000 this means that the last 8 bits in
+ # one pixel are used for the color red. When green_mask is 0x000000FF, it
+ # means that the first 8 bits in a pixel are used for the color green.
+ #
+ # The new image is initially filled completely with zeroes. Zero in a image
+ # is usually interpreted as black. This means that if your bitmap is palletized
+ # it will contain a completely black palette. You can access, and hence populate
+ # the palette via #palette.
+ #
+ # For 8-bit images, a default greyscale palette will also be created.
+ #
+ def self.create(width, height, bits_per_pixel, red_mask = 0, green_mask = 0, blue_mask = 0)
+ ptr = FreeImage.FreeImage_Allocate(width, height, bits_per_pixel, red_mask, green_mask, blue_mask)
+ FreeImage.check_last_error
+ new(ptr)
+ end
+
+ # Opens a new image from the specified source.
+ #
+ # == Parameters
+ # source:: The source of the image
+ #
+ # The source parameter can be a File, Memory or IO stream. It can
+ # also be a string which is interpreted as a fully qualified file path.
+ def self.open(source)
+ figure_source(source).open
+ end
+
+ # Closes an image and releases its associated memory
+ def self.release(ptr) #:nodoc:
+ FreeImage.FreeImage_Unload(ptr)
+ end
+
+ # Creates a new image from a c-pointer an image source. Generally you
+ # do not want to use this method. Instead, use Bitmap.open.
+ def initialize(ptr, source = nil)
+ @source = source
+ super(ptr)
+ end
+
+ # Creates an exact copy of the current image.
+ def clone
+ ptr = FreeImage.FreeImage_Clone(self)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Save the image to the specified source.
+ #
+ # == Parameters
+ # dst:: The destination where the image will be saved.
+ # format:: The format[rdoc-ref:FreeImage.formats] to save the image to.
+ # flags:: Format specific flags that control how a bitmap is saved. These flags are defined
+ # as constants on the AbstractSource class. Flags can be combined using
+ # Ruby's bitwise or operator (|)
+ #
+ def save(source, format, flags = 0)
+ self.class.figure_source(source).save(self, format, flags)
+ end
+
+ private
+
+ def self.figure_source(source)
+ case source
+ when AbstractSource
+ source
+ when ::IO
+ IO.new(source)
+ when String
+ File.new(source)
+ else
+ raise(ArgumentError, "Unknown source type: #{source.class.name}")
+ end
+ end
+
+ def figure_color_klass
+
+ end
+ end
+end
View
24 lib/free-image/enums/color_types.rb
@@ -0,0 +1,24 @@
+# encoding: UTF-8
+
+module FreeImage
+ ##
+ # FreeImage supports the following color types:
+ #
+ # :minis_black:: Monochrome bitmap (1-bit) -> first palette entry is black.
+ # Palletised bitmap (4 or 8-bit) and single channel non standard bitmap -> the bitmap has a greyscale palette
+ # :minis_white:: Monochrome bitmap (1-bit) -> first palette entry is white.
+ # Palletised bitmap (4 or 8-bit) and single channel non standard bitmap -> the bitmap has an inverted greyscale palette
+ # :palette:: Palettized bitmap (1, 4 or 8 bit)
+ # :rgb:: High-color bitmap (16, 24 or 32 bit), RGB16 or RGBF
+ # :rgb_alpha:: High-color bitmap with an alpha channel (32 bit bitmap, RGBA16 or RGBAF)
+ # :cmyk:: CMYK bitmap (32 bit only)
+ #
+ # :method: color_types
+
+ FreeImage.enum :color_type, [:minis_white, 0,
+ :minis_black, 1,
+ :rgb, 2,
+ :palette, 3,
+ :rgb_alpha, 4,
+ :cmyk, 5]
+end
View
24 lib/free-image/enums/dithers.rb
@@ -0,0 +1,24 @@
+# encoding: UTF-8
+
+module FreeImage
+ ##
+ # FreeImage supports the following dithering algorithms:
+ #
+ # :fs:: Floyd & Steinberg error diffusion algorithm
+ # :bayer4x4:: Bayer ordered dispersed dot dithering (order 2 – 4x4 -dithering matrix)
+ # :bayer8x8:: Bayer ordered dispersed dot dithering (order 3 – 8x8 -dithering matrix)
+ # :bayer16x16:: Bayer ordered dispersed dot dithering (order 4 – 16x16 dithering matrix)
+ # :cluster6x6:: Ordered clustered dot dithering (order 3 - 6x6 matrix)
+ # :cluster8x8:: Ordered clustered dot dithering (order 4 - 8x8 matrix)
+ # :cluster16x16:: Ordered clustered dot dithering (order 8 - 16x16 matrix)
+ #
+ # :method: dithers
+
+ FreeImage.enum :dither, [:fs, 0,
+ :bayer4x4, 1,
+ :bayer8x8, 2,
+ :cluster6x6, 3,
+ :cluster8x8, 4,
+ :cluster16x16, 5,
+ :bayer16x16, 6]
+end
View
12 lib/free-image/enums/filters.rb
@@ -0,0 +1,12 @@
+module FreeImage
+ ##
+ #FreeImage supports the following rescaling filters:
+ #
+ # :method: filters
+ enum :filter, [:box, 0,
+ :bicubic, 1,
+ :bilinear, 2,
+ :bspline, 3,
+ :catmullrom, 4,
+ :lanczos3, 5]
+end
View
84 lib/free-image/enums/formats.rb
@@ -0,0 +1,84 @@
+# encoding: UTF-8
+
+module FreeImage
+ ##
+ # FreeImage supports over 30 bitmap types, which are indentified via symbols.
+ # Supported formats include:
+ #
+ # :bmp:: Windows or OS/2 Bitmap File (*.BMP)
+ # :cut:: Dr. Halo (*.CUT)
+ # :dds:: DirectDraw Surface (*.DDS)
+ # :exr:: ILM OpenEXR (*.EXR)
+ # :faxg3:: Raw Fax format CCITT G3 (*.G3)
+ # :gif:: Graphics Interchange Format (*.GIF)
+ # :hdr:: High Dynamic Range (*.HDR)
+ # :ico:: Windows Icon (*.ICO)
+ # :iff:: Amiga IFF (*.IFF, *.LBM)
+ # :jpeg:: Independent JPEG Group (*.JPG, *.JIF, *.JPEG, *.JPE)
+ # :jng:: JPEG Network Graphics (*.JNG)
+ # :j2k:: JPEG-2000 codestream (*.J2K, *.J2C)
+ # :jp2:: JPEG-2000 File Format (*.JP2)
+ # :koala:: Commodore 64 Koala format (*.KOA)
+ # :lbm:: Amiga IFF (*.IFF, *.LBM)
+ # :mng:: Multiple Network Graphics (*.MNG)
+ # :pbm:: Portable Bitmap (ASCII) (*.PBM)
+ # :pbmraw:: Portable Bitmap (BINARY) (*.PBM)
+ # :pcd:: Kodak PhotoCD (*.PCD)
+ # :pcsx:: Zsoft Paintbrush PCX bitmap format (*.PCX)
+ # :pfm:: Portable Floatmap (*.PFM)
+ # :pgm:: Portable Graymap (ASCII) (*.PGM)
+ # :pgmraw:: Portable Graymap (BINARY) (*.PGM)
+ # :pict:: Macintosh PICT (*.PCT, *.PICT, *.PIC)
+ # :png:: Portable Network Graphics (*.PNG)
+ # :ppm:: Portable Pixelmap (ASCII) (*.PPM)
+ # :ppmraw:: Portable Pixelmap (BINARY) (*.PPM)
+ # :psd:: Adobe Photoshop (*.PSD)
+ # :ras:: Sun Rasterfile (*.RAS)
+ # :raw:: RAW camera image (many extensions)
+ # :sgi:: Silicon Graphics SGI image format (*.SGI)
+ # :targa:: Truevision Targa files (*.TGA, *.TARGA)
+ # :tiff:: Tagged Image File Format (*.TIF, *.TIFF)
+ # :wbmp:: Wireless Bitmap (*.WBMP)
+ # :xbm:: X11 Bitmap Format (*.XBM)
+ # :xpm:: X11 Pitmap Format (*.XPM)
+ #
+ # :method: formats
+
+ FreeImage.enum :format, [:unknown, -1,
+ :bmp, 0,
+ :ico , 1,
+ :jpeg, 2,
+ :jng , 3,
+ :koala, 4,
+ :lbm, 5,
+ :iff, 5, # Yes this is intentional!
+ :mng, 6,
+ :pbm, 7,
+ :pbmraw, 8,
+ :pcd, 9,
+ :pcsx, 10,
+ :pgm, 11,
+ :pgmraw, 12,
+ :png, 13,
+ :ppm, 14,
+ :ppmraw, 15,
+ :ras, 16,
+ :targa, 17,
+ :tiff, 18,
+ :wbmp, 19,
+ :psd, 20,
+ :cut, 21,
+ :xbm, 22,
+ :xpm, 23,
+ :dds, 24,
+ :gif, 25,
+ :hdr, 26,
+ :faxg3, 27,
+ :sgi, 28,
+ :exr, 29,
+ :j2k, 30,
+ :jp2, 31,
+ :pfm, 32,
+ :pict, 33,
+ :raw, 34]
+end
View
36 lib/free-image/enums/image_types.rb
@@ -0,0 +1,36 @@
+# encoding: UTF-8
+
+module FreeImage
+ ##
+ # FreeImage supports the following image types:
+ #
+ # :unknown:: Unknown format (returned value only, never use it as input value)
+ # :bitmap:: Standard image: 1-, 4-, 8-, 16-, 24-, 32-bit
+ # :uint16:: Array of unsigned short: unsigned 16-bit
+ # :int16:: Array of short: signed 16-bit
+ # :uint32:: Array of unsigned long: unsigned 32-bit
+ # :int32:: Array of long: signed 32-bit
+ # :float:: Array of float: 32-bit IEEE floating point
+ # :double:: Array of double: 64-bit IEEE floating point
+ # :complex:: Array of FICOMPLEX: 2 x 64-bit IEEE floating point
+ # :rgb16:: 48-bit rgb image: 3 x 16-bit
+ # :rgba16:: 64-bit rgbA image: 4 x 16-bit
+ # :rgbf:: 96-bit rgb float image: 3 x 32-bit IEEE floating point
+ # :rgbaf:: 128-bit rgbA float image: 4 x 32-bit IEEE floating point
+ #
+ # :method: image_types
+
+ FreeImage.enum :image_type, [:unknown,
+ :bitmap,
+ :uint16,
+ :int16,
+ :uint32,
+ :int32,
+ :float,
+ :double,
+ :complex,
+ :rgb16,
+ :rgba16,
+ :rgbf,
+ :rgbaf]
+end
View
44 lib/free-image/errors.rb
@@ -0,0 +1,44 @@
+module FreeImage
+ LAST_ERROR = 'free_image_error'
+
+ #typedef void (*FreeImage_OutputMessageFunction)(FREE_IMAGE_FORMAT fif, const char *msg);
+ #typedef void (DLL_CALLCONV *FreeImage_OutputMessageFunctionStdCall)(FREE_IMAGE_FORMAT fif, const char *msg);
+ callback(:output_message_callback, [:format, :pointer], :void)
+
+ if FFI::Platform.windows?
+ #DLL_API void DLL_CALLCONV FreeImage_SetOutputMessageStdCall(FreeImage_OutputMessageFunctionStdCall omf);
+ attach_function('FreeImage_SetOutputMessage', 'FreeImage_SetOutputMessageStdCall', [:output_message_callback], :void)
+ else
+ #DLL_API void DLL_CALLCONV FreeImage_SetOutputMessage(FreeImage_OutputMessageFunction omf);
+ attach_function('FreeImage_SetOutputMessage', [:output_message_callback], :void)
+ end
+
+ class FreeImageError < StandardError
+ attr_reader :format
+
+ def initialize(format, message)
+ @format = format
+ super(message)
+ end
+
+# def to_s
+# "#{self.message} Format: #{self.format}"
+# end
+ end
+
+ CALLBACK = Proc.new do |format, ptr|
+ # Create an exception object and stash it away. We can't raise it here
+ # because FreeImage won't be able to clean up any resources it needs to.
+ # Instead, the calling code must call check_last_error.
+ message = ptr.get_string(0)
+ Thread.current[LAST_ERROR] = FreeImageError.new(format, message)
+ end
+ FreeImage_SetOutputMessage(CALLBACK)
+
+ def check_last_error
+ error = Thread.current[LAST_ERROR]
+ Thread.current[LAST_ERROR] = nil
+ raise(error) if error
+ end
+ module_function :check_last_error
+end
View
166 lib/free-image/modules/conversions.rb
@@ -0,0 +1,166 @@
+module FreeImage
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo4Bits(FIBITMAP *dib);
+ attach_function('FreeImage_ConvertTo4Bits', [:pointer], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo8Bits(FIBITMAP *dib);
+ attach_function('FreeImage_ConvertTo8Bits', [:pointer], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToGreyscale(FIBITMAP *dib);
+ attach_function('FreeImage_ConvertToGreyscale', [:pointer], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits555(FIBITMAP *dib);
+ attach_function('FreeImage_ConvertTo16Bits555', [:pointer], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo16Bits565(FIBITMAP *dib);
+ attach_function('FreeImage_ConvertTo16Bits565', [:pointer], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo24Bits(FIBITMAP *dib);
+ attach_function('FreeImage_ConvertTo24Bits', [:pointer], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertTo32Bits(FIBITMAP *dib);
+ attach_function('FreeImage_ConvertTo32Bits', [:pointer], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Dither(FIBITMAP *dib, FREE_IMAGE_DITHER algorithm);
+ attach_function('FreeImage_Dither', [:pointer, :dither], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Threshold(FIBITMAP *dib, BYTE T);
+ attach_function('FreeImage_Threshold', [:pointer, :byte], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear FI_DEFAULT(TRUE));
+ attach_function('FreeImage_ConvertToStandardType', [:pointer, FreeImage::Boolean], :pointer)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear FI_DEFAULT(TRUE));
+ attach_function('FreeImage_ConvertToType', [:pointer, :image_type, FreeImage::Boolean], :pointer)
+
+ module Conversions
+ # Converts a bitmap to 4 bits. If the bitmap is a high-color (16, 24 or 32-bit),
+ # monochrome or greyscale bitmap (1 or 8-bit) the end result will be a greyscale bitmap.
+ # A 1-bit bitmap will become a palletized bitmap.
+ #
+ # Note that "greyscale" means that the resulting bitmap will have grey colors,
+ # but the palette won't be a linear greyscale palette. Thus, FreeImage::Bitmap.color_type
+ # will return a :palette.
+ def convert_to_4bits
+ ptr = FreeImage.FreeImage_ConvertTo4Bits(self)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to 8 bits. If the bitmap is a high-color (16, 24 or 32-bit),
+ # monochrome or greyscale bitmap (1 or 4-bit) the end result will be a greyscale bitmap.
+ # A 1-bit or 4-bit bitmap will become a palletized bitmap.
+ #
+ # For 16-bit greyscale images (images whose type is :uint16), conversion is done by
+ # dividing the 16-bit channel by 256 (see also FreeImage::Bitmap.ConvertToStandardType).
+ # A nil value is returned for other non-standard bitmap types.
+ def convert_to_8bits
+ ptr = FreeImage.FreeImage_ConvertTo8Bits(self)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to a 8-bit greyscale image with a linear ramp. Contrary to
+ # the FreeImage::Conversions#convert_to_8bits function, 1-, 4- and 8-bit palletized
+ # bitmaps are correctly converted, as well as images with a :minis_white color type.
+ def convert_to_greyscale
+ ptr = FreeImage.FreeImage_ConvertToGreyscale(self)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to 16 bits, where each pixel has a color pattern of
+ # 5 bits red, 5 bits green and 5 bits blue. One bit in each pixel is
+ # unused.
+ def convert_to_16bits_555
+ ptr = FreeImage.FreeImage_ConvertTo16Bits555(self)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to 16 bits, where each pixel has a color pattern of
+ # 5 bits red, 6 bits green and 5 bits blue. One bit in each pixel is
+ # unused.
+ def convert_to_16bits_565
+ ptr = FreeImage.FreeImage_ConvertTo16Bits565(self)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to 24 bits. For 48-bit RGB images, conversion is done
+ # by dividing each 16-bit channel by 256. A nil value is returned for
+ # other non-standard bitmap types.
+ def convert_to_24bits
+ ptr = FreeImage.FreeImage_ConvertTo24Bits(self)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to 32 bits. For 48-bit RGB images, conversion is done
+ # by dividing each 16-bit channel by 256 and by setting the alpha channel
+ # to an opaque value (0xFF). For 64-bit RGBA images, conversion is done
+ # by dividing each 16-bit channel by 256. A nil value is returned for
+ # other non-standard bitmap types.
+ def convert_to_32bits
+ ptr = FreeImage.FreeImage_ConvertTo32Bits(self)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a non standard image whose color type is :minis_black to a
+ # standard 8-bit greyscale image. When the scale_linear parameter is
+ # true, conversion is done by scaling linearly each pixel value from [min, max]
+ # to an integer value between [0..255], where min and max are the minimum
+ # and maximum pixel values in the image. When scale_linear is false, conversion
+ # is done by rounding each pixel value to an integer between [0..255]. Rounding
+ # is done using the following formula:
+ #
+ # dst_pixel = (BYTE) MIN(255, MAX(0, q)) where int q = int(src_pixel + 0.5)
+ #
+ # For standard bitmaps, a clone of the original bitmap is returned.
+ # For complex images, the magnitude is extracted as a double image and then converted
+ # according to the scale parameter.
+ def convert_to_standard_type(scale_linear = true)
+ ptr = FreeImage.FreeImage_ConvertToStandardType(self, scale_linear)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to the specified destination image type. When the image_type
+ # is equal to :bitmap, the function calls FreeImage::Converstions#convert_to_standard_type.
+ # Otherwise, conversion is done using standard C language casting conventions. When
+ # a conversion is not allowed, a nil value is returned and an error is thrown.
+ # Please refer to the FreeImage documentation for allowed conversions.
+ def convert_to_type(dst_image_type, scale_linear = true)
+ ptr = FreeImage.FreeImage_ConvertToType(self, dst_image_type, scale_linear)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to 1-bit monochrome bitmap using the specified
+ # {dithering}[rdoc-ref:FreeImage.dithers] algorithm. For 1-bit input
+ # bitmaps, the function clones the input bitmap and builds a
+ # monochrome palette. Otherwise the function first converts the
+ # bitmap to a 8-bit greyscale bitmap.
+ def dither(algorithm)
+ ptr = FreeImage.FreeImage_Dither(self, algorithm)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Converts a bitmap to 1-bit monochrome bitmap using a threshold value
+ # between 0 and 255. The function first converts the bitmap to a 8-bit
+ # greyscale bitmap. Then any brightness level that is less than the
+ # threshold is set to zero and any value above is set to 1.
+ # For 1-bit input bitmaps, the function clones the input bitmap and
+ # builds a monochrome palette.
+ def threshold(value)
+ value = Integer(value)
+ unless (0..255).include?(value)
+ raise(RangeError, "Value is out of range 0..255. Value: #{value}")
+ end
+ ptr = FreeImage.FreeImage_Threshold(self, value)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+ end
+end
View
42 lib/free-image/modules/helper.rb
@@ -0,0 +1,42 @@
+module FreeImage
+ #DLL_API const char *DLL_CALLCONV FreeImage_GetVersion(void);
+ attach_function('FreeImage_GetVersion', [], :string)
+
+ #DLL_API const char *DLL_CALLCONV FreeImage_GetCopyrightMessage(void);
+ attach_function('FreeImage_GetCopyrightMessage', [], :string)
+
+ #DLL_API BOOL DLL_CALLCONV FreeImage_IsLittleEndian(void);
+ attach_function('FreeImage_IsLittleEndian', [], FreeImage::Boolean)
+
+ ##
+ # :call-seq:
+ # version -> string
+ #
+ # Returns the current version of the FreeImage library
+ #
+ def self.version
+ FreeImage.FreeImage_GetVersion
+ end
+
+ ##
+ # :call-seq:
+ # copyright -> string
+ #
+ # Returns a standard copyright message you can show in your program.
+ #
+ def self.copyright
+ FreeImage.FreeImage_GetCopyrightMessage
+ end
+
+ ##
+ # :call-seq:
+ # is_little_endian? -> boolean
+ #
+ # Returns TRUE if the platform running FreeImage uses the Little Endian
+ # convention (Intel processors) and returns FALSE if it uses the Big Endian
+ # (Motorola processors).
+ #
+ def self.little_endian?
+ FreeImage.FreeImage_IsLittleEndian
+ end
+end
View
41 lib/free-image/modules/icc.rb
@@ -0,0 +1,41 @@
+module FreeImage
+ # DLL_API BOOL DLL_CALLCONV FreeImage_FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif)
+ attach_function(:icc_supported, 'FreeImage_FIFSupportsICCProfiles', [:format], FreeImage::Boolean)
+ module_function :icc_supported
+
+ module ICC
+ class Profile < FFI::Struct
+ layout :flags, :int,
+ :size, :uint,
+ :data, :pointer
+ end
+
+ # DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_GetICCProfile(FIBITMAP *dib)
+ FreeImage.attach_function('FreeImage_GetICCProfile', [:pointer], FreeImage::ICC::Profile)
+
+ def icc_profile
+ result = FreeImage.FreeImage_GetICCProfile(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # DLL_API FIICCPROFILE *DLL_CALLCONV FreeImage_CreateICCProfile(FIBITMAP *dib, void *data, long size);
+ FreeImage.attach_function('FreeImage_CreateICCProfile', [:pointer, :pointer, :long], FreeImage::ICC::Profile)
+ # DLL_API void DLL_CALLCONV FreeImage_DestroyICCProfile(FIBITMAP *dib);
+ FreeImage.attach_function('FreeImage_DestroyICCProfile', [:pointer], :void)
+
+ def icc_profile=(value)
+ result = if value
+ FreeImage.FreeImage_CreateICCProfile(self, value[:data], value[:size])
+ else
+ FreeImage.FreeImage_DestroyICCProfile(self)
+ end
+ FreeImage.check_last_error
+ result
+ end
+
+ def icc_supported?
+ FreeImage.icc_supported(self)
+ end
+ end
+end
View
305 lib/free-image/modules/information.rb
@@ -0,0 +1,305 @@
+module FreeImage
+ #DLL_API BOOL DLL_CALLCONV FreeImage_HasPixels(FIBITMAP *dib);
+ attach_function('FreeImage_HasPixels', [:pointer], FreeImage::Boolean)
+
+ #DLL_API FREE_IMAGE_TYPE DLL_CALLCONV FreeImage_GetImageType(FIBITMAP *dib)
+ attach_function('FreeImage_GetImageType', [:pointer], :image_type)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetHeight(FIBITMAP *dib);
+ attach_function('FreeImage_GetHeight', [:pointer], :uint)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetWidth(FIBITMAP *dib);
+ attach_function('FreeImage_GetWidth', [:pointer], :uint)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetBPP(FIBITMAP *dib);
+ attach_function('FreeImage_GetBPP', [:pointer], :ulong)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetLine(FIBITMAP *dib);
+ attach_function('FreeImage_GetLine', [:pointer], :ulong)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetPitch(FIBITMAP *dib);
+ attach_function('FreeImage_GetPitch', [:pointer], :ulong)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetDIBSize(FIBITMAP *dib);
+ attach_function('FreeImage_GetDIBSize', [:pointer], :ulong)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterX(FIBITMAP *dib);
+ attach_function('FreeImage_GetDotsPerMeterX', [:pointer], :ulong)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetDotsPerMeterY(FIBITMAP *dib);
+ attach_function('FreeImage_GetDotsPerMeterY', [:pointer], :ulong)
+
+ #DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterX(FIBITMAP *dib, unsigned res);
+ attach_function('FreeImage_SetDotsPerMeterX', [:pointer, :ulong], :void)
+
+ #DLL_API void DLL_CALLCONV FreeImage_SetDotsPerMeterY(FIBITMAP *dib, unsigned res);
+ attach_function('FreeImage_SetDotsPerMeterY', [:pointer, :ulong], :void)
+
+ #DLL_API FREE_IMAGE_COLOR_TYPE DLL_CALLCONV FreeImage_GetColorType(FIBITMAP *dib);
+ attach_function('FreeImage_GetColorType', [:pointer], :color_type)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetBlueMask(FIBITMAP *dib);
+ attach_function('FreeImage_GetBlueMask', [:pointer], :ulong)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetRedMask(FIBITMAP *dib);
+ attach_function('FreeImage_GetRedMask', [:pointer], :ulong)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetGreenMask(FIBITMAP *dib);
+ attach_function('FreeImage_GetGreenMask', [:pointer], :ulong)
+
+ #DLL_API unsigned DLL_CALLCONV FreeImage_GetTransparencyCount(FIBITMAP *dib);
+ attach_function('FreeImage_GetTransparencyCount', [:pointer], :ulong)
+
+ #DLL_API void DLL_CALLCONV FreeImage_SetTransparent(FIBITMAP *dib, BOOL enabled);
+ attach_function('FreeImage_SetTransparent', [:pointer, FreeImage::Boolean], :void)
+
+ #DLL_API BOOL DLL_CALLCONV FreeImage_IsTransparent(FIBITMAP *dib);
+ attach_function('FreeImage_IsTransparent', [:pointer], FreeImage::Boolean)
+
+ #DLL_API void DLL_CALLCONV FreeImage_SetTransparentIndex(FIBITMAP *dib, int index);
+ attach_function('FreeImage_SetTransparentIndex', [:pointer, :int], :void)
+
+ #DLL_API int DLL_CALLCONV FreeImage_GetTransparentIndex(FIBITMAP *dib);
+ attach_function('FreeImage_GetTransparentIndex', [:pointer], :int)
+
+ #DLL_API BOOL DLL_CALLCONV FreeImage_HasBackgroundColor(FIBITMAP *dib);
+ attach_function('FreeImage_HasBackgroundColor', [:pointer], FreeImage::Boolean)
+
+ #DLL_API BOOL DLL_CALLCONV FreeImage_GetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor);
+ attach_function('FreeImage_GetBackgroundColor', [:pointer, :pointer], FreeImage::Boolean)
+
+ # DLL_API BOOL DLL_CALLCONV FreeImage_SetBackgroundColor(FIBITMAP *dib, RGBQUAD *bkcolor);
+ attach_function('FreeImage_SetBackgroundColor', [:pointer, :pointer], FreeImage::Boolean)
+
+ # Once a bitmap is loaded into memory, you can use the following methods to
+ # retrieve information about is type, dimensions, colors, etc.
+ module Information
+
+ # Returns the background color of a bitmap. For 8-bit images, the color index
+ # in the palette is returned in the rgbReserved member of the bkcolor parameter.
+ def background_color
+ ptr = FFI::MemoryPointer.new(:pointer)
+ FreeImage.FreeImage_GetBackgroundColor(self, ptr)
+ FreeImage.check_last_error
+ RGBQuad.new(ptr)
+ end
+
+ # Set the background color of a bitmap. The color should be an instance
+ # of RGBQuad.
+ #
+ # When saving an image to PNG, this background
+ # color is transparently saved to the PNG file. When the bkcolor parameter is nil,
+ # the background color is removed from the image.
+ def background_color=(value)
+ result = FreeImage.FreeImage_GetBackgroundColor(self, value)
+ FreeImage.check_last_error
+ if !result
+ raise(RuntimeError, "Could not save background color")
+ end
+ end
+
+ # Returns the size of one pixel in the bitmap in bits. For example if each
+ # pixel takes 32-bits of space in the bitmap, this function returns 32.
+ # Possible bit depths are 1, 4, 8, 16, 24, 32 for standard bitmaps and
+ # 16-, 32-, 48-, 64-, 96- and 128-bit for non standard bitmaps
+ def bits_per_pixel
+ result = FreeImage.FreeImage_GetBPP(self)
+ FreeImage.check_last_error
+ result
+ end
+ alias :bpp :bits_per_pixel
+
+ # Returns a bit pattern describing the blue color component of a pixel in a bitmap.
+ def blue_mask
+ result = FreeImage.FreeImage_GetBlueMask(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ def color_type
+ result = FreeImage.FreeImage_GetColorType(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns the size of the DIB-element of a bitmap in memory, which is the
+ # header size + palette size + data bits. Note that this is not the real
+ # size of a bitmap, just the size of its DIB-element.
+ def dib_size
+ result = FreeImage.FreeImage_GetDIBSize(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns the horizontal resolution, in pixels-per-meter,
+ # of the target device for the bitmap.
+ def dots_per_meter_x
+ result = FreeImage.FreeImage_GetDotsPerMeterX(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Sets the horizontal resolution, in pixels-per-meter,
+ # of the target device for the bitmap.
+ def dots_per_meter_x=(value)
+ result = FreeImage.FreeImage_SetDotsPerMeterX(self, value)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns the vertical resolution, in pixels-per-meter,
+ # of the target device for the bitmap.
+ def dots_per_meter_y
+ result = FreeImage.FreeImage_GetDotsPerMeterY(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Sets the vertical resolution, in pixels-per-meter,
+ # of the target device for the bitmap.
+ def dots_per_meter_y=(value)
+ result = FreeImage.FreeImage_SetDotsPerMeterY(self, value)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns a bit pattern describing the green color component of a pixel in a bitmap.
+ def green_mask
+ result = FreeImage.FreeImage_GetGreenMask(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns true when the image has a file background color, false otherwise
+ def has_background_color
+ result = FreeImage.FreeImage_HasBackgroundColor(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns true if the bitmap contains pixel data, otherwise false. Bitmaps
+ # can be loaded using the FIF_LOAD_NOPIXELS load flag whic tells the decoder
+ # to read header data and available metadata and skip pixel data decoding.
+ # This reduces memory usage and load speed.
+ def has_pixels
+ result = FreeImage.FreeImage_HasPixels(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns the height of the bitmap in pixel units
+ def height
+ result = FreeImage.FreeImage_GetHeight(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns the {image type}[rdoc-ref:FreeImage.image_types] of a bitmap.
+ def image_type
+ result = FreeImage.FreeImage_GetImageType(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns the width of the bitmap in bytes. See also FreeImage::Information.pitch.
+ # There has been some criticism on the name of this function. Some people expect it to
+ # return a scanline in the pixel data, while it actually returns the width of the bitmap in
+ # bytes. As far as I know the term Line is common terminology for the width of a bitmap
+ # in bytes. It is at least used by Microsoft DirectX.
+ def line
+ result = FreeImage.FreeImage_GetLine(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns a bitmap's palette. If the bitmap doesn’t have a palette (i.e. when the
+ # pixel bit depth is greater than 8), this return nil.
+ def palette
+ @palette ||= Palette.new(self)
+ end
+
+ # Returns the width of the bitmap in bytes, rounded to the next 32-bit boundary,
+ # also known as pitch or stride or scan width.
+ # In FreeImage each scanline starts at a 32-bit boundary for performance reasons.
+ # This accessor is essential when using low level {pixel manipulation}[rdoc-ref:FreeImage::Pixels]
+ # functions.
+ def pitch
+ result = FreeImage.FreeImage_GetPitch(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns a bit pattern describing the red color component of a pixel in a bitmap.
+ def red_mask
+ result = FreeImage.FreeImage_GetRedMask(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns the number of transparent colors in a palletized bitmap,
+ # otherwise returns 0.
+ def transparency_count
+ result = FreeImage.FreeImage_GetTransparencyCount(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns true if the transparency table is enabled (1-, 4- or 8-bit images) or
+ # when the input dib contains alpha values (32-bit images, RGBA16 or RGBAF images).
+ # Returns false otherwise.
+ def transparent
+ result = FreeImage.FreeImage_IsTransparent(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Tells FreeImage if it should make use of the transparency table or the alpha
+ # channel that may accompany a bitmap. When calling this function with a
+ # bitmap whose bitdepth is different from 1-, 4-, 8- or 32-bit, transparency
+ # is disabled whatever the value of the Boolean parameter.
+ def transparent=(value)
+ result = FreeImage.FreeImage_SetTransparent(self, value)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Returns the palette entry used as transparent color for the image specified.
+ # Works for palletised images only and returns -1 for high color images or
+ # if the image has no color set to be transparent.
+ # Although it is possible for palletised images to have more than one transparent
+ # color, this function always returns the index of the first palette entry,
+ # set to be transparent.
+ def transparent_index
+ result = FreeImage.FreeImage_GetTransparentIndex(self)
+ FreeImage.check_last_error
+ result
+ end
+
+ # Sets the index of the palette entry to be used as transparent color for
+ # the image specified. This works on palletised images only and does nothing
+ # for high color images.
+ #
+ # Although it is possible for palletised images to have more than one transparent
+ # color, this method sets the palette entry specified as the single transparent
+ # color for the image. All other colors will be set to be non-transparent by this method.
+ #
+ # As with FreeImage::Bitmap.transparency_table=, this method also sets the
+ # image's transparency property to true for palletised images.
+ def transparent_index=(value)
+ result = FreeImage.FreeImage_SetTransparentIndex(self, value)
+ FreeImage.check_last_error
+ result
+ end
+
+# #DLL_API BOOL DLL_CALLCONV FreeImage_HasBackgroundColor(FIBITMAP *dib);
+# attach_function('FreeImage_HasBackgroundColor', [:pointer], FreeImage::Boolean)
+#
+
+ # Returns the width of the bitmap in pixel units
+ def width
+ result = FreeImage.FreeImage_GetWidth(self)
+ FreeImage.check_last_error
+ result
+ end
+ end
+end
View
261 lib/free-image/modules/modify.rb
@@ -0,0 +1,261 @@
+module FreeImage
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Copy(FIBITMAP *dib, int left, int top, int right, int bottom);
+ attach_function('FreeImage_Copy', [:pointer, :int, :int, :int, :int], :pointer)
+
+ #DLL_API BOOL DLL_CALLCONV FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha);
+ attach_function('FreeImage_Paste', [:pointer, :pointer, :int, :int, :int], FreeImage::Boolean)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Composite(FIBITMAP *fg, BOOL useFileBkg FI_DEFAULT(FALSE), RGBQUAD *appBkColor FI_DEFAULT(NULL), FIBITMAP *bg FI_DEFAULT(NULL));
+ attach_function('FreeImage_Composite', [:pointer, FreeImage::Boolean, FreeImage::RGBQuad, :pointer], :pointer)
+
+ #DLL_API BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib);
+ #attach_function('FreeImage_PreMultiplyWithAlpha', [:pointer, :int, :int, :int, :int], FreeImage::Boolean)
+
+ # DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rescale(FIBITMAP *dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
+ attach_function('FreeImage_Rescale', [:pointer, :int, :int, :filter], :pointer)
+
+ # DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert FI_DEFAULT(TRUE));
+ attach_function('FreeImage_MakeThumbnail', [:pointer, :int, FreeImage::Boolean], :pointer)
+
+ #DLL_API BOOL DLL_CALLCONV FreeImage_FillBackground(FIBITMAP *dib, const void *color, int options FI_DEFAULT(0));
+ attach_function('FreeImage_FillBackground', [:pointer, :pointer, :int], FreeImage::Boolean)
+
+ #DLL_API FIBITMAP *DLL_CALLCONV FreeImage_EnlargeCanvas(FIBITMAP *src, int left, int top, int right, int bottom, const void *color, int options FI_DEFAULT(0));
+ attach_function('FreeImage_EnlargeCanvas', [:pointer, :int, :int, :int, :int, :pointer, :int], :pointer)
+
+ # Background Filling Options
+
+ # RGBQUAD color is a RGB color (contains no valid alpha channel)
+ COLOR_IS_RGB_COLOR = 0x00
+
+ # RGBQUAD color is a RGBA color (contains a valid alpha channel)
+ COLOR_IS_RGBA_COLOR = 0x01
+
+ # For palettized images: lookup equal RGB color from palette
+ COLOR_FIND_EQUAL_COLOR = 0x02
+
+ # The color's rgbReserved member (alpha) contains the palette index to be used
+ COLOR_ALPHA_IS_INDEX = 0x04
+
+ # No color lookup is performed
+ COLOR_PALETTE_SEARCH_MASK = (COLOR_FIND_EQUAL_COLOR | COLOR_ALPHA_IS_INDEX)
+
+ # The \Modify module provides methods that can copy, paste, composite,
+ # and enlarge images. It also allows the creation of thumbnails and
+ # filling background colors.
+ #
+ module Modify
+ # Composites a transparent foreground image against a background image.
+ # The equation for computing a composited sample value is:
+ #
+ # output = alpha * foreground + (1-alpha) * background
+ #
+ # Where alpha and the input and output sample values are expressed as fractions
+ # in the range 0 to 1. For color images, the computation is done separately
+ # for R, G, and B samples.
+ def composite(background_bitmap)
+ ptr = FreeImage.FreeImage_Composite(self, false, nil, background_bitmap)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Composites a transparent foreground image against a background color.
+ # The equation for computing a composited sample value is:
+ #
+ # output = alpha * foreground + (1-alpha) * background
+ #
+ # Where alpha and the input and output sample values are expressed as fractions
+ # in the range 0 to 1. For color images, the computation is done separately
+ # for R, G, and B samples.
+ def composite_with_color(background_color)
+ ptr = FreeImage.FreeImage_Composite(self, false, background_color, nil)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Copy a subpart of the current image. The rectangle defined by the
+ # left, top, right, bottom parameters is first normalized such that the
+ # value of the left coordinate is less than the right and the top is less
+ # than the bottom. Then, the returned bitmap is defined by a width equal to
+ # (right - left) and a height equal to (bottom - top).
+ #
+ # The function returns the subimage if successful and returns nil otherwise.
+ def copy(left, top, right, bottom)
+ ptr = FreeImage.FreeImage_Copy(self, left, top, right, bottom)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Enlarges or shrinks an image selectively per side and fills newly added areas with the
+ # specified background color. The common use case is to add borders to an image.
+ #
+ # To add a border to any of the image's sides, a positive integer value must be passed in
+ # any of the parameters left, top, right or bottom. This value represents the border's
+ # width in pixels. Newly created parts of the image (the border areas)
+ # are filled with the specified color.
+ #
+ # Specifying a negative integer value for a certain side, will shrink or crop the image on
+ # this side. Consequently, specifying zero for a certain side will not
+ # change the image's extension on that side.
+ #
+ # For palletized images, the palette of the current image src is transparently
+ # copied to the newly created enlarged or shrunken image, so any color look-ups
+ # are performed on this palette.
+ #
+ # == Parameters:
+ #
+ # left:: The number of pixels the image should be enlarged on its left side. Negative
+ # values shrink the image on its left side.
+ # top:: The number of pixels the image should be enlarged on its top side. Negative
+ # values shrink the image on its top side.
+ # right:: The number of pixels the image should be enlarged on its right side. Negative
+ # values shrink the image on its right side.
+ # bottom:: The number of pixels, the image should be enlarged on its bottom side.
+ # Negative values shrink the image on its bottom side.
+ # color:: The color value to be used for filling the image. See #fill_background for
+ # more details.
+ # options:: Used to control color search process for palletized images. See
+ # #fill_background for more details.
+ #
+ # Returns a new image on success or nil.
+ #
+ def enlarge_canvas(left, top, right, bottom, color, options = 0)
+ ptr = FreeImage.FreeImage_EnlargeCanvas(self, left, top, right, bottom, color, options)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Sets all pixels of an image to the specified color.
+ #
+ # == Parameters:
+ #
+ # color:: The color value to be used for filling the image.
+ #
+ # The type of the color parameter depends on the
+ # {image type}[rdoc-ref:FreeImage.image_types]
+ #
+ # bitmap:: RGBQuad
+ # rgb16:: RGB16
+ # rgba16:: RGBA16
+ # rgbf:: RGBF
+ # rgbaf:: RGBFA
+ # complex:: Complex
+ # others:: A value of the specific type (double, int, etc.).
+ #
+ # options:: Used to control color search process for palletized images.
+ # Allowed values are defined as constants on the FreeImage
+ # module and include:
+ # COLOR_IS_RGB_COLOR = 0x00
+ # COLOR_IS_RGBA_COLOR = 0x01
+ # COLOR_FIND_EQUAL_COLOR = 0x02
+ # COLOR_ALPHA_IS_INDEX = 0x04
+ # COLOR_PALETTE_SEARCH_MASK = (FI_COLOR_FIND_EQUAL_COLOR | FI_COLOR_ALPHA_IS_INDEX)
+ #
+ # Returns true on success, false on failure.
+ #
+ def fill_background!(color, options = 0)
+ result = FreeImage.FreeImage_FillBackground(self, color, options)
+ FreeImage.check_last_error
+ result
+ end
+
+ # :call-seq:
+ # bitmap.make_thumbnail(max_pixel_size, convert = true) -> bitmap
+ #
+ # Creates a thumbnail image that fits inside a square of size max_pixel_size,
+ # keeping the original aspect ratio intact. Downsampling is done using a bilinear
+ # {filter}[rdoc-ref:FreeImage::Sampling.rescale].
+ #
+ # == Parameters:
+ #
+ # max_pixel_size:: The maximum width/height of the returned image
+ # convert:: When set to true, High Dynamic Range images (FIT_UINT16,
+ # FIT_RGB16, FIT_RGBA16, FIT_FLOAT) are transparently converted
+ # to standard images (i.e. 8-, 24 or 32-bit images). The
+ # default value is true.
+ #
+ def make_thumbnail(max_pixel_size, convert = true)
+ ptr = FreeImage.FreeImage_MakeThumbnail(self, max_pixel_size, convert)
+ FreeImage.check_last_error
+ self.class.new(ptr)
+ end
+
+ # Combines or blends a subpart of another image with the current image.
+ #
+ # == Parameters:
+ #
+ # other:: Source subimage
+ # left:: Specifies the left position of the sub image.
+ # top:: Specifies the top position of the sub image.
+ # alpha:: Alpha blend factor. If alpha is 0..255, the other images is
+ # alpha blended withe current image. If alpha > 255, then
+ # the other image is combined to the current image.
+ #
+ # The function returns true if successful, otherwise false.
+ #
+ def paste!(other, left, top, alpha)
+ result = FreeImage.FreeImage_Paste(self, other, left, top, alpha)
+ FreeImage.check_last_error
+ result
+ end
+
+ # :call-seq:
+ # bitmap.rescale(width, height, filter) -> bitmap
+ #
+ # Resamples an image to the desired width and height. Resampling changes the
+ # pixel dimensions (and therefore display size) of an image.
+ # When you downsample (or decrease the number of pixels), information is deleted from
+ # the image. When you upsample (or increase the number of pixels), new pixels are
+ # added based on color values of existing pixels. You can specify an interpolation
+ # filter to determine how pixels are added or deleted using the filter parameter.
+ #
+ # Returns the newly resample image or nil if the image cannot be resampled.
+ #
+ # == Parameters:
+ #
+ # width:: The width of the new image
+ # height:: The height of the new image
+ # filter:: The filter to use when rescaling
+ #
+ # Filter options include:
+ #
+ # :box:: The simplest and fastest of the scaling algorithms. The technique achieves
+ # magnification by pixel replication, and minification by sparse point sampling.
+ # For large-scale changes, box interpolation produces images with a
+ # blocky appearance. In addition, shift errors of up to one-half pixel are
+ # possible. These problems make this technique inappropriate when
+ # sub-pixel accuracy is required.
+ #
+ # :bicubic:: An advanced parameterized scaling filter. It uses a cubic
+ # to produce very smooth output while maintaining dynamic range
+ # and sharpness. Bicubic scaling takes approximately twice the
+ # processing time as Bilinear. This filter can be used for any
+ # scaling application, especially when scaling factors are 2X
+ # or greater.
+ #
+ # :bilinear:: The second-fastest scaling function. It employs linear interpolation
+ # to determine the output image. Bilinear scaling provides reasonably
+ # good results at moderate cost for most applications where scale
+ # factors are relatively small (4X or less).
+ #
+ # :bspline:: Produces the smoothest output, but tends to smooth over fine details.
+ # This function requires the same processing time as :bicubic filter.
+ # It is recommended for applications where the smoothest output is required.
+ #
+ # :catmullrom:: The Catmull-Rom filter is generally accepted as the best cubic interpolant filter.
+ #
+ # :lanczos3:: A sinc based filter. It is the most theoretically correct filter
+ # that produces the best output for photographic images that do not have