mirror of
https://github.com/mangosfour/server.git
synced 2025-12-31 13:37:07 +00:00
+ Got rid of zip lib requirement in G3D...
Still can re-enable code by defining _HAVE_ZIP...
+ Remove silly X11 lib dependency from G3D
Code doesn't seem to do anything yet anyway, and even if, we don't want it :p
+ Fix another weird G3D build problem...
+ Remove some __asm usage in g3d, which is not available on Win64
My editor also decided to remove a ton of trailing white spaces...tss...
+ Reapply G3D fixes for 64bit VC
+ not use SSE specific header when SSE not enabled in *nix
+ Updated project files
+ New vmap_assembler VC90/VC80 Project
+ vmap assembler binaries updates
NOTE: Old vmap fikes expected work (as tests show) with new library version.
But better use new generated versions. Its different in small parts to bad or good...
(based on Lynx3d's repo commit 44798d3)
Signed-off-by: VladimirMangos <vladimir@getmangos.com>
217 lines
6.1 KiB
C++
217 lines
6.1 KiB
C++
/**
|
|
@file GImage_ppm.cpp
|
|
@author Morgan McGuire, http://graphics.cs.williams.edu
|
|
@created 2002-05-27
|
|
@edited 2006-05-10
|
|
*/
|
|
#include "G3D/platform.h"
|
|
#include "G3D/GImage.h"
|
|
#include "G3D/BinaryInput.h"
|
|
#include "G3D/BinaryOutput.h"
|
|
#include "G3D/TextInput.h"
|
|
#include "G3D/TextOutput.h"
|
|
#include "G3D/Log.h"
|
|
|
|
namespace G3D {
|
|
|
|
void GImage::encodePPMASCII(
|
|
BinaryOutput& out) const {
|
|
|
|
TextOutput::Settings ppmOptions;
|
|
ppmOptions.convertNewlines = false;
|
|
ppmOptions.numColumns = 70;
|
|
ppmOptions.wordWrap = TextOutput::Settings::WRAP_WITHOUT_BREAKING;
|
|
TextOutput ppm(ppmOptions);
|
|
|
|
switch (m_channels) {
|
|
case 1:
|
|
{
|
|
ppm.printf("P2\n%d %d\n255\n", m_width, m_height);
|
|
|
|
const Color1uint8* c = this->pixel1();
|
|
// Insert newlines every 70 characters max
|
|
for (uint32 i = 0; i < (uint32)(m_width * m_height); ++i) {
|
|
ppm.printf("%d%c", c[i].value, (i % (70/4) == 0) ? '\n' : ' ');
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
{
|
|
ppm.printf("P3\n%d %d\n255\n", m_width, m_height);
|
|
|
|
const Color3uint8* c = this->pixel3();
|
|
// Insert newlines every 70 characters max
|
|
for (uint32 i = 0; i < (uint32)(m_width * m_height); ++i) {
|
|
ppm.printf("%d %d %d%c", c[i].r, c[i].g, c[i].b,
|
|
(i % (70/12) == 0) ?
|
|
'\n' : ' ');
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
alwaysAssertM(false, "PPM requires either 1 or 3 channels exactly.");
|
|
}
|
|
|
|
const std::string& s = ppm.commitString();
|
|
out.writeBytes(s.c_str(), s.length());
|
|
}
|
|
|
|
|
|
void GImage::encodePPM(
|
|
BinaryOutput& out) const {
|
|
|
|
// http://netpbm.sourceforge.net/doc/ppm.html
|
|
if (m_channels == 3) {
|
|
std::string header = format("P6 %d %d 255 ", m_width, m_height);
|
|
out.writeBytes(header.c_str(), header.size());
|
|
out.writeBytes(this->pixel3(), m_width * m_height * 3);
|
|
} else if (m_channels == 1) {
|
|
std::string header = format("P5 %d %d 255 ", m_width, m_height);
|
|
out.writeBytes(header.c_str(), header.size());
|
|
out.writeBytes(this->pixel1(), m_width * m_height);
|
|
} else {
|
|
alwaysAssertM(false, "PPM requires either 1 or 3 channels exactly.");
|
|
}
|
|
}
|
|
|
|
|
|
void GImage::decodePPMASCII(
|
|
BinaryInput& input) {
|
|
|
|
int ppmWidth;
|
|
int ppmHeight;
|
|
|
|
double maxColor;
|
|
|
|
// Create a TextInput object to parse ascii format
|
|
// Mixed binary/ascii formats will require more
|
|
|
|
const std::string inputStr = input.readString();
|
|
|
|
TextInput::Settings ppmOptions;
|
|
ppmOptions.cppLineComments = false;
|
|
ppmOptions.otherCommentCharacter = '#';
|
|
ppmOptions.signedNumbers = true;
|
|
ppmOptions.singleQuotedStrings = false;
|
|
|
|
TextInput ppmInput(TextInput::FROM_STRING, inputStr, ppmOptions);
|
|
|
|
//Skip first line in header P#
|
|
std::string ppmType = ppmInput.readSymbol();
|
|
|
|
ppmWidth = (int)ppmInput.readNumber();
|
|
ppmHeight = (int)ppmInput.readNumber();
|
|
|
|
// Everything but a PBM will have a max color value
|
|
if (ppmType != "P2") {
|
|
maxColor = ppmInput.readNumber();
|
|
} else {
|
|
maxColor = 255;
|
|
}
|
|
|
|
if ((ppmWidth < 0) ||
|
|
(ppmHeight < 0) ||
|
|
(maxColor <= 0)) {
|
|
throw GImage::Error("Invalid PPM Header.", input.getFilename());
|
|
}
|
|
|
|
// I don't think it's proper to scale values less than 255
|
|
if (maxColor <= 255.0) {
|
|
maxColor = 255.0;
|
|
}
|
|
|
|
m_width = ppmWidth;
|
|
m_height = ppmHeight;
|
|
m_channels = 3;
|
|
// always scale down to 1 byte per channel
|
|
m_byte = (uint8*)m_memMan->alloc(m_width * m_height * 3);
|
|
|
|
// Read in the image data. I am not validating if the values match the maxColor
|
|
// requirements. I only scale if needed to fit within the byte available.
|
|
for (uint32 i = 0; i < (uint32)(m_width * m_height); ++i) {
|
|
// read in color and scale to max pixel defined in header
|
|
// A max color less than 255 might need to be left alone and not scaled.
|
|
Color3uint8& curPixel = *(pixel3() + i);
|
|
|
|
if (ppmType == "P3") {
|
|
curPixel.r = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
|
|
curPixel.g = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
|
|
curPixel.b = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
|
|
} else if (ppmType == "P2") {
|
|
uint8 pixel = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
|
|
curPixel.r = pixel;
|
|
curPixel.g = pixel;
|
|
curPixel.b = pixel;
|
|
} else if (ppmType == "P1") {
|
|
int pixel = (uint8)(ppmInput.readNumber() * maxColor);
|
|
curPixel.r = pixel;
|
|
curPixel.g = pixel;
|
|
curPixel.b = pixel;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Consumes whitespace up to and including a number, but not the following character */
|
|
static int scanUInt(BinaryInput& input) {
|
|
char c = input.readUInt8();
|
|
while (isWhiteSpace(c)) {
|
|
c = input.readUInt8();
|
|
}
|
|
|
|
std::string s;
|
|
s += c;
|
|
c = input.readUInt8();
|
|
while (!isWhiteSpace(c)) {
|
|
s += c;
|
|
c = input.readUInt8();
|
|
}
|
|
|
|
// Back up one to avoid consuming the last character
|
|
input.setPosition(input.getPosition() - 1);
|
|
|
|
int x;
|
|
sscanf(s.c_str(), "%d", &x);
|
|
return x;
|
|
}
|
|
|
|
|
|
void GImage::decodePPM(
|
|
BinaryInput& input) {
|
|
|
|
char head[2];
|
|
int w, h;
|
|
|
|
input.readBytes(head, 2);
|
|
if (head[0] != 'P' || (head[1] != '6') && (head[1] != '5')) {
|
|
throw GImage::Error("Invalid PPM Header.", input.getFilename());
|
|
}
|
|
|
|
w = scanUInt(input);
|
|
h = scanUInt(input);
|
|
|
|
// Skip the max color specifier
|
|
scanUInt(input);
|
|
|
|
if ((w < 0) ||
|
|
(h < 0) ||
|
|
(w > 100000) ||
|
|
(h > 100000)) {
|
|
throw GImage::Error("Invalid PPM size in header.", input.getFilename());
|
|
}
|
|
|
|
// Trailing whitespace
|
|
input.readUInt8();
|
|
|
|
if (head[1] == '6') {
|
|
// 3 channel
|
|
resize(w, h, 3);
|
|
input.readBytes(m_byte, m_width * m_height * 3);
|
|
} else if (head[1] == '5') {
|
|
// 1 channel
|
|
resize(w, h, 1);
|
|
input.readBytes(m_byte, m_width * m_height);
|
|
}
|
|
}
|
|
|
|
}
|