mirror of
https://github.com/FULU-Foundation/OrcaSlicer-bambulab.git
synced 2026-07-23 18:04:27 +03:00
Building igl statically and moving to the dep scripts
Fixing dep build script on Windows and removing some warnings. Use bundled igl by default. Not building with the dependency scripts if not explicitly stated. This way, it will stay in Fix the libigl patch to include C source files in header only mode.
This commit is contained in:
87
src/libigl/igl/copyleft/opengl2/render_to_tga.cpp
Normal file
87
src/libigl/igl/copyleft/opengl2/render_to_tga.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "render_to_tga.h"
|
||||
#include "tga.h"
|
||||
|
||||
#include "../../opengl2/gl.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
IGL_INLINE bool igl::opengl::render_to_tga(
|
||||
const std::string tga_file,
|
||||
const int width,
|
||||
const int height,
|
||||
const bool alpha)
|
||||
{
|
||||
|
||||
size_t components = 3;
|
||||
GLenum format = GL_BGR;
|
||||
if(alpha)
|
||||
{
|
||||
format = GL_BGRA;
|
||||
components = 4;
|
||||
}
|
||||
GLubyte * cmap = NULL;
|
||||
|
||||
// OpenGL by default tries to read data in multiples of 4, if our data is
|
||||
// only RGB or BGR and the width is not divible by 4 then we need to alert
|
||||
// opengl
|
||||
if((width % 4) != 0 &&
|
||||
(format == GL_RGB ||
|
||||
format == GL_BGR))
|
||||
{
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
}
|
||||
GLubyte *pixels;
|
||||
pixels = (unsigned char *) malloc (width * height * components);
|
||||
glReadPixels(
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
format,
|
||||
GL_UNSIGNED_BYTE,
|
||||
pixels);
|
||||
|
||||
// set up generic image struct
|
||||
gliGenericImage * genericImage;
|
||||
genericImage = (gliGenericImage*) malloc(sizeof(gliGenericImage));
|
||||
genericImage->width = width;
|
||||
genericImage->height = height;
|
||||
genericImage->format = format;
|
||||
genericImage->components = components;
|
||||
genericImage->pixels = pixels;
|
||||
// CMAP is not supported, but we need to put something here
|
||||
genericImage->cmapEntries = 0;
|
||||
genericImage->cmapFormat = GL_BGR;
|
||||
genericImage->cmap = cmap;
|
||||
|
||||
// write pixels to tga file
|
||||
FILE * imgFile;
|
||||
// "-" as output file name is code for write to stdout
|
||||
if(tga_file.compare("-") == 0)
|
||||
{
|
||||
imgFile = stdout;
|
||||
}else{
|
||||
imgFile = fopen(tga_file.c_str(),"w");
|
||||
if(NULL==imgFile)
|
||||
{
|
||||
printf("IOError: %s could not be opened...\n",tga_file.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
writeTGA(genericImage,imgFile);
|
||||
|
||||
free(genericImage);
|
||||
return fclose(imgFile) == 0;
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
#endif
|
||||
38
src/libigl/igl/copyleft/opengl2/render_to_tga.h
Normal file
38
src/libigl/igl/copyleft/opengl2/render_to_tga.h
Normal file
@@ -0,0 +1,38 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_OPENGL_RENDER_TO_TGA_H
|
||||
#define IGL_OPENGL_RENDER_TO_TGA_H
|
||||
#include "../../igl_inline.h"
|
||||
#include <string>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
// Render current open GL image to .tga file
|
||||
// Inputs:
|
||||
// tga_file path to output .tga file
|
||||
// width width of scene and resulting image
|
||||
// height height of scene and resulting image
|
||||
/// alpha whether to include alpha channel
|
||||
// Returns true only if no errors occurred
|
||||
//
|
||||
// See also: png/render_to_png which is slower but writes .png files
|
||||
IGL_INLINE bool render_to_tga(
|
||||
const std::string tga_file,
|
||||
const int width,
|
||||
const int height,
|
||||
const bool alpha);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "render_to_tga.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
68
src/libigl/igl/copyleft/opengl2/texture_from_tga.cpp
Normal file
68
src/libigl/igl/copyleft/opengl2/texture_from_tga.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#include "texture_from_tga.h"
|
||||
#include "tga.h"
|
||||
#include <cstring>
|
||||
|
||||
IGL_INLINE bool igl::opengl::texture_from_tga(const std::string tga_file, GLuint & id)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// read pixels to tga file
|
||||
FILE * imgFile;
|
||||
// "-" as input file name is code for read from stdin
|
||||
imgFile = fopen(tga_file.c_str(),"r");
|
||||
if(NULL==imgFile)
|
||||
{
|
||||
printf("IOError: %s could not be opened...",tga_file.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// gliReadTGA annoyingly uses char * instead of const char *
|
||||
size_t len = tga_file.length();
|
||||
char* tga_file_char = new char [ len + 1 ];
|
||||
strcpy( tga_file_char, tga_file.c_str() );
|
||||
// read image
|
||||
gliGenericImage* img = gliReadTGA(imgFile, tga_file_char, 0, 0);
|
||||
// clean up filename buffer
|
||||
delete[] tga_file_char;
|
||||
fclose( imgFile );
|
||||
|
||||
// set up texture mapping parameters and generate texture id
|
||||
glGenTextures(1,&id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
// Texture parameters
|
||||
float empty[] = {1.0f,1.0f,1.0f,0.0f};
|
||||
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,empty);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
// GL_LINEAR_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR);
|
||||
|
||||
// OpenGL by default tries to read data in multiples of 4, if our data is
|
||||
// only RGB or BGR and the width is not divible by 4 then we need to alert
|
||||
// opengl
|
||||
if((img->width % 4) != 0 &&
|
||||
(img->format == GL_RGB ||
|
||||
img->format == GL_BGR))
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
}
|
||||
|
||||
// Load texture
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->width,
|
||||
img->height, 0, img->format, GL_UNSIGNED_BYTE,
|
||||
img->pixels);
|
||||
return id;
|
||||
}
|
||||
|
||||
#ifdef IGL_STATIC_LIBRARY
|
||||
// Explicit template instantiation
|
||||
#endif
|
||||
33
src/libigl/igl/copyleft/opengl2/texture_from_tga.h
Normal file
33
src/libigl/igl/copyleft/opengl2/texture_from_tga.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_OPENGL_TEXTURE_FROM_TGA_H
|
||||
#define IGL_OPENGL_TEXTURE_FROM_TGA_H
|
||||
#include "../../igl_inline.h"
|
||||
#include "../../opengl2/gl.h"
|
||||
#include <string>
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
// Read an image from a .tga file and use it as a texture
|
||||
//
|
||||
// Input:
|
||||
// tga_file path to .tga file
|
||||
// Output:
|
||||
// id of generated openGL texture
|
||||
// Returns true on success, false on failure
|
||||
IGL_INLINE bool texture_from_tga(const std::string tga_file, GLuint & id);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "texture_from_tga.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
549
src/libigl/igl/copyleft/opengl2/tga.cpp
Normal file
549
src/libigl/igl/copyleft/opengl2/tga.cpp
Normal file
@@ -0,0 +1,549 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WARNING
|
||||
//
|
||||
// THIS DOES NOT DEAL WITH VERTICALLY FLIPPED DATA CORRECTLY
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* This file is derived from (actually an earlier version of)... */
|
||||
|
||||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* $Id: tga.cpp,v 1.1.2.5 2007-05-10 02:10:07 elif Exp $
|
||||
* TrueVision Targa loading and saving file filter for the Gimp.
|
||||
* Targa code Copyright (C) 1997 Raphael FRANCOIS and Gordon Matzigkeit
|
||||
*
|
||||
* The Targa reading and writing code was written from scratch by
|
||||
* Raphael FRANCOIS <fraph@ibm.net> and Gordon Matzigkeit
|
||||
* <gord@gnu.ai.mit.edu> based on the TrueVision TGA File Format
|
||||
* Specification, Version 2.0:
|
||||
*
|
||||
* <URL:ftp://ftp.truevision.com/pub/TGA.File.Format.Spec/>
|
||||
*
|
||||
* It does not contain any code written for other TGA file loaders.
|
||||
* Not even the RLE handling. ;)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "tga.h"
|
||||
#include "../../opengl2/glext.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
static char error[256];
|
||||
static unsigned int _verbose = 0;
|
||||
static int totbytes = 0;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *statebuf;
|
||||
int statelen;
|
||||
int laststate;
|
||||
} RLEstate;
|
||||
|
||||
IGL_INLINE static int
|
||||
std_fread(RLEstate * /*rleInfo*/, unsigned char *buf, size_t datasize, size_t nelems, FILE *fp)
|
||||
{
|
||||
if (_verbose > 1) {
|
||||
totbytes += nelems * datasize;
|
||||
printf("TGA: std_fread %d (total %d)\n",
|
||||
(int)(nelems * datasize), totbytes);
|
||||
}
|
||||
return fread(buf, datasize, nelems, fp);
|
||||
}
|
||||
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define RLE_PACKETSIZE 0x80
|
||||
|
||||
/* Decode a bufferful of file. */
|
||||
IGL_INLINE static int
|
||||
rle_fread(RLEstate *rleInfo, unsigned char *vbuf, size_t datasize, size_t nelems, FILE *fp)
|
||||
{
|
||||
|
||||
unsigned char *buf = vbuf;
|
||||
int j, k;
|
||||
int buflen, count, bytes, curbytes;
|
||||
unsigned char *p;
|
||||
|
||||
/* Scale the buffer length. */
|
||||
buflen = nelems * datasize;
|
||||
|
||||
j = 0;
|
||||
curbytes = totbytes;
|
||||
while (j < buflen) {
|
||||
if (rleInfo->laststate < rleInfo->statelen) {
|
||||
/* Copy bytes from our previously decoded buffer. */
|
||||
bytes = MIN(buflen - j, rleInfo->statelen - rleInfo->laststate);
|
||||
memcpy(buf + j, rleInfo->statebuf + rleInfo->laststate, bytes);
|
||||
j += bytes;
|
||||
rleInfo->laststate += bytes;
|
||||
|
||||
/* If we used up all of our state bytes, then reset them. */
|
||||
if (rleInfo->laststate >= rleInfo->statelen) {
|
||||
rleInfo->laststate = 0;
|
||||
rleInfo->statelen = 0;
|
||||
}
|
||||
|
||||
/* If we filled the buffer, then exit the loop. */
|
||||
if (j >= buflen) break;
|
||||
}
|
||||
|
||||
/* Decode the next packet. */
|
||||
count = fgetc(fp);
|
||||
if (count == EOF) {
|
||||
if (_verbose) printf("TGA: hit EOF while looking for count\n");
|
||||
return j / datasize;
|
||||
}
|
||||
|
||||
/* Scale the byte length to the size of the data. */
|
||||
bytes = ((count & ~RLE_PACKETSIZE) + 1) * datasize;
|
||||
|
||||
if (j + bytes <= buflen) {
|
||||
/* We can copy directly into the image buffer. */
|
||||
p = buf + j;
|
||||
} else {
|
||||
#ifdef PROFILE
|
||||
printf("TGA: needed to use statebuf for %d bytes\n", buflen - j);
|
||||
#endif
|
||||
/* Allocate the state buffer if we haven't already. */
|
||||
if (!rleInfo->statebuf) {
|
||||
rleInfo->statebuf = (unsigned char *) malloc(RLE_PACKETSIZE * datasize);
|
||||
}
|
||||
p = rleInfo->statebuf;
|
||||
}
|
||||
|
||||
if (count & RLE_PACKETSIZE) {
|
||||
/* Fill the buffer with the next value. */
|
||||
if (fread(p, datasize, 1, fp) != 1) {
|
||||
if (_verbose) {
|
||||
printf("TGA: EOF while reading %d/%d element RLE packet\n",
|
||||
bytes, (int)datasize);
|
||||
}
|
||||
return j / datasize;
|
||||
}
|
||||
|
||||
/* Optimized case for single-byte encoded data. */
|
||||
if (datasize == 1) {
|
||||
memset(p + 1, *p, bytes - 1);
|
||||
} else {
|
||||
for (k = datasize; k < bytes; k += datasize) {
|
||||
memcpy(p + k, p, datasize);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Read in the buffer. */
|
||||
if (fread(p, bytes, 1, fp) != 1) {
|
||||
if (_verbose) {
|
||||
printf("TGA: EOF while reading %d/%d element raw packet\n",
|
||||
bytes, (int)datasize);
|
||||
}
|
||||
return j / datasize;
|
||||
}
|
||||
}
|
||||
|
||||
if (_verbose > 1) {
|
||||
totbytes += bytes;
|
||||
if (_verbose > 2) {
|
||||
printf("TGA: %s packet %d/%d\n",
|
||||
(count & RLE_PACKETSIZE) ? "RLE" : "raw",
|
||||
bytes, totbytes);
|
||||
}
|
||||
}
|
||||
|
||||
/* We may need to copy bytes from the state buffer. */
|
||||
if (p == rleInfo->statebuf) {
|
||||
rleInfo->statelen = bytes;
|
||||
} else {
|
||||
j += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (_verbose > 1) {
|
||||
printf("TGA: rle_fread %d/%d (total %d)\n",
|
||||
(int) ( nelems * datasize), totbytes - curbytes, totbytes);
|
||||
}
|
||||
return nelems;
|
||||
}
|
||||
|
||||
IGL_INLINE igl::opengl::gliGenericImage *
|
||||
igl::opengl::gliReadTGA(FILE *fp, char *name, int /*hflip*/, int vflip)
|
||||
{
|
||||
igl::opengl::TgaHeader tgaHeader;
|
||||
igl::opengl::TgaFooter tgaFooter;
|
||||
char horzrev, vertrev;
|
||||
int width, height, bpp;
|
||||
int start, end, dir;
|
||||
int i, j, k;
|
||||
int pelbytes, wbytes;
|
||||
GLenum format;
|
||||
int components;
|
||||
RLEstate rleRec;
|
||||
RLEstate *rleInfo;
|
||||
int rle;
|
||||
int index, colors, length;
|
||||
GLubyte *cmap, *pixels, *data;
|
||||
int (*myfread)(RLEstate *rleInfo, unsigned char*, size_t, size_t, FILE*);
|
||||
igl::opengl::gliGenericImage *genericImage;
|
||||
|
||||
/* Check the footer. */
|
||||
if (fseek(fp, 0L - sizeof(tgaFooter), SEEK_END)
|
||||
|| fread(&tgaFooter, sizeof(tgaFooter), 1, fp) != 1) {
|
||||
sprintf(error, "TGA: Cannot read footer from \"%s\"", name);
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check the signature. */
|
||||
if (memcmp(tgaFooter.signature, TGA_SIGNATURE,
|
||||
sizeof(tgaFooter.signature)) == 0) {
|
||||
if (_verbose) printf("TGA: found New TGA\n");
|
||||
} else {
|
||||
if (_verbose) printf("TGA: found Original TGA\n");
|
||||
}
|
||||
|
||||
if (fseek(fp, 0, SEEK_SET) ||
|
||||
fread(&tgaHeader, sizeof(tgaHeader), 1, fp) != 1) {
|
||||
sprintf(error, "TGA: Cannot read header from \"%s\"", name);
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_verbose && tgaHeader.idLength) {
|
||||
char *idString = (char*) malloc(tgaHeader.idLength);
|
||||
|
||||
if (fread(idString, tgaHeader.idLength, 1, fp) != 1) {
|
||||
sprintf(error, "TGA: Cannot read ID field in \"%s\"", name);
|
||||
printf("%s\n", error);
|
||||
} else {
|
||||
printf("TGA: ID field: \"%*s\"\n", tgaHeader.idLength, idString);
|
||||
}
|
||||
free(idString);
|
||||
} else {
|
||||
/* Skip the image ID field. */
|
||||
if (tgaHeader.idLength && fseek(fp, tgaHeader.idLength, SEEK_CUR)) {
|
||||
sprintf(error, "TGA: Cannot skip ID field in \"%s\"", name);
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reassemble the multi-byte values correctly, regardless of
|
||||
host endianness. */
|
||||
width = (tgaHeader.widthHi << 8) | tgaHeader.widthLo;
|
||||
height = (tgaHeader.heightHi << 8) | tgaHeader.heightLo;
|
||||
bpp = tgaHeader.bpp;
|
||||
if (_verbose) {
|
||||
printf("TGA: width=%d, height=%d, bpp=%d\n", width, height, bpp);
|
||||
}
|
||||
|
||||
horzrev = tgaHeader.descriptor & TGA_DESC_HORIZONTAL;
|
||||
vertrev = tgaHeader.descriptor & TGA_DESC_VERTICAL;
|
||||
//vertrev=0;
|
||||
|
||||
// // JASON - we can force this stuff if we want
|
||||
// if( hflip )
|
||||
// horzrev = 1;
|
||||
if( vflip )
|
||||
vertrev = 1;
|
||||
|
||||
if (_verbose && horzrev) printf("TGA: horizontal reversed\n");
|
||||
if (_verbose && vertrev) printf("TGA: vertical reversed\n");
|
||||
|
||||
rle = 0;
|
||||
switch (tgaHeader.imageType) {
|
||||
case TGA_TYPE_MAPPED_RLE:
|
||||
rle = 1;
|
||||
if (_verbose) printf("TGA: run-length encoded\n");
|
||||
case TGA_TYPE_MAPPED:
|
||||
/* Test for alpha channel. */
|
||||
format = GL_COLOR_INDEX;
|
||||
components = 1;
|
||||
if (_verbose) {
|
||||
printf("TGA: %d bit indexed image (%d bit palette)\n",
|
||||
tgaHeader.colorMapSize, bpp);
|
||||
}
|
||||
break;
|
||||
|
||||
case TGA_TYPE_GRAY_RLE:
|
||||
rle = 1;
|
||||
if (_verbose) printf("TGA: run-length encoded\n");
|
||||
case TGA_TYPE_GRAY:
|
||||
format = GL_LUMINANCE;
|
||||
components = 1;
|
||||
if (_verbose) printf("TGA: %d bit grayscale image\n", bpp);
|
||||
break;
|
||||
|
||||
case TGA_TYPE_COLOR_RLE:
|
||||
rle = 1;
|
||||
if (_verbose) printf("TGA: run-length encoded\n");
|
||||
case TGA_TYPE_COLOR:
|
||||
/* Test for alpha channel. */
|
||||
if (bpp == 32) {
|
||||
format = GL_BGRA_EXT;
|
||||
components = 4;
|
||||
if (_verbose) {
|
||||
printf("TGA: %d bit color image with alpha channel\n", bpp);
|
||||
}
|
||||
} else {
|
||||
format = GL_BGR_EXT;
|
||||
components = 3;
|
||||
if (_verbose) printf("TGA: %d bit color image\n", bpp);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(error,
|
||||
"TGA: unrecognized image type %d\n", tgaHeader.imageType);
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((format == GL_BGRA_EXT && bpp != 32) ||
|
||||
(format == GL_BGR_EXT && bpp != 24) ||
|
||||
((format == GL_LUMINANCE || format == GL_COLOR_INDEX) && bpp != 8)) {
|
||||
/* FIXME: We haven't implemented bit-packed fields yet. */
|
||||
fprintf(stderr, "bpp %d, format %x\n", bpp, (unsigned int)format);
|
||||
sprintf(error, "TGA: channel sizes other than 8 bits are unimplemented");
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check that we have a color map only when we need it. */
|
||||
if (format == GL_COLOR_INDEX) {
|
||||
if (tgaHeader.colorMapType != 1) {
|
||||
sprintf(error, "TGA: indexed image has invalid color map type %d\n",
|
||||
tgaHeader.colorMapType);
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
} else if (tgaHeader.colorMapType != 0) {
|
||||
sprintf(error, "TGA: non-indexed image has invalid color map type %d\n",
|
||||
tgaHeader.colorMapType);
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tgaHeader.colorMapType == 1) {
|
||||
/* We need to read in the colormap. */
|
||||
index = (tgaHeader.colorMapIndexHi << 8) | tgaHeader.colorMapIndexLo;
|
||||
length = (tgaHeader.colorMapLengthHi << 8) | tgaHeader.colorMapLengthLo;
|
||||
|
||||
if (_verbose) {
|
||||
printf("TGA: reading color map (%d + %d) * (%d / 8)\n",
|
||||
index, length, tgaHeader.colorMapSize);
|
||||
}
|
||||
if (length == 0) {
|
||||
sprintf(error, "TGA: invalid color map length %d", length);
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
if (tgaHeader.colorMapSize != 24) {
|
||||
/* We haven't implemented bit-packed fields yet. */
|
||||
sprintf(error, "TGA: channel sizes other than 8 bits are unimplemented");
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pelbytes = tgaHeader.colorMapSize / 8;
|
||||
colors = length + index;
|
||||
cmap = (GLubyte*)malloc (colors * pelbytes);
|
||||
|
||||
/* Zero the entries up to the beginning of the map. */
|
||||
memset(cmap, 0, index * pelbytes);
|
||||
|
||||
/* Read in the rest of the colormap. */
|
||||
if (fread(cmap, pelbytes, length, fp) != (size_t) length) {
|
||||
sprintf(error, "TGA: error reading colormap (ftell == %ld)\n",
|
||||
ftell (fp));
|
||||
if (_verbose) printf("%s\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pelbytes >= 3) {
|
||||
/* Rearrange the colors from BGR to RGB. */
|
||||
int tmp;
|
||||
for (j = index; j < length * pelbytes; j += pelbytes) {
|
||||
tmp = cmap[j];
|
||||
cmap[j] = cmap[j + 2];
|
||||
cmap[j + 2] = tmp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
colors = 0;
|
||||
cmap = NULL;
|
||||
}
|
||||
|
||||
/* Allocate the data. */
|
||||
pelbytes = bpp / 8;
|
||||
pixels = (unsigned char *) malloc (width * height * pelbytes);
|
||||
|
||||
if (rle) {
|
||||
rleRec.statebuf = 0;
|
||||
rleRec.statelen = 0;
|
||||
rleRec.laststate = 0;
|
||||
rleInfo = &rleRec;
|
||||
myfread = rle_fread;
|
||||
} else {
|
||||
rleInfo = NULL;
|
||||
myfread = std_fread;
|
||||
}
|
||||
|
||||
wbytes = width * pelbytes;
|
||||
|
||||
if (vertrev) {
|
||||
start = 0;
|
||||
end = height;
|
||||
dir = 1;
|
||||
} else {
|
||||
/* We need to reverse loading order of rows. */
|
||||
start = height-1;
|
||||
end = -1;
|
||||
dir = -1;
|
||||
}
|
||||
|
||||
for (i = start; i != end; i += dir) {
|
||||
data = pixels + i*wbytes;
|
||||
|
||||
/* Suck in the data one row at a time. */
|
||||
if (myfread(rleInfo, data, pelbytes, width, fp) != width) {
|
||||
/* Probably premature end of file. */
|
||||
if (_verbose) {
|
||||
printf ("TGA: error reading (ftell == %ld, width=%d)\n",
|
||||
ftell(fp), width);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (horzrev) {
|
||||
/* We need to mirror row horizontally. */
|
||||
for (j = 0; j < width/2; j++) {
|
||||
GLubyte tmp;
|
||||
|
||||
for (k = 0; k < pelbytes; k++) {
|
||||
tmp = data[j*pelbytes+k];
|
||||
data[j*pelbytes+k] = data[(width-j-1)*pelbytes+k];
|
||||
data[(width-j-1)*pelbytes+k] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rle) {
|
||||
free(rleInfo->statebuf);
|
||||
}
|
||||
|
||||
if (fgetc (fp) != EOF) {
|
||||
if (_verbose) printf ("TGA: too much input data, ignoring extra...\n");
|
||||
}
|
||||
|
||||
genericImage = (igl::opengl::gliGenericImage*) malloc(sizeof(igl::opengl::gliGenericImage));
|
||||
genericImage->width = width;
|
||||
genericImage->height = height;
|
||||
genericImage->format = format;
|
||||
genericImage->components = components;
|
||||
genericImage->cmapEntries = colors;
|
||||
genericImage->cmapFormat = GL_BGR_EXT; // XXX fix me
|
||||
genericImage->cmap = cmap;
|
||||
genericImage->pixels = pixels;
|
||||
|
||||
return genericImage;
|
||||
}
|
||||
|
||||
IGL_INLINE int igl::opengl::gli_verbose(int new_verbose)
|
||||
{
|
||||
_verbose = new_verbose;
|
||||
return _verbose;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// added 10/2005, Denis Zorin
|
||||
// a very simple TGA output, supporting
|
||||
// uncompressed luminance RGB and RGBA
|
||||
// G22.2270 students: this is C (no C++)
|
||||
// so this is not the style I would encourage
|
||||
// you to use; I used it for consistency
|
||||
// with the rest of the code in this file
|
||||
|
||||
|
||||
// fixed header values for the subset of TGA we use for writing
|
||||
unsigned char TGAHeaderColor[12] =
|
||||
{ 0,// 0 ID length = no id
|
||||
0,// 1 color map type = no color map
|
||||
2,// 2 image type = uncompressed true color
|
||||
0, 0, 0, 0, 0,// color map spec = empty
|
||||
0, 0, // x origin of image
|
||||
0, 0 // y origin of image
|
||||
};
|
||||
|
||||
unsigned char TGAHeaderBW[12] =
|
||||
{ 0,// 0 ID length = no id
|
||||
0,// 1 color map type = no color map
|
||||
3,// 3 image type = uncompressed black and white
|
||||
0, 0, 0, 0, 0,// color map spec = empty
|
||||
0, 0, // x origin of image
|
||||
0, 0 // y origin of image
|
||||
};
|
||||
|
||||
// this makes sure that
|
||||
// image size is written in correct format
|
||||
// and byte order (least first)
|
||||
IGL_INLINE void write16bit(int n, FILE* fp) {
|
||||
unsigned char bytes[] = { static_cast<unsigned char>(n % 256), static_cast<unsigned char>(n / 256) };
|
||||
fwrite(bytes, 2, sizeof(unsigned char),fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
IGL_INLINE void igl::opengl::writeTGA( igl::opengl::gliGenericImage* image, FILE *fp) {
|
||||
|
||||
assert(!image->cmap); // we do not deal with color map images
|
||||
|
||||
if(image->components == 3 || image->components == 4)
|
||||
fwrite(TGAHeaderColor, 12, sizeof(unsigned char),fp);
|
||||
else {
|
||||
if(image->components == 1 )
|
||||
fwrite(TGAHeaderBW, 12, sizeof(unsigned char),fp);
|
||||
else { fprintf(stderr,"Supported component number: 1,3 or 4\n"); exit(1); }
|
||||
}
|
||||
|
||||
write16bit(image->width,fp);
|
||||
write16bit(image->height,fp);
|
||||
switch (image->components ) {
|
||||
case 1:
|
||||
putc(8,fp);
|
||||
break;
|
||||
case 3:
|
||||
putc(24,fp);
|
||||
break;
|
||||
case 4:
|
||||
putc(32,fp);
|
||||
break;
|
||||
default: fprintf(stderr,"Supported component number: 1,3 or 4\n"); exit(1);
|
||||
};
|
||||
|
||||
if(image-> components == 4)
|
||||
putc(0x04,fp); // bottom left image (0x00) + 8 bit alpha (0x4)
|
||||
else
|
||||
putc(0x00,fp);
|
||||
|
||||
fwrite(image->pixels, image->height*image->width*image->components, sizeof(char),fp);
|
||||
}
|
||||
|
||||
106
src/libigl/igl/copyleft/opengl2/tga.h
Normal file
106
src/libigl/igl/copyleft/opengl2/tga.h
Normal file
@@ -0,0 +1,106 @@
|
||||
// This file is part of libigl, a simple c++ geometry processing library.
|
||||
//
|
||||
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public License
|
||||
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
// obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#ifndef IGL_OPENGL_TGA_H
|
||||
#define IGL_OPENGL_TGA_H
|
||||
#include "../../igl_inline.h"
|
||||
|
||||
#include "../../opengl2/gl.h"
|
||||
// See license in tga.cpp
|
||||
/* tga.h - interface for TrueVision (TGA) image file loader */
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace igl
|
||||
{
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
|
||||
GLsizei width;
|
||||
GLsizei height;
|
||||
GLint components;
|
||||
GLenum format;
|
||||
|
||||
GLsizei cmapEntries;
|
||||
GLenum cmapFormat;
|
||||
GLubyte *cmap;
|
||||
|
||||
GLubyte *pixels;
|
||||
|
||||
} gliGenericImage;
|
||||
|
||||
typedef struct {
|
||||
unsigned char idLength;
|
||||
unsigned char colorMapType;
|
||||
|
||||
/* The image type. */
|
||||
#define TGA_TYPE_MAPPED 1
|
||||
#define TGA_TYPE_COLOR 2
|
||||
#define TGA_TYPE_GRAY 3
|
||||
#define TGA_TYPE_MAPPED_RLE 9
|
||||
#define TGA_TYPE_COLOR_RLE 10
|
||||
#define TGA_TYPE_GRAY_RLE 11
|
||||
unsigned char imageType;
|
||||
|
||||
/* Color Map Specification. */
|
||||
/* We need to separately specify high and low bytes to avoid endianness
|
||||
and alignment problems. */
|
||||
unsigned char colorMapIndexLo, colorMapIndexHi;
|
||||
unsigned char colorMapLengthLo, colorMapLengthHi;
|
||||
unsigned char colorMapSize;
|
||||
|
||||
/* Image Specification. */
|
||||
unsigned char xOriginLo, xOriginHi;
|
||||
unsigned char yOriginLo, yOriginHi;
|
||||
|
||||
unsigned char widthLo, widthHi;
|
||||
unsigned char heightLo, heightHi;
|
||||
|
||||
unsigned char bpp;
|
||||
|
||||
/* Image descriptor.
|
||||
3-0: attribute bpp
|
||||
4: left-to-right ordering
|
||||
5: top-to-bottom ordering
|
||||
7-6: zero
|
||||
*/
|
||||
#define TGA_DESC_ABITS 0x0f
|
||||
#define TGA_DESC_HORIZONTAL 0x10
|
||||
#define TGA_DESC_VERTICAL 0x20
|
||||
unsigned char descriptor;
|
||||
|
||||
} TgaHeader;
|
||||
|
||||
typedef struct {
|
||||
unsigned int extensionAreaOffset;
|
||||
unsigned int developerDirectoryOffset;
|
||||
#define TGA_SIGNATURE "TRUEVISION-XFILE"
|
||||
char signature[16];
|
||||
char dot;
|
||||
char null;
|
||||
} TgaFooter;
|
||||
|
||||
IGL_INLINE extern gliGenericImage *gliReadTGA(FILE *fp, char *name, int hflip, int vflip);
|
||||
IGL_INLINE int gli_verbose(int new_verbose);
|
||||
IGL_INLINE extern int gliVerbose(int newVerbose);
|
||||
|
||||
IGL_INLINE void writeTGA( gliGenericImage* image, FILE *fp);
|
||||
|
||||
|
||||
|
||||
} // end of igl namespace
|
||||
}
|
||||
|
||||
#ifndef IGL_STATIC_LIBRARY
|
||||
# include "tga.cpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user