|
From: Foster B. <fos...@us...> - 2006-02-27 20:42:13
|
Update of /cvsroot/adobe-source/sandbox/adobe-source/adobe/gil/extension/io In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8667/adobe/gil/extension/io Added Files: io_factory.hpp targa.hpp Log Message: image_t (icons and pictures) support for Mac and Win32, along with a GIL image factory and a (sample) Targa file format importing module for that factory. Also added alert.adm/eve as a sample for the icon support. Added the notion of a working directory to the modal dialog interface to reference external resources. Also added an alert API that leverages modal_dialog_interface. Other misc. bug fixes and changes. --- NEW FILE: io_factory.hpp --- /* Copyright 2005-2006 Adobe Systems Incorporated Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt or a copy at http://opensource.adobe.com/licenses.html) */ /*************************************************************************************************/ #ifndef ADOBE_GIL_EXTENSION_IO_FACTORY_HPP #define ADOBE_GIL_EXTENSION_IO_FACTORY_HPP /*************************************************************************************************/ #include <adobe/gil/extension/conceptspace/any_standard_image.hpp> #include <adobe/gil/core/image_view_factory.hpp> #include <adobe/gil/core/color_convert.hpp> #include <adobe/gil/core/algorithm.hpp> #include <adobe/gil/core/variant.hpp> #include <adobe/regular_object.hpp> #include <adobe/algorithm.hpp> #include <adobe/dictionary.hpp> #include <vector> #include <iostream> #include <cassert> /*************************************************************************************************/ ADOBE_GIL_NAMESPACE_BEGIN /*************************************************************************************************/ /*! image_io_dispatch is a struct that, by default, will call the procs in your class by the same name as they appear in the image_io GIL extension. If your class uses different names for detection, reading and writing, you'll want to write a specialization of this struct for your class that calls the right functions for the operations. */ template <typename T, typename ViewType> struct image_io_dispatch { typedef T value_type; typedef ViewType view_type; typedef GIL::image<view_type> image_type; inline bool detect(const value_type& value, std::streambuf& stream_buffer) const { return value.detect(stream_buffer); } inline void read(const value_type& value, image_type& image, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const { value.read(image, stream_buffer, parameters); } inline void write(const value_type& value, const view_type& image_view, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const { value.write(image_view, stream_buffer, parameters); } }; /*************************************************************************************************/ template <typename ViewType> class image_factory_t; /*************************************************************************************************/ /*! image_format_t is the regular_object wrapper for the file format io interface to a given format */ template <typename ViewType> class image_format_t { typedef ViewType view_type; typedef GIL::image<view_type> image_type; struct interface { virtual ~interface() { } virtual bool detect(std::streambuf& stream_buffer) const = 0; virtual void read(image_type& image, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const = 0; virtual void write(const view_type& image_view, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const = 0; }; template <typename T> // T models ImageFileIOType struct instance : adobe::regular_interface<interface> { typedef T value_type; instance(const value_type& x) : value(x) { } bool detect(std::streambuf& stream_buffer) const { return image_io_dispatch<value_type, view_type>().detect(value, stream_buffer); } void read(image_type& image, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const { image_io_dispatch<value_type, view_type>().read(value, image, stream_buffer, parameters); } void write(const view_type& image_view, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const { image_io_dispatch<value_type, view_type>().write(value, image_view, stream_buffer, parameters); } T value; }; public: template <typename T> // T models ImageFileIOType image_format_t(adobe::name_t tag, const T& f) : tag_m(tag), object_m(f) { } bool detect(std::streambuf& stream_buffer) const { return object_m->detect(stream_buffer); } adobe::name_t read(image_type& image, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const { object_m->read(image, stream_buffer, parameters); return tag(); } void write(const view_type& image_view, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const { object_m->write(image_view, stream_buffer, parameters); } adobe::name_t tag() const { return tag_m; } friend inline bool operator==(const image_format_t& x, const image_format_t& y) { return x.tag_m == y.tag_m; } private: adobe::name_t tag_m; adobe::regular_object<interface, instance> object_m; friend class image_factory_t<view_type>; }; /*************************************************************************************************/ template <typename ViewType> class image_factory_t { public: typedef ViewType view_type; typedef GIL::image<view_type> image_type; typedef image_format_t<view_type> image_format_type; typedef std::vector<image_format_type> format_set_t; typedef typename format_set_t::value_type value_type; typedef typename format_set_t::iterator iterator; typedef typename format_set_t::const_iterator const_iterator; template <typename O> O detect_all_for(std::streambuf& stream_buffer, O output) const { for (const_iterator first(format_set_m.begin()), last(format_set_m.end()); first != last; ++first) { if (first->detect(stream_buffer)) *output++ = first->tag(); } return output; } adobe::name_t read(image_type& image, std::streambuf& stream_buffer, adobe::name_t format_tag = adobe::name_t(), adobe::dictionary_t parameters = adobe::dictionary_t()) { return format_tag == adobe::name_t() ? detect_first_for(stream_buffer).read(image, stream_buffer, parameters) : find(format_tag)->read(image, stream_buffer, parameters); } void write(const view_type& image_view, std::streambuf& stream_buffer, adobe::name_t format_tag = adobe::name_t(), adobe::dictionary_t parameters = adobe::dictionary_t()) { format_tag == adobe::name_t() ? detect_first_for(stream_buffer).write(image_view, stream_buffer, parameters) : find(format_tag)->write(image_view, stream_buffer, parameters); } void register_format(const image_format_type& format) { format_set_m.push_back(format); } bool is_registered(adobe::name_t format_tag) { try { find(format_tag); } catch (...) { return false; } return true; } void unregister_format(adobe::name_t format_tag) { format_set_m.erase(find(format_tag)); } private: inline iterator find(adobe::name_t format_tag) { iterator result(adobe::find_if(format_set_m, boost::bind(adobe::compare_members(&value_type::tag_m, std::equal_to<adobe::name_t>()), format_tag, _1))); if (result == format_set_m.end()) throw std::runtime_error("gil: image_io: format not found"); return result; } value_type& detect_first_for(std::streambuf& stream_buffer) { iterator result(adobe::find_if(format_set_m, boost::bind(&value_type::detect, _1, boost::ref(stream_buffer)))); if (result == format_set_m.end()) throw std::runtime_error("gil: image_io: format not detected"); return *result; } format_set_t format_set_m; }; /*************************************************************************************************/ ADOBE_GIL_NAMESPACE_END /*************************************************************************************************/ #endif /*************************************************************************************************/ --- NEW FILE: targa.hpp --- /* Copyright 2005-2006 Adobe Systems Incorporated Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt or a copy at http://opensource.adobe.com/licenses.html) */ /*************************************************************************************************/ #ifndef ADOBE_GIL_EXTENSION_IMAGE_IO_TARGA_HPP #define ADOBE_GIL_EXTENSION_IMAGE_IO_TARGA_HPP /*************************************************************************************************/ #include <adobe/gil/core/image_view_factory.hpp> #include <adobe/gil/core/color_convert.hpp> #include <adobe/gil/core/algorithm.hpp> #include <adobe/gil/core/variant.hpp> #include <adobe/gil/extension/argb/argb.hpp> #include <adobe/dictionary.hpp> #include <adobe/future/endian.hpp> #include <boost/cstdint.hpp> #include <stdexcept> /*************************************************************************************************/ ADOBE_GIL_NAMESPACE_BEGIN /*************************************************************************************************/ namespace detail { /*************************************************************************************************/ template <typename T1, typename T2> struct _color_converter<T1, rgb_tag, T2, rgba_tag> { template <typename P1, typename P2> void operator()(const P1& src, P2& dst) { dst.a=-1; dst.r=src.r; dst.g=src.g; dst.b=src.b; } }; /*************************************************************************************************/ } // namespace detail /*************************************************************************************************/ namespace implementation { /*************************************************************************************************/ struct targa_header_t { boost::uint8_t id_length_m; boost::uint8_t color_map_type_m; boost::uint8_t image_type_m; boost::uint16_t color_map_start_m; boost::uint16_t color_map_length_m; boost::uint8_t color_map_depth_m; boost::uint16_t x_offset_m; boost::uint16_t y_offset_m; boost::uint16_t width_m; boost::uint16_t height_m; boost::uint8_t pixel_depth_m; boost::uint8_t image_descriptor_m; }; /*************************************************************************************************/ enum targa_image_data_type { data_type_none_s = 0, data_type_colormapped_s = 1, data_type_truecolor_s = 2, data_type_monochrome_s = 3, data_type_colormapped_rle_s = 9, data_type_truecolor_rle_s = 10, data_type_monochrome_rle_s = 11 }; /*************************************************************************************************/ template <adobe::endian::type StreamEndian> struct streambuf_swizzler { enum { endian = StreamEndian }; explicit streambuf_swizzler(std::streambuf& buffer) : buf_m(buffer) { } template <typename T> void operator()(T& x) { enum { size = sizeof(T) }; if (buf_m.sgetn(reinterpret_cast<char*>(&x), size) != size) throw std::runtime_error("streambuf_swizzler read error"); adobe::endian_swap<StreamEndian>()(x); } template <typename T> void operator()(T* first, T* last) { enum { size = sizeof(T) }; std::streamsize total_size(static_cast<std::streamsize>(std::distance(first, last) * size)); if (buf_m.sgetn(reinterpret_cast<char*>(first), total_size) != total_size) throw std::runtime_error("streambuf_swizzler read error"); for (; first != last; ++first) adobe::endian_swap<StreamEndian>()(*first); } std::streambuf& buf_m; }; /****************************************************************************************************/ static void targa_read_header(std::streambuf& stream_buffer, targa_header_t& dst) { streambuf_swizzler<adobe::endian::little> reader(stream_buffer); // We read in the header chunks one contiguous type set at // a time to work around padding that may be introduced between // the different types to achieve word alignment. //reader(dst.id_length_m); //reader(dst.color_map_type_m); //reader(dst.image_type_m); reader(&dst.id_length_m, &dst.image_type_m + 1); //reader(dst.color_map_start_m); //reader(dst.color_map_length_m); reader(&dst.color_map_start_m, &dst.color_map_length_m + 1); reader(dst.color_map_depth_m); //reader(dst.x_offset_m); //reader(dst.y_offset_m); //reader(dst.width_m); //reader(dst.height_m); reader(&dst.x_offset_m, &dst.height_m + 1); //reader(dst.pixel_depth_m); //reader(dst.image_descriptor_m); reader(&dst.pixel_depth_m, &dst.image_descriptor_m + 1); } /*************************************************************************************************/ template <typename V, adobe::endian::type SourceEndian> void read_rle_pixels(GIL::image<V>& img, streambuf_swizzler<SourceEndian>& stream) { typedef typename GIL::image<V>::value_type value_type; typedef typename GIL::image<V>::iterator iterator; unsigned char rle_header; value_type rle_color; iterator first(img.begin()); iterator last(img.end()); while (first != last) { std::size_t num_pixels(0); stream(rle_header); if (rle_header & char(0x80)) // rle compressed data flag check { num_pixels = (rle_header & 0x7f) + 1; stream(rle_color); for (std::size_t i(0); i < num_pixels; ++i) { *first = rle_color; ++first; } } else // raw data { num_pixels = (rle_header + 1); std::vector<value_type> slurp(num_pixels); stream(&slurp[0], &slurp[0] + slurp.size()); first = std::transform(&slurp[0], &slurp[0] + slurp.size(), first, GIL::color_converter<value_type>()); } } } /*************************************************************************************************/ template <typename SourcePixelType, typename V, adobe::endian::type SourceEndian> void stuff_image(GIL::image<V>& img, streambuf_swizzler<SourceEndian>& stream, bool rle_compression) { typedef SourcePixelType* src_ptr; typedef GIL::pixel_xy_locator<GIL::pixel_step_iterator<src_ptr> > src_loc; typedef GIL::image_view<src_loc> src_view; typedef GIL::image<src_view, std::allocator<unsigned char> > src_image; typedef typename src_image::iterator src_iterator; typedef typename V::value_type dst_value_type; src_image src; GIL::resize_clobber_image(src, img.width(), img.height()); if (rle_compression) read_rle_pixels(src, stream); else { // REVISIT (fbrereto) : boost::bind me src_iterator src_first(src.begin()); src_iterator src_last(src.end()); for (; src_first != src_last; ++src_first) stream(*src_first); } std::transform(src.begin(), src.end(), img.begin(), GIL::color_converter<dst_value_type>()); } /*************************************************************************************************/ } // namespace implementation /*************************************************************************************************/ template <typename ViewType> class targa_t { private: typedef ViewType view_type; typedef GIL::image<view_type> image_type; public: bool detect(std::streambuf& stream_buffer) const; void read(image_type& img, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const; void write(const view_type& img_view, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const; friend inline bool operator==(const targa_t& x, const targa_t& y) { return true; } }; /*************************************************************************************************/ template <typename ConceptSpace> // REVISIT (fbrereto) : Maybe needs to be a ConceptSpaceView? class targa_variant_t { public: bool detect(std::streambuf& stream_buffer) const { return targa_t<GIL::argb8_view>().detect(stream_buffer); } template <typename C> void read(GIL::variant<C>& img, std::streambuf& stream_buffer, adobe::dictionary_t parameters = adobe::dictionary_t()) const { img = GIL::argb8_image(); targa_t<GIL::argb8_view>().read(img, stream_buffer, parameters); } template <typename CV> void write(const GIL::variant<CV>& /*img_view*/, std::streambuf& /*stream_buffer*/, adobe::dictionary_t /*parameters = adobe::dictionary_t()*/) const { throw std::runtime_error("gil: image_io: targa: specific format not supported"); } }; /*************************************************************************************************/ template <typename ViewType> bool targa_t<ViewType>::detect(std::streambuf& stream_buffer) const try { stream_buffer.pubseekpos(0); implementation::targa_header_t header; implementation::targa_read_header(stream_buffer, header); return (header.image_type_m == implementation::data_type_truecolor_s || header.image_type_m == implementation::data_type_truecolor_rle_s) && (header.pixel_depth_m == 24 || header.pixel_depth_m == 32); } catch (...) { return false; } /*************************************************************************************************/ template <typename ViewType> void targa_t<ViewType>::read(image_type& img, std::streambuf& stream_buffer, adobe::dictionary_t parameters) const { stream_buffer.pubseekpos(0); implementation::targa_header_t header; implementation::targa_read_header(stream_buffer, header); bool rle_compression(header.image_type_m == implementation::data_type_truecolor_rle_s); if (header.id_length_m) stream_buffer.pubseekpos(sizeof(header) + header.id_length_m); implementation::streambuf_swizzler<adobe::endian::little> stream(stream_buffer); GIL::resize_clobber_image(img, header.width_m, header.height_m); if (header.pixel_depth_m == 24) implementation::stuff_image<GIL::rgb8_pixel>(img, stream, rle_compression); else if (header.pixel_depth_m == 32) implementation::stuff_image<GIL::argb8_pixel>(img, stream, rle_compression); else throw std::runtime_error("gil: image_io: targa: specific format not supported"); } /*************************************************************************************************/ template <typename ViewType> void targa_t<ViewType>::write(const view_type& /*img_view*/, std::streambuf& /*stream_buffer*/, adobe::dictionary_t /*parameters*/) const { throw std::runtime_error("gil: image_io: targa: writing not supported"); } /*************************************************************************************************/ ADOBE_GIL_NAMESPACE_END /*************************************************************************************************/ #endif /*************************************************************************************************/ |