1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom 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.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "Palette.h"
21 
22 #include "Exceptions.h"
23 #include "StringUtils.h"
24 
25 #include <algorithm>
26 #include <cstring>
27 #include <fstream>
28 
29 namespace TrenchBroom {
30     namespace Assets {
Palette(const IO::Path & path)31         Palette::Palette(const IO::Path& path) {
32             if (StringUtils::caseInsensitiveEqual(path.extension(), "lmp"))
33                 loadLmpPalette(path);
34             else if (StringUtils::caseInsensitiveEqual(path.extension(), "pcx"))
35                 loadPcxPalette(path);
36             else
37                 throw FileSystemException("Unknown palette format " + path.asString());
38         }
39 
Palette(const Palette & other)40         Palette::Palette(const Palette& other) :
41         m_data(NULL),
42         m_size(other.m_size) {
43             m_data = new unsigned char[m_size];
44             memcpy(m_data, other.m_data, m_size);
45         }
46 
operator =(Palette other)47         void Palette::operator=(Palette other) {
48             using std::swap;
49             swap(m_data, other.m_data);
50             swap(m_size, other.m_size);
51         }
52 
~Palette()53         Palette::~Palette() {
54             delete[] m_data;
55         }
56 
loadLmpPalette(const IO::Path & path)57         void Palette::loadLmpPalette(const IO::Path& path) {
58             std::ifstream stream(path.asString().c_str(), std::ios::binary | std::ios::in);
59             if (!stream.is_open())
60                 throw FileSystemException("Cannot load palette " + path.asString());
61 
62             stream.seekg(0, std::ios::end);
63             m_size = static_cast<size_t>(stream.tellg());
64             stream.seekg(0, std::ios::beg);
65             m_data = new unsigned char[m_size];
66 
67             stream.read(reinterpret_cast<char*>(m_data), static_cast<std::streamsize>(m_size));
68         }
69 
loadPcxPalette(const IO::Path & path)70         void Palette::loadPcxPalette(const IO::Path& path) {
71             std::ifstream stream(path.asString().c_str(), std::ios::binary | std::ios::in);
72             if (!stream.is_open())
73                 throw FileSystemException("Cannot load palette " + path.asString());
74 
75             m_size = 768;
76             stream.seekg(-(static_cast<std::iostream::off_type>(m_size+1)), std::ios::end);
77 
78             char magic;
79             stream.get(magic);
80             if (magic != 0x0C)
81                throw FileSystemException("Cannot load palette " + path.asString());
82 
83             m_data = new unsigned char[m_size];
84             stream.read(reinterpret_cast<char*>(m_data), static_cast<std::streamsize>(m_size));
85         }
86     }
87 }
88