2016-11-09 18:14:35 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* apps/graphics/traveler/tools/libwld/wld_loadpcx.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
|
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
|
|
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
|
|
|
* used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* FILE: wld_loadpcx.c
|
|
|
|
* DESCRIPTION: This file contains the logic which loads a PCX file.
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Compilation Options
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Included files
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
#include "trv_types.h"
|
|
|
|
#include "wld_mem.h"
|
|
|
|
#if (!MSWINDOWS)
|
|
|
|
#include "wld_bitmaps.h"
|
|
|
|
#include "wld_graphicfile.h"
|
|
|
|
#endif
|
|
|
|
#include "wld_pcx.h"
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Definitions
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Private Type Declarations
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Private Function Prototypes
|
|
|
|
*************************************************************************/
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
static void wld_loadpcxHeader(FILE *fp, pcxHeader *header);
|
|
|
|
static void wld_loadpcxData(FILE *fp, sint32 imagSize, uint8_t *imageBuffer);
|
|
|
|
static void wld_loadpcxPalette(FILE *fp, RGBColor *palette);
|
2016-11-09 18:14:35 +01:00
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Global Variables
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Private Variables
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
/*************************************************************************
|
2016-11-09 19:29:30 +01:00
|
|
|
* Name: wld_loadpcx
|
2016-11-09 18:14:35 +01:00
|
|
|
* Description:
|
|
|
|
* This function loads a pcx file into a picture structure, the actual image
|
|
|
|
* data for the pcx file is decompressed and expanded into a secondary buffer
|
|
|
|
* within the picture structure, the separate images can be grabbed from this
|
|
|
|
* buffer later. also the header and palette are loaded
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#if MSWINDOWS
|
2016-11-09 19:29:30 +01:00
|
|
|
uint8_t wld_loadpcx(char *filename, pcxPicturePtr image)
|
2016-11-09 18:14:35 +01:00
|
|
|
{
|
|
|
|
FILE *fp, *fopen();
|
|
|
|
uint16_t imageWidth, imageHeight;
|
|
|
|
uint32 imageSize;
|
|
|
|
|
|
|
|
/* Open the file */
|
|
|
|
|
|
|
|
fp = fopen(filename,"rb");
|
|
|
|
if (!fp) return PCX_OPEN_ERROR;
|
|
|
|
|
|
|
|
/* Load the PCX Header */
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
wld_loadpcxHeader(fp, &image->header);
|
2016-11-09 18:14:35 +01:00
|
|
|
|
|
|
|
/* Load the PCX data */
|
|
|
|
|
|
|
|
if (image->buffer)
|
|
|
|
{
|
|
|
|
imageWidth = image->header.width - image->header.x + 1;
|
|
|
|
imageHeight = image->header.height - image->header.y + 1;
|
|
|
|
imageSize = imageHeight * imageWidth;
|
2016-11-09 19:29:30 +01:00
|
|
|
wld_loadpcxData(fp, imageSize, image->buffer);
|
2016-11-09 18:14:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Load the PCX palette */
|
|
|
|
|
|
|
|
if (image->palette)
|
|
|
|
{
|
2016-11-09 19:29:30 +01:00
|
|
|
wld_loadpcxPalette(fp, &image->palette);
|
2016-11-09 18:14:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
return PCX_SUCCESS;
|
|
|
|
}
|
|
|
|
#else
|
2016-11-09 19:29:30 +01:00
|
|
|
GraphicFileType *wld_loadpcx(FILE *fp, char *filename)
|
2016-11-09 18:14:35 +01:00
|
|
|
{
|
|
|
|
pcxHeader header;
|
|
|
|
trv_pixel_t *buffer;
|
|
|
|
GraphicFileType *gFile;
|
|
|
|
RGBColor *palette;
|
|
|
|
uint16_t imageWidth, imageHeight;
|
|
|
|
uint32 imageSize;
|
|
|
|
|
|
|
|
/* Load the PCX Header */
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
wld_loadpcxHeader(fp, &header);
|
2016-11-09 18:14:35 +01:00
|
|
|
|
|
|
|
/* Allocate Space to hold the image data */
|
|
|
|
|
|
|
|
imageWidth = header.width - header.x + 1;
|
|
|
|
imageHeight = header.height - header.y + 1;
|
|
|
|
imageSize = imageHeight * imageWidth * sizeof(trv_pixel_t);
|
2016-11-09 19:29:30 +01:00
|
|
|
buffer = (trv_pixel_t*)wld_malloc(imageSize + 1);
|
2016-11-09 18:14:35 +01:00
|
|
|
|
|
|
|
/* Load the PCX data into the buffer */
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
wld_loadpcxData(fp, imageSize, (uint8_t*)buffer);
|
2016-11-09 18:14:35 +01:00
|
|
|
|
|
|
|
/* Allocate space to hold the PCX palette */
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
palette = (RGBColor*)wld_malloc(sizeof(RGBColor) * 256);
|
2016-11-09 18:14:35 +01:00
|
|
|
|
|
|
|
/* Load the PCX palette */
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
wld_loadpcxPalette(fp, palette);
|
2016-11-09 18:14:35 +01:00
|
|
|
|
|
|
|
/* Now save the resulting data in a GraphicFileType structure */
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
gFile = wld_new_graphicfile();
|
2016-11-09 18:14:35 +01:00
|
|
|
gFile->type = gfPaletted;
|
|
|
|
gFile->palette = palette;
|
|
|
|
gFile->width = imageWidth;
|
|
|
|
gFile->height = imageHeight;
|
|
|
|
gFile->bitmap = buffer;
|
|
|
|
|
|
|
|
return gFile;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*************************************************************************
|
2016-11-09 19:29:30 +01:00
|
|
|
* Name: wld_loadpcxHeader
|
2016-11-09 18:14:35 +01:00
|
|
|
* Description:
|
|
|
|
************************************************************************/
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
static void wld_loadpcxHeader(FILE *fp, pcxHeader *header)
|
2016-11-09 18:14:35 +01:00
|
|
|
{
|
|
|
|
uint8_t *tempBuffer;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Load the header */
|
|
|
|
|
|
|
|
tempBuffer = (uint8_t*)header;
|
|
|
|
|
|
|
|
for (i = 0; i < SIZEOF_PCX_HEADER; i++)
|
|
|
|
{
|
|
|
|
tempBuffer[i] = getc(fp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
2016-11-09 19:29:30 +01:00
|
|
|
* Name: wld_loadpcxData
|
2016-11-09 18:14:35 +01:00
|
|
|
* Description:
|
|
|
|
************************************************************************/
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
static void wld_loadpcxData(FILE *fp, sint32 imageSize, uint8_t *imageBuffer)
|
2016-11-09 18:14:35 +01:00
|
|
|
{
|
|
|
|
uint32 count;
|
|
|
|
int16_t numBytes;
|
|
|
|
uint8_t data;
|
|
|
|
|
|
|
|
count = 0;
|
|
|
|
while(count <= imageSize)
|
|
|
|
{
|
|
|
|
/* Get the first piece of data */
|
|
|
|
|
|
|
|
data = getc(fp);
|
|
|
|
|
|
|
|
/* Is this a run length encoding? */
|
|
|
|
|
|
|
|
if ((data >= 192) /* && (data <= 255) */)
|
|
|
|
{
|
|
|
|
/* How many bytes in run? */
|
|
|
|
|
|
|
|
numBytes = data - 192;
|
|
|
|
|
|
|
|
/* Get the actual data for the run */
|
|
|
|
|
|
|
|
data = getc(fp);
|
|
|
|
|
|
|
|
/* Replicate data in buffer numBytes times */
|
|
|
|
|
|
|
|
while(numBytes-- > 0)
|
|
|
|
{
|
|
|
|
imageBuffer[count++] = data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Actual data, just copy it into buffer at next location */
|
|
|
|
|
|
|
|
imageBuffer[count++] = data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
2016-11-09 19:29:30 +01:00
|
|
|
* Name: wld_loadpcxPalette
|
2016-11-09 18:14:35 +01:00
|
|
|
* Description:
|
|
|
|
************************************************************************/
|
|
|
|
|
2016-11-09 19:29:30 +01:00
|
|
|
static void wld_loadpcxPalette(FILE *fp, RGBColor *palette)
|
2016-11-09 18:14:35 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Move to end of file then back up 768 bytes i.e. to begining of palette */
|
|
|
|
|
|
|
|
fseek(fp, -768L, SEEK_END);
|
|
|
|
|
|
|
|
/* Load the PCX palette into the palette structure */
|
|
|
|
|
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
{
|
|
|
|
/* Get the RGB components */
|
|
|
|
|
|
|
|
#if MSWINDOWS
|
|
|
|
palette[i].red = (getc(fp) >> 2);
|
|
|
|
palette[i].green = (getc(fp) >> 2);
|
|
|
|
palette[i].blue = (getc(fp) >> 2);
|
|
|
|
#else
|
|
|
|
palette[i].red = getc(fp);
|
|
|
|
palette[i].green = getc(fp);
|
|
|
|
palette[i].blue = getc(fp);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|