- Add JPEG support

- Refactor call to LoadTGA so it returns image_t * directly
This commit is contained in:
Daniel Gibson 2012-03-11 16:50:57 +00:00
parent ccf45a3b6e
commit 441c988b31
4 changed files with 202 additions and 15 deletions

View file

@ -41,6 +41,13 @@ CC := gcc
# ----------
# Options
# Enables .jpg texture support
JPEG := 1
# ----------
# Base CFLAGS.
#
# -O2 are enough optimizations.
@ -169,6 +176,11 @@ build/refresher/%.o: %.c
release/ref_gl.so : CFLAGS += -fPIC
release/ref_gl.so : LDFLAGS += -shared
ifdef JPEG
release/ref_gl.so : CFLAGS += -DWITH_JPEG
release/ref_gl.so : LDFLAGS += -ljpeg
endif
# ----------
@ -376,6 +388,7 @@ OPENGL_OBJS_ = \
src/refresh/files/pcx.o \
src/refresh/files/sp2.o \
src/refresh/files/tga.o \
src/refresh/files/jpeg.o \
src/refresh/files/wal.o \
src/sdl/input.o \
src/sdl/refresh.o \

168
src/refresh/files/jpeg.c Normal file
View file

@ -0,0 +1,168 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
*
* 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.
*
* =======================================================================
*
* The JPEG image format
*
* =======================================================================
*/
#ifdef WITH_JPEG
#include "../header/local.h"
#include <jpeglib.h>
/*
=================================================================
JPEG LOADING
NiceAss: Code from Q2Ice
=================================================================
*/
void jpg_null(j_decompress_ptr cinfo)
{
}
boolean jpg_fill_input_buffer(j_decompress_ptr cinfo)
{
ri.Con_Printf(PRINT_ALL, "Premature end of JPEG data\n");
return 1;
}
void jpg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
cinfo->src->next_input_byte += (size_t) num_bytes;
cinfo->src->bytes_in_buffer -= (size_t) num_bytes;
}
void jpeg_mem_src (j_decompress_ptr cinfo, byte *mem, int len)
{
cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr));
cinfo->src->init_source = jpg_null;
cinfo->src->fill_input_buffer = jpg_fill_input_buffer;
cinfo->src->skip_input_data = jpg_skip_input_data;
cinfo->src->resync_to_restart = jpeg_resync_to_restart;
cinfo->src->term_source = jpg_null;
cinfo->src->bytes_in_buffer = len;
cinfo->src->next_input_byte = mem;
}
/*
==============
LoadJPG
==============
*/
image_t *
LoadJPG (char *filename, int *width, int *height, imagetype_t type)
{
byte *pic = NULL;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
byte *rawdata, *rgbadata, *scanline, *p, *q;
unsigned int rawsize, i;
// Load JPEG file into memory
rawsize = ri.FS_LoadFile(filename, (void **)&rawdata);
if (!rawdata)
return NULL;
if (rawsize < 10 || rawdata[6] != 'J' || rawdata[7] != 'F' || rawdata[8] != 'I' || rawdata[9] != 'F')
{
ri.Con_Printf (PRINT_ALL, "Invalid JPEG header: %s\n", filename);
ri.FS_FreeFile(rawdata);
return NULL;
}
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, rawdata, rawsize);
jpeg_read_header(&cinfo, true);
jpeg_start_decompress(&cinfo);
if(cinfo.output_components != 3 && cinfo.output_components != 4)
{
ri.Con_Printf(PRINT_ALL, "Invalid JPEG colour components\n");
jpeg_destroy_decompress(&cinfo);
ri.FS_FreeFile(rawdata);
return NULL;
}
// Allocate Memory for decompressed image
rgbadata = malloc(cinfo.output_width * cinfo.output_height * 4);
if(!rgbadata)
{
ri.Con_Printf(PRINT_ALL, "Insufficient memory for JPEG buffer\n");
jpeg_destroy_decompress(&cinfo);
ri.FS_FreeFile(rawdata);
return NULL;
}
// Pass sizes to output
*width = cinfo.output_width;
*height = cinfo.output_height;
// Allocate Scanline buffer
scanline = malloc (cinfo.output_width * 3);
if (!scanline)
{
ri.Con_Printf (PRINT_ALL, "Insufficient memory for JPEG scanline buffer\n");
free (rgbadata);
jpeg_destroy_decompress (&cinfo);
ri.FS_FreeFile (rawdata);
return NULL;
}
// Read Scanlines, and expand from RGB to RGBA
q = rgbadata;
while (cinfo.output_scanline < cinfo.output_height)
{
p = scanline;
jpeg_read_scanlines(&cinfo, &scanline, 1);
for (i = 0; i < cinfo.output_width; i++)
{
q[0] = p[0];
q[1] = p[1];
q[2] = p[2];
q[3] = 255;
p += 3;
q += 4;
}
}
free (scanline);
jpeg_finish_decompress (&cinfo);
jpeg_destroy_decompress (&cinfo);
pic = rgbadata;
if ( !pic )
{
return ( NULL );
}
return R_LoadPic( filename, pic, *width, *height, type, 32 );
}
#endif // WITH_JPEG

View file

@ -35,9 +35,10 @@ typedef struct _TargaHeader
unsigned char pixel_size, attributes;
} TargaHeader;
void
LoadTGA ( char *name, byte **pic, int *width, int *height )
image_t *
LoadTGA ( char *name, int *width, int *height, imagetype_t type )
{
byte *pic = NULL;
int columns, rows, numPixels;
byte *pixbuf;
int row, column;
@ -48,15 +49,13 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
byte *targa_rgba;
byte tmp [ 2 ];
*pic = NULL;
/* load the file */
length = ri.FS_LoadFile( name, (void **) &buffer );
if ( !buffer )
{
ri.Con_Printf( PRINT_DEVELOPER, "Bad tga file %s\n", name );
return;
return NULL;
}
buf_p = buffer;
@ -112,7 +111,7 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
}
targa_rgba = malloc( numPixels * 4 );
*pic = targa_rgba;
pic = targa_rgba;
if ( targa_header.id_length != 0 )
{
@ -271,5 +270,12 @@ LoadTGA ( char *name, byte **pic, int *width, int *height )
}
ri.FS_FreeFile( buffer );
if ( !pic )
{
return ( NULL );
}
return R_LoadPic( name, pic, *width, *height, type, 32 );
}

View file

@ -52,7 +52,10 @@ int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
int gl_filter_max = GL_LINEAR;
image_t *LoadWal ( char *name );
void LoadTGA ( char *name, byte **pic, int *width, int *height );
image_t *LoadTGA ( char *name, int *width, int *height, imagetype_t type );
#ifdef WITH_JPEG
image_t *LoadJPG (char *filename, int *width, int *height, imagetype_t type);
#endif
int Draw_GetPalette ( void );
typedef struct
@ -1066,14 +1069,11 @@ R_FindImage ( char *name, imagetype_t type )
}
else if ( !strcmp( name + len - 4, ".tga" ) )
{
LoadTGA( name, &pic, &width, &height );
if ( !pic )
{
return ( NULL );
}
image = R_LoadPic( name, pic, width, height, type, 32 );
return LoadTGA( name, &width, &height, type );
}
else if ( !strcmp( name + len - 4, ".jpg" ) )
{
return LoadJPG( name, &width, &height, type );
}
else
{