Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-11-11 19:11:57 +0000
committerStijn Buys <ingar@osirion.org>2008-11-11 19:11:57 +0000
commit773c1bafe0f1d8b706e0f72e235f8466e7a9ccf5 (patch)
treeab4b3058f436a4e4c54618f132a9179ee40e330c /src/render/tga.cc
parent3082cb197fb6af7d069f9ad211ff6ea5657d924a (diff)
cleanups
Diffstat (limited to 'src/render/tga.cc')
-rw-r--r--src/render/tga.cc367
1 files changed, 0 insertions, 367 deletions
diff --git a/src/render/tga.cc b/src/render/tga.cc
deleted file mode 100644
index a7a2356..0000000
--- a/src/render/tga.cc
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- render/tga.cc
- This file is part of the Osirion project and is distributed under
- the terms of the GNU General Public License version 2
-*/
-
-/*
- Documentation and examples on the TGA file format:
-
- http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf
- http://www.fileformat.info/format/tga/egff.htm
- http://www.morrowland.com/apron/tut_gl.php
-
- Notes
-
- TGA image type Colormap RLE
- 0 No image data included in file No No
- 1 Colormapped image data Yes No
- 2 Truecolor image data No No
- 3 Monochrome image data No No
- 9 Colormapped image data Yes Yes
- 10 Truecolor image data No Yes
- 11 Monochrome image data No Yes
-
- TGA multi-byte integer values have LSB first
-*/
-
-#include <string.h>
-
-#include <fstream>
-#include <sstream>
-#include <string>
-
-#include "filesystem/filesystem.h"
-#include "render/tga.h"
-#include "sys/sys.h"
-
-const unsigned char TGA_NONE = 0;
-const unsigned char TGA_TRUECOLOR = 2;
-const unsigned char TGA_TRUECOLOR_RLE = 10;
-
-namespace render
-{
-
-Image *TGA::load(const char *filename)
-{
- Image *image = 0;
-
- if (!filename)
- return 0;
-
- filesystem::File *tga_file = filesystem::open(filename);
- if (!tga_file) {
- //con_warn << "Could not open " << filename << std::endl;
- return 0;
- }
-
- // TGA header
- unsigned char header[18];
- memset(header, 0, sizeof(header));
-
- if (!tga_file->read(header, 18)) {
- con_warn << "Error reading " << filename << std::endl;
- filesystem::close(tga_file);
- return 0;
- }
-
- // byte 0 - image ID field length
- unsigned int tga_idlength = header[0];
-
- // byte 1 - color map type
- unsigned int tga_colormap = header[1];
-
- // byte 2 - image type
- unsigned int tga_type = header[2];
-
- // byte 3+4 - color map first entry index
- //unsigned int tga_colormap_first = header[3] + (header[4] << 8 );
-
- // byte 5+6 - color map length (in bits)
- unsigned int tga_color_map_length = header[5] +(header[6] << 8 );
-
- // byte 7 - color map entry length
- unsigned int tga_colormap_entry = header[7];
-
- // byte 8+9 - image x origin
- // byte 10+11 - image y origin
- // byte 12+13 - image width (LSB first)
- unsigned int tga_width = header[12] + (header[13] << 8);
-
- // byte 14+15 - image height (LSB first)
- unsigned int tga_height = header[14] + (header[15] << 8);
-
- // byte 16 - image color depth (in bits)
- unsigned int tga_depth = header[16];
-
- // byte 17 - image descriptor byte
- unsigned int tga_descriptor = header[17];
-
- // read the image id if there is one
- if (tga_idlength)
- tga_file->skip(tga_idlength);
-
- // read color map data (even for non-color mapped images)
- if (tga_colormap) {
- if (tga_colormap > 1)
- con_warn << filename << ": invalid color map type!" << std::endl;
-
- tga_file->skip(tga_color_map_length*tga_colormap_entry);
- }
-
- unsigned int index = 0;
- unsigned int channels = tga_depth / 8;
-
- switch(tga_type) {
-
- case TGA_NONE:
- con_warn << "Error reading " << filename
- << ": no image data!" << std::endl;
- filesystem::close(tga_file);
- return 0;
- break;
-
- case TGA_TRUECOLOR:
- if ((tga_depth == 24) || (tga_depth == 32)) {
-
- image = new Image(tga_width, tga_height, channels);
-
- for (size_t i = 0; i < tga_width * tga_height; i++) {
- tga_file->read((void *)(*image)[i*(size_t)channels], channels);
- }
-
- image->swap_channels();
-
- } else if (tga_depth == 16) {
-
- channels = 3;
- image = new Image(tga_width, tga_height,channels);
-
- for (size_t i =0; i < tga_width * tga_height; i++) {
- // unpack one pixel
- unsigned char pixel_data[2];
- tga_file->read((void *)pixel_data, 2);
- unsigned int unpacked = pixel_data[0] + pixel_data[1]* 0xff;
-
- unsigned int b = (unpacked & 0x1f) << 3;
- unsigned int g = ((unpacked >> 5) & 0x1f) << 3;
- unsigned int r = ((unpacked >> 10) & 0x1f) << 3;
-
- // store it
- image->data()[i * channels] = (unsigned char) b;
- image->data()[i * channels+1] = (unsigned char) g;
- image->data()[i * channels+2] = (unsigned char) r;
- }
- } else {
- con_warn << "Error reading " << filename
- << ": unsupported image depth '" << tga_depth << "'!" << std::endl;
- filesystem::close(tga_file);
- return 0;
- }
-
- break;
-
- case TGA_TRUECOLOR_RLE:
-
- image = new Image(tga_width, tga_height, channels);
-
- while (index < tga_width * tga_height) {
- unsigned char rle = 0;
- unsigned char pixel_data[3];
-
- // read RLE packet byte
- tga_file->read(&rle, 1);
-
- if (rle < 128) {
- rle++; // rle contains the number of pixels-1
- tga_file->read((void *)(*image)[index*channels], rle*channels);
- index += rle;
-
- } else {
- rle -= 127; // rle contains 128 + the number of identical pixels-1
- tga_file->read(pixel_data, channels);
-
- while (rle) {
- memcpy((void *)(*image)[index*channels], (void *)pixel_data, channels);
- index++;
- rle--;
- }
- }
- }
-
- image->swap_channels();
-
- break;
-
- default:
- con_warn << "Error reading " << filename
- << ": unsupported TGA type '" << (int) tga_type << "'!" << std::endl;
- filesystem::close(tga_file);
- return 0;
- }
-
- filesystem::close(tga_file);
-
- if ((tga_descriptor & 0x20) == 0x0) {
- // origin at bottom left
- image->flip();
- }
-
- if ((tga_descriptor & 0x10) == 0x10) {
- con_warn << filename << ": descriptor bit 4 (left-right) set!" << std::endl;
- }
-
- con_debug << " " << filename << " " << image->width() << "x" << image->height() << "x" << image->bpp() << "bpp" << std::endl;
- return image;
-}
-
-void TGA::save(const char *filename, Image & image)
-{
- if (!filename)
- return;
-
- std::ofstream ofs(filename, std::ios_base::out | std::ios_base::binary );
-
- if (!ofs.is_open()) {
- con_warn << "Could not write " << filename << std::endl;
- return;
- }
-
- // write TGA header
- unsigned char header[18];
- memset(header, 0, sizeof(header));
-
- // byte 0 - image ID field length = 0 (no image ID field present)
- // byte 1 - color map type = 0 (no palette present)
- // byte 2 - image type = 10 (truecolor RLE encoded)
- header[2] = TGA_TRUECOLOR_RLE;
- // byte 3-11 - palette data (not used)
- // byte 12+13 - image width
- header[12] = (image.width() & 0xff);
- header[13] = ((image.width() >> 8) & 0xff);
- // byte 14+15 - image height
- header[14] = (image.height() & 0xff);
- header[15] = ((image.height() >> 8) & 0xff);
- // byte 16 - image color depth = 24 (RGB) or 32 (RGBA)
- header[16] = image.channels() * 8;
- // byte 17 - image descriptor byte = 0x20 (origin at bottom left)
- header[17] = 0x20;
-
- // write header
- ofs.write((char *)header, sizeof(header));
-
- // write image data
- // TGA has the R and B channels switched
- unsigned char pixel_data[image.channels()];
- unsigned char block_data[image.channels()*128];
- unsigned char rle_packet;
- bool compress = false;
- size_t block_length = 0;
-
- for (int y = image.height()-1; y >= 0; y--) {
- for (size_t x = 0; x < image.width(); x++) {
- size_t index = y*image.width()*image.channels() + x * image.channels();
-
- pixel_data[0] = *image[index+2];
- pixel_data[1] = *image[index+1];
- pixel_data[2] = *image[index];
- if (image.channels() == 4)
- pixel_data[3] = *image[index+3];
-
- if (block_length == 0) {
- memcpy(block_data, pixel_data, image.channels());
- block_length++;
- compress = false;
- } else {
- if (!compress) {
-
- // uncompressed block and pixel_data differs from the last pixel
- if (memcmp(&block_data[(block_length-1)*image.channels()], pixel_data, image.channels()) != 0) {
- // append pixel
- memcpy(&block_data[block_length*image.channels()], pixel_data, image.channels());
-
- block_length++;
- } else {
-
- // uncompressed block and pixel data is identical
- if (block_length > 1 ) {
- // write the uncompressed block
- rle_packet = block_length - 2;
- ofs.write((char *)&rle_packet, 1);
- ofs.write((char *)block_data, (block_length-1) * image.channels());
- block_length = 1;
- }
- memcpy(block_data, pixel_data, image.channels());
- block_length++;
- compress = true;
- }
-
- } else {
-
- // compressed block and pixel data is identical
- if (memcmp(block_data, pixel_data, image.channels()) == 0) {
- block_length++;
-
- } else {
-
- // compressed block and pixel data differs
- if (block_length > 1) {
- // write the compressed block
- rle_packet = block_length + 127;
- ofs.write((char *)&rle_packet, 1);
- ofs.write((char *)block_data, image.channels());
- block_length = 0;
- }
- memcpy(&block_data[block_length * image.channels()], pixel_data, image.channels());
- block_length++;
- compress = false;
- }
- }
- }
-
- if (block_length == 128) {
- rle_packet = block_length - 1;
- if (!compress) {
- ofs.write((char *)&rle_packet, 1);
- ofs.write((char *)block_data, 128 * image.channels());
- } else {
- rle_packet += 128;
- ofs.write((char *)&rle_packet, 1);
- ofs.write((char *)block_data, image.channels());
- }
-
- block_length = 0;
- compress = false;
- }
- }
- }
-
- // write remaining bytes
- if (block_length) {
- rle_packet = block_length - 1;
- if (!compress) {
- ofs.write((char *)&rle_packet, 1);
- ofs.write((char *)block_data, block_length * image.channels());
- } else {
- rle_packet += 128;
- ofs.write((char *)&rle_packet, 1);
- ofs.write((char *)block_data, image.channels());
- }
- }
-
-
- // write footer (optional, but the specification recommends it)
- char footer[26];
- memset(footer, 0, sizeof(footer));
- strncpy(&footer[8] , "TRUEVISION-XFILE", 16);
- footer[24] = '.';
- footer[25] = 0;
- ofs.write(footer, sizeof(footer));
-
- // close file
- ofs.close();
-
- con_print << "Wrote " << filename << std::endl;
-}
-
-}