• R/O
  • SSH
  • HTTPS

hamigaki: 提交


Commit MetaInfo

修訂1623 (tree)
時間2008-04-28 22:49:59
作者hamigaki

Log Message

added png_reader.cpp

Change Summary

差異

--- sandbox/trunk/tools/gtk_test/texture.cpp (revision 1622)
+++ sandbox/trunk/tools/gtk_test/texture.cpp (revision 1623)
@@ -39,6 +39,8 @@
3939 ::glBindTexture(GL_TEXTURE_2D, handle_);
4040 ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4141 ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
42+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
43+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
4244 ::glTexImage2D(
4345 GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
4446 GL_RGBA, GL_UNSIGNED_BYTE, data);
--- sandbox/trunk/tools/gtk_test/png_test.cpp (nonexistent)
+++ sandbox/trunk/tools/gtk_test/png_test.cpp (revision 1623)
@@ -0,0 +1,169 @@
1+// png_test.cpp: the test program for the class png_reader
2+
3+// Copyright Takeshi Mouri 2008.
4+// Distributed under the Boost Software License, Version 1.0.
5+// (See accompanying file LICENSE_1_0.txt or copy at
6+// http://www.boost.org/LICENSE_1_0.txt)
7+
8+// See http://hamigaki.sourceforge.jp/ for library home page.
9+
10+#include <boost/config.hpp>
11+
12+#include "png_reader.hpp"
13+#include "texture.hpp"
14+#include "render_context.hpp"
15+#include <boost/scoped_array.hpp>
16+#include <cstring>
17+#include <fstream>
18+#include <iostream>
19+#include <stdexcept>
20+
21+#if defined(BOOST_WINDOWS)
22+ #include <windows.h>
23+#endif
24+#include <GL/gl.h>
25+
26+class main_window_data
27+{
28+public:
29+ explicit main_window_data(GtkWidget* widget) : rc_(widget), texture_(rc_)
30+ {
31+ rc_.select();
32+
33+ std::ifstream is("milk.png", std::ios_base::binary);
34+
35+ hamigaki::png_reader png(is);
36+ const int width = static_cast<int>(png.width());
37+ const int height = static_cast<int>(png.height());
38+ const unsigned long pitch = png.pitch();
39+
40+ typedef unsigned char ubyte;
41+ boost::scoped_array<ubyte> row(new ubyte[pitch]);
42+ boost::scoped_array<ubyte> data(new ubyte[4*width*height]);
43+
44+ const std::size_t data_pitch = static_cast<std::size_t>(4*width);
45+ for (int i = 0; i < height; ++i)
46+ {
47+ png.read_next_row(row.get());
48+ std::memcpy(&data[data_pitch*i], row.get(), data_pitch);
49+ }
50+
51+ texture_.set_image(width, height, data.get());
52+ }
53+
54+ void render()
55+ {
56+ rc_.select();
57+
58+ ::glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
59+ ::glClear(GL_COLOR_BUFFER_BIT);
60+
61+ ::glAlphaFunc(GL_GREATER, 0.1f);
62+ ::glEnable(GL_ALPHA_TEST);
63+ ::glEnable(GL_TEXTURE_2D);
64+ texture_.bind();
65+
66+ ::glBegin(GL_QUADS);
67+ ::glTexCoord2f(0.0f, 0.0f);
68+ ::glVertex3f(-0.75f, 0.75f, 0.0f);
69+ ::glTexCoord2f(1.0f, 0.0f);
70+ ::glVertex3f(0.75f, 0.75f, 0.0f);
71+ ::glTexCoord2f(1.0f, 1.0f);
72+ ::glVertex3f(0.75f, -0.75f, 0.0f);
73+ ::glTexCoord2f(0.0f, 1.0f);
74+ ::glVertex3f(-0.75f, -0.75f, 0.0f);
75+ ::glEnd();
76+
77+ ::glDisable(GL_TEXTURE_2D);
78+
79+ rc_.swap_buffers();
80+ }
81+
82+private:
83+ hamigaki::render_context rc_;
84+ hamigaki::texture texture_;
85+
86+ main_window_data(const main_window_data&);
87+ main_window_data& operator=(const main_window_data&);
88+};
89+
90+void destroy(GtkWidget*, gpointer)
91+{
92+ ::gtk_main_quit();
93+}
94+
95+void realize(GtkWidget* widget, gpointer user_data)
96+{
97+ main_window_data*& pimpl = *static_cast<main_window_data**>(user_data);
98+ try
99+ {
100+ pimpl = new main_window_data(widget);
101+ }
102+ catch (const std::exception& e)
103+ {
104+ std::cerr << "Error: " << e.what() << std::endl;
105+ pimpl = 0;
106+ }
107+}
108+
109+void unrealize(GtkWidget*, gpointer user_data)
110+{
111+ main_window_data*& pimpl = *static_cast<main_window_data**>(user_data);
112+ delete pimpl;
113+ pimpl = 0;
114+}
115+
116+gboolean render(gpointer user_data)
117+{
118+ if (main_window_data*& pimpl = *static_cast<main_window_data**>(user_data))
119+ {
120+ try
121+ {
122+ pimpl->render();
123+ }
124+ catch (const std::exception& e)
125+ {
126+ std::cerr << "Error: " << e.what() << std::endl;
127+ }
128+ }
129+
130+ return TRUE;
131+}
132+
133+template<class Widget, class Arg>
134+inline gulong connect_signal(
135+ Widget* w, const char* sig, GCallback func, Arg* arg)
136+{
137+ gulong id = ::g_signal_connect(G_OBJECT(w), sig, func, arg);
138+ if (id == 0)
139+ throw std::runtime_error("g_signal_connect() failed");
140+ return id;
141+}
142+
143+int main(int argc, char* argv[])
144+{
145+ try
146+ {
147+ ::gtk_set_locale();
148+ ::gtk_init(&argc, &argv);
149+
150+ GtkWidget* window = ::gtk_window_new(GTK_WINDOW_TOPLEVEL);
151+ if (window == 0)
152+ throw std::runtime_error("gtk_window_new() failed");
153+
154+ main_window_data* pimpl = 0;
155+ connect_signal(window, "destroy", G_CALLBACK(destroy), &pimpl);
156+ connect_signal(window, "realize", G_CALLBACK(realize), &pimpl);
157+ connect_signal(window, "unrealize", G_CALLBACK(unrealize), &pimpl);
158+ ::g_timeout_add(16, &render, &pimpl);
159+
160+ ::gtk_widget_show_all(window);
161+ ::gtk_main();
162+ }
163+ catch (const std::exception& e)
164+ {
165+ std::cerr << "Error: " << e.what() << std::endl;
166+ }
167+
168+ return 0;
169+}
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
--- sandbox/trunk/tools/gtk_test/png_reader.cpp (nonexistent)
+++ sandbox/trunk/tools/gtk_test/png_reader.cpp (revision 1623)
@@ -0,0 +1,192 @@
1+// png_reader.cpp: PNG reader class
2+
3+// Copyright Takeshi Mouri 2008.
4+// Distributed under the Boost Software License, Version 1.0.
5+// (See accompanying file LICENSE_1_0.txt or copy at
6+// http://www.boost.org/LICENSE_1_0.txt)
7+
8+// See http://hamigaki.sourceforge.jp/ for library home page.
9+
10+#include "png_reader.hpp"
11+#include <csetjmp>
12+#include <istream>
13+#include <stdexcept>
14+#include <png.h>
15+
16+#if !defined(NDEBUG)
17+ #include <windows.h>
18+#endif
19+
20+namespace
21+{
22+
23+void PNGAPI do_long_jump(png_struct* ctx, const char*)
24+{
25+ longjmp(png_jmpbuf(ctx), 1);
26+}
27+
28+void PNGAPI process_error(png_struct*, const char* msg)
29+{
30+ throw std::runtime_error(msg);
31+}
32+
33+#if defined(NDEBUG)
34+void PNGAPI process_warning(png_struct*, const char*)
35+{
36+}
37+#else
38+void PNGAPI process_warning(png_struct*, const char* msg)
39+{
40+ ::OutputDebugStringA(msg);
41+}
42+#endif
43+
44+void PNGAPI read_from_stream(png_struct* ctx, unsigned char* p, std::size_t n)
45+{
46+ std::streamsize size = static_cast<std::streamsize>(n);
47+
48+ std::istream& is = *static_cast<std::istream*>(png_get_io_ptr(ctx));
49+ is.read(reinterpret_cast<char*>(p), size);
50+ if (is.gcount() != size)
51+ throw std::runtime_error("failed read_from_stream()");
52+}
53+
54+} // namespace
55+
56+namespace hamigaki
57+{
58+
59+class png_reader::impl
60+{
61+public:
62+ explicit impl(std::istream& is)
63+ {
64+ // Note:
65+ // png_create_read_struct() uses setjmp() for error handling
66+ // So error_fn must call longjmp() in this function
67+ pimpl_ = ::png_create_read_struct(
68+ PNG_LIBPNG_VER_STRING, 0, &do_long_jump, &process_warning);
69+
70+ if (!pimpl_)
71+ throw std::runtime_error("failed png_create_read_struct()");
72+
73+ // Now, error_fn can throw a exception
74+ ::png_set_error_fn(pimpl_, 0, &process_error, &process_warning);
75+
76+ info_ptr_ = ::png_create_info_struct(pimpl_);
77+ if (!info_ptr_)
78+ {
79+ ::png_destroy_read_struct(&pimpl_, 0, 0);
80+ throw std::runtime_error("failed png_create_info_struct()");
81+ }
82+
83+ ::png_set_read_fn(pimpl_, &is, read_from_stream);
84+ }
85+
86+ ~impl()
87+ {
88+ ::png_destroy_read_struct(&pimpl_, &info_ptr_, 0);
89+ }
90+
91+ void read_info()
92+ {
93+ ::png_read_info(pimpl_, info_ptr_);
94+ }
95+
96+ void force_rgba()
97+ {
98+ unsigned long w;
99+ unsigned long h;
100+ int bits;
101+ int type;
102+
103+ ::png_get_IHDR(pimpl_, info_ptr_, &w, &h, &bits, &type, 0, 0, 0);
104+
105+ ::png_set_strip_16(pimpl_);
106+ ::png_set_packing(pimpl_);
107+
108+ if (type == PNG_COLOR_TYPE_PALETTE)
109+ ::png_set_palette_to_rgb(pimpl_);
110+
111+ if (((type & PNG_COLOR_MASK_COLOR) == 0) && (bits < 8))
112+ ::png_set_gray_1_2_4_to_8(pimpl_);
113+
114+ if (png_get_valid(pimpl_, info_ptr_, PNG_INFO_tRNS))
115+ ::png_set_tRNS_to_alpha(pimpl_);
116+ else if ((type & PNG_COLOR_MASK_ALPHA) == 0)
117+ ::png_set_add_alpha(pimpl_, 0xFF, PNG_FILLER_AFTER);
118+
119+ ::png_set_bgr(pimpl_);
120+
121+ ::png_read_update_info(pimpl_, info_ptr_);
122+ }
123+
124+ unsigned long width() const
125+ {
126+ return ::png_get_image_width(pimpl_, info_ptr_);
127+ }
128+
129+ unsigned long height() const
130+ {
131+ return ::png_get_image_height(pimpl_, info_ptr_);
132+ }
133+
134+ unsigned long pitch() const
135+ {
136+ return ::png_get_rowbytes(pimpl_, info_ptr_);
137+ }
138+
139+ void read_next_row(unsigned char* buf)
140+ {
141+ ::png_read_row(pimpl_, buf, 0);
142+ }
143+
144+ void read_end()
145+ {
146+ ::png_read_end(pimpl_, 0);
147+ }
148+
149+private:
150+ png_struct* pimpl_;
151+ png_info* info_ptr_;
152+
153+ impl(const impl&);
154+ impl& operator=(const impl&);
155+};
156+
157+png_reader::png_reader(std::istream& is) : pimpl_(new impl(is))
158+{
159+ pimpl_->read_info();
160+ pimpl_->force_rgba();
161+}
162+
163+png_reader::~png_reader()
164+{
165+}
166+
167+unsigned long png_reader::width() const
168+{
169+ return pimpl_->width();
170+}
171+
172+unsigned long png_reader::height() const
173+{
174+ return pimpl_->height();
175+}
176+
177+unsigned long png_reader::pitch() const
178+{
179+ return pimpl_->pitch();
180+}
181+
182+void png_reader::read_next_row(unsigned char* buf)
183+{
184+ pimpl_->read_next_row(buf);
185+}
186+
187+void png_reader::read_end()
188+{
189+ pimpl_->read_end();
190+}
191+
192+} // namespace hamigaki
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
--- sandbox/trunk/tools/gtk_test/png_reader.hpp (nonexistent)
+++ sandbox/trunk/tools/gtk_test/png_reader.hpp (revision 1623)
@@ -0,0 +1,37 @@
1+// png_reader.hpp: PNG reader class
2+
3+// Copyright Takeshi Mouri 2008.
4+// Distributed under the Boost Software License, Version 1.0.
5+// (See accompanying file LICENSE_1_0.txt or copy at
6+// http://www.boost.org/LICENSE_1_0.txt)
7+
8+// See http://hamigaki.sourceforge.jp/ for library home page.
9+
10+#ifndef HAMIGAKI_PNG_IMAGE_HPP
11+#define HAMIGAKI_PNG_IMAGE_HPP
12+
13+#include <boost/shared_ptr.hpp>
14+#include <iosfwd>
15+
16+namespace hamigaki
17+{
18+
19+class png_reader
20+{
21+public:
22+ explicit png_reader(std::istream& is);
23+ ~png_reader();
24+ unsigned long width() const;
25+ unsigned long height() const;
26+ unsigned long pitch() const;
27+ void read_next_row(unsigned char* buf);
28+ void read_end();
29+
30+private:
31+ class impl;
32+ boost::shared_ptr<impl> pimpl_;
33+};
34+
35+} // namespace hamigaki
36+
37+#endif // HAMIGAKI_PNG_IMAGE_HPP
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Show on old repository browser