?? tga.c
字號:
/* Copyright (C) 2000 Marco Ziech (mmz@gmx.net) Copyright (C) 2000 Ross Combs (rocombs@cs.nmsu.edu) 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 "common/setup_before.h"#include <stdio.h>#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif#endif#include <errno.h>#include "compat/strerror.h"#include "fileio.h"#include "tga.h"#include "common/setup_after.h"static int rotate_updown(t_tgaimg *img);static int rotate_leftright(t_tgaimg *img);static int RLE_decompress(FILE *f, void *buf, int bufsize, int pixelsize);static void RLE_write_pkt(FILE *f, t_tgapkttype pkttype, int len, void *data, int pixelsize);static int RLE_compress(FILE *f, t_tgaimg const *img);static int rotate_updown(t_tgaimg *img) { unsigned char *ndata; int pixelsize; int y; if (img == NULL) return -1; if (img->data == NULL) return -1; pixelsize = getpixelsize(img); if (pixelsize == 0) return -1; ndata = malloc(img->width*img->height*pixelsize); for (y = 0; y < img->height; y++) { memcpy(ndata + (y*img->width*pixelsize), img->data + ((img->width*img->height*pixelsize)-((y+1)*img->width*pixelsize)), img->width*pixelsize); } free(img->data); img->data = ndata; return 0;}static int rotate_leftright(t_tgaimg *img) { unsigned char *ndata, *datap; int pixelsize; int y,x; fprintf(stderr,"WARNING: rotate_leftright: this function is untested!\n"); if (img == NULL) return -1; if (img->data == NULL) return -1; pixelsize = getpixelsize(img); if (pixelsize == 0) return -1; ndata = malloc(img->width*img->height*pixelsize); datap = img->data; for (y = 0; y < img->height; y++) { unsigned char *linep = (ndata + (((y+1)*img->width*pixelsize)-pixelsize)); for (x = 0; x < img->width; x++) { memcpy(linep,datap,pixelsize); linep -= pixelsize; datap += pixelsize; } } free(img->data); img->data = ndata; return 0;}extern int getpixelsize(t_tgaimg const *img) { switch (img->bpp) { case 8: return 1; case 15: case 16: return 2; case 24: return 3; case 32: return 4; default: fprintf(stderr,"load_tga: color depth %u is not supported!\n",img->bpp); return 0; }}extern t_tgaimg * new_tgaimg(unsigned int width, unsigned int height, unsigned int bpp, t_tgaimgtype imgtype) { t_tgaimg *img; img = malloc(sizeof(t_tgaimg)); img->idlen = 0; img->cmaptype = tgacmap_none; img->imgtype = imgtype; img->cmapfirst = 0; img->cmaplen = 0; img->cmapes = 0; img->xorigin = 0; img->yorigin = 0; img->width = width; img->height = height; img->bpp = bpp; img->desc = 0; /* no attribute bits, top, left, and zero reserved */ img->data = NULL; img->extareaoff = 0; img->devareaoff = 0; return img;}extern t_tgaimg * load_tgaheader(void) { t_tgaimg *img; img = malloc(sizeof(t_tgaimg)); img->idlen = file_readb(); img->cmaptype = file_readb(); img->imgtype = file_readb(); img->cmapfirst = file_readw_le(); img->cmaplen = file_readw_le(); img->cmapes = file_readb(); img->xorigin = file_readw_le(); img->yorigin = file_readw_le(); img->width = file_readw_le(); img->height = file_readw_le(); img->bpp = file_readb(); img->desc = file_readb(); img->data = NULL; img->extareaoff = 0; /* ignored when reading */ img->devareaoff = 0; /* ignored when reading */ return img;}extern t_tgaimg * load_tga(FILE *f) { t_tgaimg *img; int pixelsize; file_rpush(f); img = load_tgaheader(); /* make sure we understand the header fields */ if (img->cmaptype != tgacmap_none) { fprintf(stderr,"load_tga: Color-mapped images are not (yet?) supported!\n"); free(img); return NULL; } if (img->imgtype!=tgaimgtype_uncompressed_truecolor && img->imgtype!=tgaimgtype_rlecompressed_truecolor) { fprintf(stderr,"load_tga: imagetype %u is not supported. (only 2 and 10 are supported)\n",img->imgtype); free(img); return NULL; } pixelsize = getpixelsize(img); if (pixelsize == 0) { free(img); return NULL; } /* Skip the ID if there is one */ if (img->idlen > 0) { fprintf(stderr,"load_tga: ID present, skipping %d bytes\n",img->idlen); if (fseek(f,img->idlen,SEEK_CUR)<0) fprintf(stderr,"load_tga: could not seek %u bytes forward (fseek: %s)\n",img->idlen,pstrerror(errno)); } /* Now, we can alloc img->data */ img->data = malloc(img->width*img->height*pixelsize); if (img->imgtype == tgaimgtype_uncompressed_truecolor) { if (fread(img->data,pixelsize,img->width*img->height,f)<(unsigned)(img->width*img->height)) { fprintf(stderr,"load_tga: error while reading data!\n"); free(img->data); free(img); return NULL; } } else { /* == tgaimgtype_rlecompressed_truecolor */ if (RLE_decompress(f,img->data,img->width*img->height*pixelsize,pixelsize) < 0) { fprintf(stderr,"load_tga: error while decompressing data!\n"); free(img->data); free(img); return NULL; } } file_rpop(); if ((img->desc & tgadesc_horz) == 1) { /* right, want left */ if (rotate_leftright(img)<0) { fprintf(stderr,"ERROR: rotate_leftright failed!\n"); } } if ((img->desc & tgadesc_vert) == 0) { /* bottom, want top */ if (rotate_updown(img)<0) { fprintf(stderr,"ERROR: rotate_updown failed!\n"); } } return img;}extern int write_tga(FILE *f, t_tgaimg *img) { if (f == NULL) return -1; if (img == NULL) return -1; if (img->data == NULL) return -1; if (img->idlen!=0) return -1; if (img->cmaptype!=tgacmap_none) return -1; if (img->imgtype!=tgaimgtype_uncompressed_truecolor && img->imgtype!=tgaimgtype_rlecompressed_truecolor) return -1; file_wpush(f); file_writeb(img->idlen); file_writeb(img->cmaptype); file_writeb(img->imgtype); file_writew_le(img->cmapfirst); file_writew_le(img->cmaplen); file_writeb(img->cmapes); file_writew_le(img->xorigin); file_writew_le(img->yorigin); file_writew_le(img->width); file_writew_le(img->height); file_writeb(img->bpp); file_writeb(img->desc); if ((img->desc&tgadesc_horz)==1) { /* right, want left */ fprintf(stderr,"write_tga: flipping horizontally\n"); if (rotate_leftright(img)<0) { fprintf(stderr,"ERROR: rotate_updown failed!\n"); } } if ((img->desc&tgadesc_vert)==0) { /* bottom, want top */ fprintf(stderr,"write_tga: flipping vertically\n"); if (rotate_updown(img)<0) { fprintf(stderr,"ERROR: rotate_updown failed!\n"); } } if (img->imgtype==tgaimgtype_uncompressed_truecolor) { int pixelsize; pixelsize = getpixelsize(img); if (pixelsize == 0) return -1; if (fwrite(img->data,pixelsize,img->width*img->height,f)<(unsigned)(img->width*img->height)) { fprintf(stderr,"write_tga: could not write %d pixels (fwrite: %s)\n",img->width*img->height,pstrerror(errno)); file_wpop(); return -1; } } else if (img->imgtype==tgaimgtype_rlecompressed_truecolor) { fprintf(stderr,"write_tga: using RLE compression\n"); if (RLE_compress(f,img)<0) { fprintf(stderr,"write_tga: RLE compression failed.\n"); } } /* Write the file-footer */ file_writed_le(img->extareaoff); file_writed_le(img->devareaoff); if (fwrite(TGAMAGIC,strlen(TGAMAGIC)+1,1,f)<1)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -