mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-26 05:50:32 +05:00
250 lines
6.1 KiB
C
250 lines
6.1 KiB
C
/*
|
|
* SGI rgb file reader borrowed from gltk library
|
|
*/
|
|
|
|
#include "togl.h" /* added by GG to include windows.h */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "image.h"
|
|
|
|
#ifndef SEEK_SET
|
|
# define SEEK_SET 0
|
|
#endif
|
|
|
|
|
|
static void
|
|
tkQuit(void)
|
|
{
|
|
exit(0);
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
typedef struct _rawImageRec
|
|
{
|
|
unsigned short imagic;
|
|
unsigned short type;
|
|
unsigned short dim;
|
|
unsigned short sizeX, sizeY, sizeZ;
|
|
unsigned long min, max;
|
|
unsigned long wasteBytes;
|
|
char name[80];
|
|
unsigned long colorMap;
|
|
FILE *file;
|
|
unsigned char *tmp, *tmpR, *tmpG, *tmpB, *tmpA;
|
|
unsigned long rleEnd;
|
|
GLuint *rowStart;
|
|
GLint *rowSize;
|
|
} rawImageRec;
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
static void
|
|
ConvertShort(unsigned short *array, long length)
|
|
{
|
|
unsigned long b1, b2;
|
|
unsigned char *ptr;
|
|
|
|
ptr = (unsigned char *) array;
|
|
while (length--) {
|
|
b1 = *ptr++;
|
|
b2 = *ptr++;
|
|
*array++ = (b1 << 8) | (b2);
|
|
}
|
|
}
|
|
|
|
static void
|
|
ConvertLong(GLuint *array, long length)
|
|
{
|
|
unsigned long b1, b2, b3, b4;
|
|
unsigned char *ptr;
|
|
|
|
ptr = (unsigned char *) array;
|
|
while (length--) {
|
|
b1 = *ptr++;
|
|
b2 = *ptr++;
|
|
b3 = *ptr++;
|
|
b4 = *ptr++;
|
|
*array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
|
|
}
|
|
}
|
|
|
|
static rawImageRec *
|
|
RawImageOpen(char *fileName)
|
|
{
|
|
union
|
|
{
|
|
int testWord;
|
|
char testByte[4];
|
|
} endianTest;
|
|
rawImageRec *raw;
|
|
GLenum swapFlag;
|
|
int x;
|
|
|
|
endianTest.testWord = 1;
|
|
if (endianTest.testByte[0] == 1) {
|
|
swapFlag = GL_TRUE;
|
|
} else {
|
|
swapFlag = GL_FALSE;
|
|
}
|
|
|
|
raw = (rawImageRec *) malloc(sizeof (rawImageRec));
|
|
if (raw == NULL) {
|
|
fprintf(stderr, "Out of memory!\n");
|
|
tkQuit();
|
|
}
|
|
if ((raw->file = fopen(fileName, "rb")) == NULL) {
|
|
perror(fileName);
|
|
tkQuit();
|
|
}
|
|
|
|
fread(raw, 1, 12, raw->file);
|
|
|
|
if (swapFlag) {
|
|
ConvertShort(&raw->imagic, 6);
|
|
}
|
|
|
|
raw->tmp = (unsigned char *) malloc(raw->sizeX * 256);
|
|
raw->tmpR = (unsigned char *) malloc(raw->sizeX * 256);
|
|
raw->tmpG = (unsigned char *) malloc(raw->sizeX * 256);
|
|
raw->tmpB = (unsigned char *) malloc(raw->sizeX * 256);
|
|
raw->tmpA = (unsigned char *) malloc(raw->sizeX * 256);
|
|
if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
|
|
raw->tmpB == NULL || raw->tmpA == NULL) {
|
|
fprintf(stderr, "Out of memory!\n");
|
|
tkQuit();
|
|
}
|
|
|
|
if ((raw->type & 0xFF00) == 0x0100) {
|
|
x = raw->sizeY * raw->sizeZ * sizeof (GLuint);
|
|
raw->rowStart = (GLuint *) malloc(x);
|
|
raw->rowSize = (GLint *) malloc(x);
|
|
if (raw->rowStart == NULL || raw->rowSize == NULL) {
|
|
fprintf(stderr, "Out of memory!\n");
|
|
tkQuit();
|
|
}
|
|
raw->rleEnd = 512 + (2 * x);
|
|
fseek(raw->file, 512, SEEK_SET);
|
|
fread(raw->rowStart, 1, x, raw->file);
|
|
fread(raw->rowSize, 1, x, raw->file);
|
|
if (swapFlag) {
|
|
ConvertLong(raw->rowStart, x / sizeof (GLuint));
|
|
ConvertLong((GLuint *) raw->rowSize, x / sizeof (GLint));
|
|
}
|
|
}
|
|
return raw;
|
|
}
|
|
|
|
static void
|
|
RawImageClose(rawImageRec * raw)
|
|
{
|
|
|
|
fclose(raw->file);
|
|
free(raw->tmp);
|
|
free(raw->tmpR);
|
|
free(raw->tmpG);
|
|
free(raw->tmpB);
|
|
free(raw->tmpA);
|
|
free(raw);
|
|
}
|
|
|
|
static void
|
|
RawImageGetRow(rawImageRec * raw, unsigned char *buf, int y, int z)
|
|
{
|
|
unsigned char *iPtr, *oPtr, pixel;
|
|
int count;
|
|
|
|
if ((raw->type & 0xFF00) == 0x0100) {
|
|
fseek(raw->file, raw->rowStart[y + z * raw->sizeY], SEEK_SET);
|
|
fread(raw->tmp, 1, (unsigned int) raw->rowSize[y + z * raw->sizeY],
|
|
raw->file);
|
|
|
|
iPtr = raw->tmp;
|
|
oPtr = buf;
|
|
while (1) {
|
|
pixel = *iPtr++;
|
|
count = (int) (pixel & 0x7F);
|
|
if (!count) {
|
|
return;
|
|
}
|
|
if (pixel & 0x80) {
|
|
while (count--) {
|
|
*oPtr++ = *iPtr++;
|
|
}
|
|
} else {
|
|
pixel = *iPtr++;
|
|
while (count--) {
|
|
*oPtr++ = pixel;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
fseek(raw->file, 512 + (y * raw->sizeX) + (z * raw->sizeX * raw->sizeY),
|
|
SEEK_SET);
|
|
fread(buf, 1, raw->sizeX, raw->file);
|
|
}
|
|
}
|
|
|
|
static void
|
|
RawImageGetData(rawImageRec * raw, TK_RGBImageRec * final)
|
|
{
|
|
unsigned char *ptr;
|
|
int i, j;
|
|
|
|
final->data =
|
|
(unsigned char *) malloc((raw->sizeX + 1) * (raw->sizeY + 1) * 4);
|
|
if (final->data == NULL) {
|
|
fprintf(stderr, "Out of memory!\n");
|
|
tkQuit();
|
|
}
|
|
|
|
ptr = final->data;
|
|
for (i = 0; i < (int) (raw->sizeY); i++) {
|
|
RawImageGetRow(raw, raw->tmpR, i, 0);
|
|
RawImageGetRow(raw, raw->tmpG, i, 1);
|
|
RawImageGetRow(raw, raw->tmpB, i, 2);
|
|
if (raw->sizeZ == 4) {
|
|
/* 4 components */
|
|
RawImageGetRow(raw, raw->tmpA, i, 3);
|
|
for (j = 0; j < (int) (raw->sizeX); j++) {
|
|
*ptr++ = *(raw->tmpR + j);
|
|
*ptr++ = *(raw->tmpG + j);
|
|
*ptr++ = *(raw->tmpB + j);
|
|
*ptr++ = *(raw->tmpA + j);
|
|
}
|
|
} else {
|
|
/* 3 components */
|
|
for (j = 0; j < (int) (raw->sizeX); j++) {
|
|
*ptr++ = *(raw->tmpR + j);
|
|
*ptr++ = *(raw->tmpG + j);
|
|
*ptr++ = *(raw->tmpB + j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TK_RGBImageRec *
|
|
tkRGBImageLoad(char *fileName)
|
|
{
|
|
rawImageRec *raw;
|
|
TK_RGBImageRec *final;
|
|
|
|
raw = RawImageOpen(fileName);
|
|
final = (TK_RGBImageRec *) malloc(sizeof (TK_RGBImageRec));
|
|
if (final == NULL) {
|
|
fprintf(stderr, "Out of memory!\n");
|
|
tkQuit();
|
|
}
|
|
final->sizeX = raw->sizeX;
|
|
final->sizeY = raw->sizeY;
|
|
final->sizeZ = raw->sizeZ;
|
|
RawImageGetData(raw, final);
|
|
RawImageClose(raw);
|
|
return final;
|
|
}
|
|
|
|
/******************************************************************************/
|