1
// $Id: thumb_cache.cxx,v 1.12 2003/03/28 12:06:32 grumbel Exp $
3
// Pingus - A free Lemmings clone
4
// Copyright (C) 2000 Ingo Ruhnke <grumbel@gmx.de>
6
// This program is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public License
8
// as published by the Free Software Foundation; either version 2
9
// of the License, or (at your option) any later version.
11
// This program is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
// GNU General Public License for more details.
16
// You should have received a copy of the GNU General Public License
17
// along with this program; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
#include <ClanLib/Core/IOData/outputsource_file.h>
22
#include <ClanLib/Core/IOData/inputsource_file.h>
23
#include <ClanLib/Core/System/error.h>
24
#include <ClanLib/Display/SurfaceProviders/canvas.h>
25
#include "../globals.hxx"
26
#include "../blitter.hxx"
27
#include "../system.hxx"
28
#include "../debug.hxx"
29
#include "../pingus_resource.hxx"
30
#include "../math.hxx"
31
#include "thumb_cache.hxx"
35
const unsigned int thumbcache_version = 3;
44
uint32: mtime of parent image
50
ThumbCache::uncached_load (const std::string & res_ident, const std::string & datafile)
52
CL_Surface sur = PingusResource::load_surface (res_ident, datafile);
55
pout << "ThumbCache: Loading: " << res_ident << " (" << datafile << ")" << std::endl;
57
// Add object to cache
58
return ThumbCache::cache (sur, res_ident, datafile);
62
ThumbCache::load (const std::string & res_ident, const std::string & datafile)
64
std::string filename = res_ident + "-" + datafile;
66
for (unsigned int i = 0; i < filename.size (); ++i)
67
if (filename[i] == '/')
70
filename = System::get_cachedir () + filename;
72
// std::cout <<" Loading cache file: " << filename << std::endl;
74
if (System::exist (filename))
76
//FILE* in = fopen (filename.c_str (), "r");
79
CL_InputSource_File in(filename);
81
unsigned int version = in.read_uint32 ();
82
if (version != thumbcache_version)
84
std::cout << "Thumbnail: version mismatch" << std::endl;
85
return uncached_load (res_ident, datafile);
88
unsigned int width = in.read_uint32 ();
89
unsigned int height = in.read_uint32 ();
91
unsigned int timestamp = in.read_uint32 ();
92
// The thumbnail needs an update
93
if (timestamp != PingusResource::get_mtime (res_ident, datafile))
95
std::cout << "Thumbnail: file needs update" << std::endl;
96
return uncached_load (res_ident, datafile);
99
CL_Canvas* canvas = new CL_Canvas (width, height);
101
void* buffer = canvas->get_data ();
102
size_t buffer_size = width * height * 4;
104
size_t read_size = in.read (buffer, buffer_size);
106
if (read_size != buffer_size)
108
perr(PINGUS_DEBUG_EDITOR) << "ThumbCache: " << filename << ": read error: wanted "
109
<< buffer_size << " got " << read_size << std::endl;
111
return uncached_load (res_ident, datafile);
114
return CL_Surface (canvas, true);
116
catch (CL_Error& err)
118
std::cout << "ThumbCache: Read error: " << filename << " | " << err.message <<std::endl;
119
return uncached_load (res_ident, datafile);
123
return uncached_load (res_ident, datafile);
127
ThumbCache::cache (const CL_Surface& sur, const std::string & res_ident, const std::string & datafile)
129
if (sur.get_provider ()->get_height () < 50
130
&& sur.get_provider ()->get_width () < 50)
132
// If the image is smaller than the thumbnail, there is no need to cache it
134
pout << "ThumbCache: image too small for cache: " << res_ident << std::endl;
139
std::string filename = res_ident + "-" + datafile;
141
for (unsigned int i = 0; i < filename.size (); ++i)
142
if (filename[i] == '/')
145
filename = System::get_cachedir () + filename;
147
unsigned int timestamp = PingusResource::get_mtime (res_ident, datafile);
150
pout << "ThumbCache: Writing cache file: " << filename
151
<< " timestamp: " << timestamp << std::endl;
155
CL_OutputSource_File out(filename);
157
unsigned int width = Math::min((unsigned int)50, sur.get_width ());
158
unsigned int height = Math::min((unsigned int)50, sur.get_height ());
160
// Caller is responsible to delete the canvas
161
CL_Canvas* canvas = Blitter::scale_surface_to_canvas (sur, width, height);
163
void* buffer = canvas->get_data();
164
int buffer_size = canvas->get_height () * canvas->get_pitch ();
166
// Versionnumber of the thumbnail format
167
out.write_uint32 (thumbcache_version);
169
out.write_uint32 (width);
170
out.write_uint32 (height);
172
// Modification time of the parent file
173
out.write_uint32 (timestamp);
176
// FIXME: Endian issue here?!
177
out.write (buffer, buffer_size);
180
// Canvas will get deleted on the end of the lifetime of this surface
181
return CL_Surface (canvas, true);
185
perr << "ThumbCache: Couldn't open file for writing: " << filename << std::endl;
187
// If writing the surface fails, we return the surface without
188
// writing it to the cache
189
unsigned int width = Math::min((unsigned int)50, sur.get_width ());
190
unsigned int height = Math::min((unsigned int)50, sur.get_height ());
191
return Blitter::scale_surface (sur, width, height);
195
} // namespace EditorNS