Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <stdio.h></stdio.h>
Toshihiro Shimizu 890ddd
#include <string.h></string.h>
Toshihiro Shimizu 890ddd
#include <stdlib.h></stdlib.h>
Toshihiro Shimizu 890ddd
#include <math.h></math.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "../compatibility/tnz4.h"
Toshihiro Shimizu 890ddd
#include "../compatibility/inforegion.h"
Toshihiro Shimizu 890ddd
#include "filebmp.h"
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
typedef unsigned long  ULONG;
Toshihiro Shimizu 890ddd
typedef unsigned short USHORT;
Toshihiro Shimizu 890ddd
typedef unsigned char  UCHAR;
Toshihiro Shimizu 890ddd
typedef unsigned int   UINT;
Toshihiro Shimizu 890ddd
typedef void IMAGERGB;
Toshihiro Shimizu 890ddd
typedef struct {USHORT m,b,g,r;} SPIXEL;
Toshihiro Shimizu 890ddd
#define CASE break; case
Toshihiro Shimizu 890ddd
#define __OR      ; case
Toshihiro Shimizu 890ddd
#define DEFAULT break; default
Toshihiro Shimizu 890ddd
#define TRUE 1
Toshihiro Shimizu 890ddd
#define FALSE 0
Toshihiro Shimizu 890ddd
#define NIL (void*)0
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef enum {
Shinya Kitaoka 120a6e
  BMP_NONE,
Shinya Kitaoka 120a6e
  BMP_BW,
Shinya Kitaoka 120a6e
  BMP_GREY16,
Shinya Kitaoka 120a6e
  BMP_GREY16C,
Shinya Kitaoka 120a6e
  BMP_GREY256,
Shinya Kitaoka 120a6e
  BMP_GREY256C,
Shinya Kitaoka 120a6e
  BMP_CMAPPED16,
Shinya Kitaoka 120a6e
  BMP_CMAPPED16C,
Shinya Kitaoka 120a6e
  BMP_CMAPPED256,
Shinya Kitaoka 120a6e
  BMP_CMAPPED256C,
Shinya Kitaoka 120a6e
  BMP_RGB
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} BMP_SUBTYPE;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
typedef struct bmpimage {
Shinya Kitaoka 120a6e
        int xsize,ysize;
Shinya Kitaoka 120a6e
        LPIXEL *buffer;
Toshihiro Shimizu 890ddd
  BMP_SUBTYPE type;
Shinya Kitaoka 120a6e
        } IMAGE;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define UNUSED_REDUCE_COLORS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*-- Defines ----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BMP_BI_RGB 0
Toshihiro Shimizu 890ddd
#define BMP_BI_RLE8 1
Toshihiro Shimizu 890ddd
#define BMP_BI_RLE4 2
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BMP_WIN_OS2_OLD 12
Toshihiro Shimizu 890ddd
#define BMP_WIN_NEW 40
Toshihiro Shimizu 890ddd
#define BMP_OS2_NEW 64
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BMP_READ_INFO 1
Toshihiro Shimizu 890ddd
#define BMP_READ_IMAGE 2
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BMP_FERROR(fp) (ferror(fp) || feof(fp))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BMP_RMAP(x) (x & 0xe0) | ((x & 0xe0) >> 3) | ((x & 0xc0) >> 6)
Toshihiro Shimizu 890ddd
#define BMP_GMAP(x) ((x & 0x1c) << 3) | (x & 0x1c) | ((x & 0x18) >> 3)
Shinya Kitaoka 120a6e
#define BMP_BMAP(x)                                                            \
Shinya Kitaoka 120a6e
  ((x & 0x03) << 6) | ((x & 0x03) << 4) | ((x & 0x03) << 2) | (x & 0x03)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
#define BMP_RMAP16(x)                                                          \
Shinya Kitaoka 120a6e
  ((x & 0xc0) << 0) | ((x & 0xc0) >> 2) | ((x & 0xc0) >> 4) | ((x & 0xc0) >> 6)
Shinya Kitaoka 120a6e
#define BMP_GMAP16(x)                                                          \
Shinya Kitaoka 120a6e
  ((x & 0x60) << 1) | ((x & 0x60) >> 1) | ((x & 0x60) >> 3) | ((x & 0x60) >> 5)
Shinya Kitaoka 120a6e
#define BMP_BMAP16(x)                                                          \
Shinya Kitaoka 120a6e
  ((x & 0x30) << 2) | ((x & 0x30) << 0) | ((x & 0x30) >> 2) | ((x & 0x30) >> 4)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
#define BMP_CUT(a, b, c)                                                       \
Shinya Kitaoka 120a6e
  {                                                                            \
Shinya Kitaoka 120a6e
    if (a < b)                                                                 \
Shinya Kitaoka 120a6e
      a = b;                                                                   \
Shinya Kitaoka 120a6e
    else if (a > c)                                                            \
Shinya Kitaoka 120a6e
      a = c;                                                                   \
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
#define BMP_REDUCE_COLORS(r, g, b)                                             \
Shinya Kitaoka 120a6e
  ((r & 0xe0) | ((g & 0xe0) >> 3) | ((b & 0xc0) >> 6))
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
#define BMP_ADD_ERROR(pix, weight)                                             \
Shinya Kitaoka 120a6e
  {                                                                            \
Shinya Kitaoka 120a6e
    tmp = (pix).r + ((r1 * weight) >> 4);                                      \
Shinya Kitaoka 120a6e
    BMP_CUT(tmp, 0, 255);                                                      \
Shinya Kitaoka 120a6e
    (pix).r = tmp;                                                             \
Shinya Kitaoka 120a6e
    tmp     = (pix).g + ((g1 * weight) >> 4);                                  \
Shinya Kitaoka 120a6e
    BMP_CUT(tmp, 0, 255);                                                      \
Shinya Kitaoka 120a6e
    (pix).g = tmp;                                                             \
Shinya Kitaoka 120a6e
    tmp     = (pix).b + ((b1 * weight) >> 4);                                  \
Shinya Kitaoka 120a6e
    BMP_CUT(tmp, 0, 255);                                                      \
Shinya Kitaoka 120a6e
    (pix).b = tmp;                                                             \
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
#define BMP_ADD_ERROR_BW(pix, error)                                           \
Shinya Kitaoka 120a6e
  {                                                                            \
Shinya Kitaoka 120a6e
    tmp = (pix).r + (error);                                                   \
Shinya Kitaoka 120a6e
    BMP_CUT(tmp, 0, 255);                                                      \
Shinya Kitaoka 120a6e
    (pix).r = tmp;                                                             \
Shinya Kitaoka 120a6e
    tmp     = (pix).g + (error);                                               \
Shinya Kitaoka 120a6e
    BMP_CUT(tmp, 0, 255);                                                      \
Shinya Kitaoka 120a6e
    (pix).g = tmp;                                                             \
Shinya Kitaoka 120a6e
    tmp     = (pix).b + (error);                                               \
Shinya Kitaoka 120a6e
    BMP_CUT(tmp, 0, 255);                                                      \
Shinya Kitaoka 120a6e
    (pix).b = tmp;                                                             \
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*-- Structures and Enums ---------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
typedef struct {
Shinya Kitaoka 120a6e
  UINT bfSize;
Shinya Kitaoka 120a6e
  UINT bfOffBits;
Shinya Kitaoka 120a6e
  UINT biSize;
Shinya Kitaoka 120a6e
  UINT biWidth;
Shinya Kitaoka 120a6e
  UINT biHeight;
Shinya Kitaoka 120a6e
  UINT biPlanes;
Shinya Kitaoka 120a6e
  UINT biBitCount;
Shinya Kitaoka 120a6e
  UINT biCompression;
Shinya Kitaoka 120a6e
  UINT biSizeImage;
Shinya Kitaoka 120a6e
  UINT biXPelsPerMeter;
Shinya Kitaoka 120a6e
  UINT biYPelsPerMeter;
Shinya Kitaoka 120a6e
  UINT biClrUsed;
Shinya Kitaoka 120a6e
  UINT biClrImportant;
Shinya Kitaoka 120a6e
  UINT biFilesize;
Shinya Kitaoka 120a6e
  UINT biPad;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} BMP_HEADER;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*-- Prototypes -------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int load_bmp_header(FILE *fp, BMP_HEADER **pHd);
Toshihiro Shimizu 890ddd
int write_bmp_header(FILE *fp, BMP_HEADER *hd);
Toshihiro Shimizu 890ddd
void release_bmp_header(BMP_HEADER *hd);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int write_bmp_palette(FILE *fp, int nc, UCHAR *b, UCHAR *g, UCHAR *r);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int make_bmp_palette(int colors, int grey, UCHAR *r, UCHAR *g, UCHAR *b);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
BMP_SUBTYPE bmp_get_colorstyle(IMAGE *img);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int error_checking_bmp(BMP_HEADER *hd);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int read_bmp_line(FILE *fp, void *line, UINT w, UINT h, UCHAR **map,
Shinya Kitaoka 120a6e
                  BMP_SUBTYPE type);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int write_bmp_line(FILE *fp, void *line_buffer, UINT w, UINT row, UCHAR *map,
Shinya Kitaoka 120a6e
                   BMP_SUBTYPE type);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int skip_bmp_lines(FILE *fp, UINT w, UINT rows, int whence, BMP_SUBTYPE type);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*-- Local Prototypes -------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static UINT getshort(FILE *fp);
Toshihiro Shimizu 890ddd
static UINT getint(FILE *fp);
Toshihiro Shimizu 890ddd
static void putshort(FILE *fp, int value);
Toshihiro Shimizu 890ddd
static void putint(FILE *fp, int value);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int img_read_bmp_generic(const MYSTRING fname, int type, IMAGE **);
Toshihiro Shimizu 890ddd
#ifndef UNUSED_REDUCE_COLORS
Shinya Kitaoka 120a6e
static UCHAR *reduce_colors(UCHAR *buffin, int xsize, int ysize, UCHAR *rmap,
Shinya Kitaoka 120a6e
                            UCHAR *gmap, UCHAR *bmap, int nc);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static int loadBMP1(FILE *fp, LPIXEL *pic, UINT w, UINT h, UCHAR *r, UCHAR *g,
Shinya Kitaoka 120a6e
                    UCHAR *b);
Shinya Kitaoka 120a6e
static int loadBMP4(FILE *fp, LPIXEL *pic, UINT w, UINT h, UINT comp, UCHAR *r,
Shinya Kitaoka 120a6e
                    UCHAR *g, UCHAR *b);
Shinya Kitaoka 120a6e
static int loadBMP8(FILE *fp, LPIXEL *pic, UINT w, UINT h, UINT comp, UCHAR *r,
Shinya Kitaoka 120a6e
                    UCHAR *g, UCHAR *b);
Toshihiro Shimizu 890ddd
static int loadBMP24(FILE *fp, LPIXEL *pic, UINT w, UINT h);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int writeBMP1(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *map);
Toshihiro Shimizu 890ddd
static int writeBMP4(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *map);
Toshihiro Shimizu 890ddd
static int writeBMPC4(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *map);
Toshihiro Shimizu 890ddd
static int writeBMP8(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *map);
Toshihiro Shimizu 890ddd
static int writeBMPC8(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *map);
Toshihiro Shimizu 890ddd
static int writeBMP24(FILE *fp, UCHAR *pic24, UINT w, UINT h, UCHAR *map);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int load_lineBMP1(FILE *fp, LPIXEL *pic, UINT w, UINT padw, UCHAR **map);
Toshihiro Shimizu 890ddd
static int load_lineBMP4(FILE *fp, LPIXEL *pic, UINT w, UINT padw, UCHAR **map);
Toshihiro Shimizu 890ddd
static int load_lineBMPC4(FILE *fp, LPIXEL *pic, UINT w, UINT y, UCHAR **map);
Toshihiro Shimizu 890ddd
static int load_lineBMP8(FILE *fp, LPIXEL *pic, UINT w, UINT padw, UCHAR **map);
Toshihiro Shimizu 890ddd
static int load_lineBMPC8(FILE *fp, LPIXEL *pic, UINT w, UINT y, UCHAR **map);
Toshihiro Shimizu 890ddd
static int load_lineBMP24(FILE *fp, LPIXEL *pic, UINT w, UINT padb);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static int line_writeBMP1(FILE *fp, UCHAR *pic8, UINT w, UINT padw,
Shinya Kitaoka 120a6e
                          UCHAR *pc2nc);
Shinya Kitaoka 120a6e
static int line_writeBMP4(FILE *fp, UCHAR *pic8, UINT w, UINT padw,
Shinya Kitaoka 120a6e
                          UCHAR *pc2nc);
Shinya Kitaoka 120a6e
static int line_writeBMPC4(FILE *fp, UCHAR *pic8, UINT w, UINT row,
Shinya Kitaoka 120a6e
                           UCHAR *pc2nc);
Shinya Kitaoka 120a6e
static int line_writeBMP8(FILE *fp, UCHAR *pic8, UINT w, UINT padw,
Shinya Kitaoka 120a6e
                          UCHAR *pc2nc);
Shinya Kitaoka 120a6e
static int line_writeBMPC8(FILE *fp, UCHAR *pic8, UINT w, UINT row,
Shinya Kitaoka 120a6e
                           UCHAR *pc2nc);
Toshihiro Shimizu 890ddd
static int line_writeBMP24(FILE *fp, LPIXEL *pp, UINT w, UINT padb);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static int skip_rowsBMP1(FILE *fp, UINT w, UINT pad, UINT rows, int whence);
Toshihiro Shimizu 890ddd
static int skip_rowsBMP4(FILE *fp, UINT w, UINT pad, UINT rows, int whence);
Toshihiro Shimizu 890ddd
static int skip_rowsBMPC4(FILE *fp, UINT rows);
Toshihiro Shimizu 890ddd
static int skip_rowsBMP8(FILE *fp, UINT w, UINT pad, UINT rows, int whence);
Toshihiro Shimizu 890ddd
static int skip_rowsBMPC8(FILE *fp, UINT rows);
Toshihiro Shimizu 890ddd
static int skip_rowsBMP24(FILE *fp, UINT w, UINT pad, UINT rows, int whence);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BMP_DEBUG 0
Toshihiro Shimizu 890ddd
#define __BMP_WRITE_LINE_BY_LINE
Toshihiro Shimizu 890ddd
#define __BMP_READ_LINE_BY_LINE
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
int read_bmp_line(FILE *fp, void *line_buffer, UINT w, UINT row, UCHAR **map,
Shinya Kitaoka 120a6e
                  BMP_SUBTYPE type)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  LPIXEL *pic = (LPIXEL *)line_buffer;
Shinya Kitaoka 120a6e
  unsigned int pad;
Shinya Kitaoka 120a6e
  int rv = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (type) {
Shinya Kitaoka 120a6e
  case BMP_BW:
Shinya Kitaoka 120a6e
    pad = ((w + 31) / 32) * 32;
Shinya Kitaoka 120a6e
    rv  = load_lineBMP1(fp, pic, w, pad, map);
Shinya Kitaoka 120a6e
    CASE BMP_GREY16 : __OR BMP_CMAPPED16 : pad = ((w + 7) / 8) * 8;
Shinya Kitaoka 120a6e
    rv = load_lineBMP4(fp, pic, w, pad, map);
Shinya Kitaoka 120a6e
    CASE BMP_GREY16C : __OR BMP_CMAPPED16C
Shinya Kitaoka 120a6e
                       : rv = load_lineBMPC4(fp, pic, w, row, map);
Shinya Kitaoka 120a6e
    if (rv == -1)
Shinya Kitaoka 120a6e
      rv = 1;
Shinya Kitaoka 120a6e
    else if (rv == -2)
Shinya Kitaoka 120a6e
      rv = 0;
Shinya Kitaoka 120a6e
    else if (rv == -3)
Shinya Kitaoka 120a6e
      rv = 0;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      rv                                         = 0;
Shinya Kitaoka 120a6e
    CASE BMP_GREY256 : __OR BMP_CMAPPED256 : pad = ((w + 3) / 4) * 4;
Shinya Kitaoka 120a6e
    rv = load_lineBMP8(fp, pic, w, pad, map);
Shinya Kitaoka 120a6e
    CASE BMP_GREY256C : __OR BMP_CMAPPED256C
Shinya Kitaoka 120a6e
                        : rv = load_lineBMPC8(fp, pic, w, row, map);
Shinya Kitaoka 120a6e
    if (rv == -1)
Shinya Kitaoka 120a6e
      rv = 1;
Shinya Kitaoka 120a6e
    else if (rv == -2)
Shinya Kitaoka 120a6e
      rv = 0;
Shinya Kitaoka 120a6e
    else if (rv == -3)
Shinya Kitaoka 120a6e
      rv = 0;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      rv               = 0;
Shinya Kitaoka 120a6e
    CASE BMP_RGB : pad = (4 - ((w * 3) % 4)) & 0x03;
Shinya Kitaoka 120a6e
    rv                 = load_lineBMP24(fp, pic, w, pad);
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return !rv; /* return 0 for unsuccess */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
int write_bmp_line(FILE *fp, void *line_buffer, UINT w, UINT row, UCHAR *map,
Shinya Kitaoka 120a6e
                   BMP_SUBTYPE type)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UCHAR *pic  = (UCHAR *)line_buffer;
Shinya Kitaoka 120a6e
  LPIXEL *p24 = (LPIXEL *)line_buffer;
Shinya Kitaoka 120a6e
  unsigned int pad;
Shinya Kitaoka 120a6e
  int rv = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (type) {
Shinya Kitaoka 120a6e
  case BMP_BW:
Shinya Kitaoka 120a6e
    pad = ((w + 31) / 32) * 32;
Shinya Kitaoka 120a6e
    rv  = line_writeBMP1(fp, pic, w, pad, map);
Shinya Kitaoka 120a6e
    CASE BMP_GREY16 : __OR BMP_CMAPPED16 : pad = ((w + 7) / 8) * 8;
Shinya Kitaoka 120a6e
    rv = line_writeBMP4(fp, pic, w, pad, map);
Shinya Kitaoka 120a6e
    CASE BMP_GREY16C : __OR BMP_CMAPPED16C
Shinya Kitaoka 120a6e
                       : rv = line_writeBMPC4(fp, pic, w, row, map);
Shinya Kitaoka 120a6e
    CASE BMP_GREY256 : __OR BMP_CMAPPED256 : pad = ((w + 3) / 4) * 4;
Shinya Kitaoka 120a6e
    rv = line_writeBMP8(fp, pic, w, pad, map);
Shinya Kitaoka 120a6e
    CASE BMP_GREY256C : __OR BMP_CMAPPED256C
Shinya Kitaoka 120a6e
                        : rv = line_writeBMPC8(fp, pic, w, row, map);
Shinya Kitaoka 120a6e
    CASE BMP_RGB : pad       = (4 - ((w * 3) % 4)) & 0x03;
Shinya Kitaoka 120a6e
    rv                       = line_writeBMP24(fp, p24, w, pad);
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return rv; /* 0 for unsuccess */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int skip_bmp_lines(FILE *fp, UINT w, UINT rows, int whence, BMP_SUBTYPE type)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  unsigned int pad;
Shinya Kitaoka 120a6e
  int rv = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (type) {
Shinya Kitaoka 120a6e
  case BMP_BW:
Shinya Kitaoka 120a6e
    pad = ((w + 31) / 32) * 32;
Shinya Kitaoka 120a6e
    rv  = skip_rowsBMP1(fp, w, pad, rows, whence);
Shinya Kitaoka 120a6e
    CASE BMP_GREY16 : __OR BMP_CMAPPED16 : pad = ((w + 7) / 8) * 8;
Shinya Kitaoka 120a6e
    rv = skip_rowsBMP4(fp, w, pad, rows, whence);
Shinya Kitaoka 120a6e
    CASE BMP_GREY16C : __OR BMP_CMAPPED16C : rv  = skip_rowsBMPC4(fp, rows);
Shinya Kitaoka 120a6e
    CASE BMP_GREY256 : __OR BMP_CMAPPED256 : pad = ((w + 3) / 4) * 4;
Shinya Kitaoka 120a6e
    rv = skip_rowsBMP8(fp, w, pad, rows, whence);
Shinya Kitaoka 120a6e
    CASE BMP_GREY256C : __OR BMP_CMAPPED256C : rv = skip_rowsBMPC8(fp, rows);
Shinya Kitaoka 120a6e
    CASE BMP_RGB : pad                            = (4 - ((w * 3) % 4)) & 0x03;
Shinya Kitaoka 120a6e
    rv = skip_rowsBMP24(fp, w, pad, rows, whence);
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return !rv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int error_checking_bmp(BMP_HEADER *hd)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  /* error checking */
Shinya Kitaoka 120a6e
  if ((hd->biBitCount != 1 && hd->biBitCount != 4 && hd->biBitCount != 8 &&
Shinya Kitaoka 120a6e
       hd->biBitCount != 24) ||
Shinya Kitaoka 120a6e
      hd->biPlanes != 1 || hd->biCompression > BMP_BI_RLE4) {
Shinya Kitaoka 120a6e
    return UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* error checking */
Shinya Kitaoka 120a6e
  if (((hd->biBitCount == 1 || hd->biBitCount == 24) &&
Shinya Kitaoka 120a6e
       hd->biCompression != BMP_BI_RGB) ||
Shinya Kitaoka 120a6e
      (hd->biBitCount == 4 && hd->biCompression == BMP_BI_RLE8) ||
Shinya Kitaoka 120a6e
      (hd->biBitCount == 8 && hd->biCompression == BMP_BI_RLE4)) {
Shinya Kitaoka 120a6e
    return UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return OK;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int load_bmp_header(FILE *fp, BMP_HEADER **header)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  BMP_HEADER *hd = NULL;
Shinya Kitaoka 120a6e
  int c, c1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  *header = NULL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  hd = (BMP_HEADER *)calloc((size_t)1, sizeof(BMP_HEADER));
Shinya Kitaoka 120a6e
  if (!hd) return OUT_OF_MEMORY;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* figure out the file size */
Shinya Kitaoka 120a6e
  fseek(fp, 0L, SEEK_END);
Shinya Kitaoka 120a6e
  hd->biFilesize = ftell(fp);
Shinya Kitaoka 120a6e
  fseek(fp, 0L, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* read the file type (first two bytes) */
Shinya Kitaoka 120a6e
  c  = getc(fp);
Shinya Kitaoka 120a6e
  c1 = getc(fp);
Shinya Kitaoka 120a6e
  if (c != 'B' || c1 != 'M') {
Shinya Kitaoka 120a6e
    free(hd);
Shinya Kitaoka 120a6e
    return UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  hd->bfSize = getint(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* reserved and ignored */
Shinya Kitaoka 120a6e
  getshort(fp);
Shinya Kitaoka 120a6e
  getshort(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  hd->bfOffBits = getint(fp);
Shinya Kitaoka 120a6e
  hd->biSize    = getint(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (hd->biSize == BMP_WIN_NEW || hd->biSize == BMP_OS2_NEW) {
Shinya Kitaoka 120a6e
    hd->biWidth         = getint(fp);
Shinya Kitaoka 120a6e
    hd->biHeight        = getint(fp);
Shinya Kitaoka 120a6e
    hd->biPlanes        = getshort(fp);
Shinya Kitaoka 120a6e
    hd->biBitCount      = getshort(fp);
Shinya Kitaoka 120a6e
    hd->biCompression   = getint(fp);
Shinya Kitaoka 120a6e
    hd->biSizeImage     = getint(fp);
Shinya Kitaoka 120a6e
    hd->biXPelsPerMeter = getint(fp);
Shinya Kitaoka 120a6e
    hd->biYPelsPerMeter = getint(fp);
Shinya Kitaoka 120a6e
    hd->biClrUsed       = getint(fp);
Shinya Kitaoka 120a6e
    hd->biClrImportant  = getint(fp);
Shinya Kitaoka 120a6e
  } else /* old bitmap format */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    hd->biWidth    = getshort(fp);
Shinya Kitaoka 120a6e
    hd->biHeight   = getshort(fp);
Shinya Kitaoka 120a6e
    hd->biPlanes   = getshort(fp);
Shinya Kitaoka 120a6e
    hd->biBitCount = getshort(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /* Not in old versions so have to compute them */
Shinya Kitaoka 120a6e
    hd->biSizeImage =
Shinya Kitaoka 120a6e
        (((hd->biPlanes * hd->biBitCount * hd->biWidth) + 31) / 32) * 4 *
Shinya Kitaoka 120a6e
        hd->biHeight;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    hd->biCompression   = BMP_BI_RGB;
Shinya Kitaoka 120a6e
    hd->biXPelsPerMeter = 0;
Shinya Kitaoka 120a6e
    hd->biYPelsPerMeter = 0;
Shinya Kitaoka 120a6e
    hd->biClrUsed       = 0;
Shinya Kitaoka 120a6e
    hd->biClrImportant  = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_DEBUG) {
Shinya Kitaoka 120a6e
    printf("\nLoadBMP:\tbfSize=%u, bfOffBits=%u\n", hd->bfSize, hd->bfOffBits);
Shinya Kitaoka 120a6e
    printf("\t\tbiSize=%u, biWidth=%u, biHeight=%u, biPlanes=%u\n", hd->biSize,
Shinya Kitaoka 120a6e
           hd->biWidth, hd->biHeight, hd->biPlanes);
Shinya Kitaoka 120a6e
    printf("\t\tbiBitCount=%u, biCompression=%u, biSizeImage=%u\n",
Shinya Kitaoka 120a6e
           hd->biBitCount, hd->biCompression, hd->biSizeImage);
Shinya Kitaoka 120a6e
    printf("\t\tbiX,YPelsPerMeter=%u,%u  biClrUsed=%u, biClrImp=%u\n",
Shinya Kitaoka 120a6e
           hd->biXPelsPerMeter, hd->biYPelsPerMeter, hd->biClrUsed,
Shinya Kitaoka 120a6e
           hd->biClrImportant);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) {
Shinya Kitaoka 120a6e
    free(hd);
Shinya Kitaoka 120a6e
    return UNEXPECTED_EOF;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  *header = hd;
Shinya Kitaoka 120a6e
  return OK;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
void release_bmp_header(BMP_HEADER *hd)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  if (hd) free(hd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef __LIBSIMAGE__
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int img_read_bmp(const MYSTRING fname, IMAGE **pimg)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  return img_read_bmp_generic(fname, BMP_READ_IMAGE, pimg);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int img_read_bmp_generic(const MYSTRING fname, int type, IMAGE **pimg)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int retCode = OK;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UCHAR r[256], g[256], b[256];
Shinya Kitaoka 120a6e
  BMP_HEADER *hd = NULL;
Shinya Kitaoka 120a6e
  IMAGE *img     = NULL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int rv, c, i;
Shinya Kitaoka 120a6e
  LPIXEL *pic;
Shinya Kitaoka 120a6e
  FILE *fp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  *pimg = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* returns  'NULL' on unsuccess */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pic = (LPIXEL *)NULL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* open image file */
Shinya Kitaoka 120a6e
  fp = _wfopen(fname, L"rb");
Shinya Kitaoka 120a6e
  if (!fp) return CANT_OPEN_FILE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* load up the image header */
Shinya Kitaoka 120a6e
  retCode = load_bmp_header(fp, &hd);
Shinya Kitaoka 120a6e
  if (retCode != OK) goto ERROR;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* error checking */
Shinya Kitaoka 120a6e
  if ((hd->biBitCount != 1 && hd->biBitCount != 4 && hd->biBitCount != 8 &&
Shinya Kitaoka 120a6e
       hd->biBitCount != 24) ||
Shinya Kitaoka 120a6e
      hd->biPlanes != 1 || hd->biCompression > BMP_BI_RLE4) {
Shinya Kitaoka 120a6e
    retCode = UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* error checking */
Shinya Kitaoka 120a6e
  if (((hd->biBitCount == 1 || hd->biBitCount == 24) &&
Shinya Kitaoka 120a6e
       hd->biCompression != BMP_BI_RGB) ||
Shinya Kitaoka 120a6e
      (hd->biBitCount == 4 && hd->biCompression == BMP_BI_RLE8) ||
Shinya Kitaoka 120a6e
      (hd->biBitCount == 8 && hd->biCompression == BMP_BI_RLE4)) {
Shinya Kitaoka 120a6e
    retCode = UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  img       = new_img();
Shinya Kitaoka 120a6e
  img->type = TOONZRGB;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (type == BMP_READ_INFO) {
Shinya Kitaoka 120a6e
    fclose(fp);
Shinya Kitaoka 120a6e
    img->xSBsize = img->xsize = hd->biWidth;
Shinya Kitaoka 120a6e
    img->ySBsize = img->ysize = hd->biHeight;
Shinya Kitaoka 120a6e
    release_bmp_header(hd);
Shinya Kitaoka 120a6e
    *pimg = img;
Shinya Kitaoka 120a6e
    return OK;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  allocate_pixmap(img, (int)hd->biWidth, (int)hd->biHeight);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* hd->biPad; */
Shinya Kitaoka 120a6e
  if (hd->biSize != BMP_WIN_OS2_OLD) {
Shinya Kitaoka 120a6e
    /* skip ahead to colormap, using biSize */
Shinya Kitaoka 120a6e
    c = hd->biSize - 40; /* 40 bytes read from biSize to biClrImportant */
Shinya Kitaoka 120a6e
    for (i    = 0; i < c; i++) getc(fp);
Shinya Kitaoka 120a6e
    hd->biPad = hd->bfOffBits - (hd->biSize + 14);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* load up colormap, if any */
Shinya Kitaoka 120a6e
  if (hd->biBitCount != 24) {
Shinya Kitaoka 120a6e
    int i, cmaplen;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*cmaplen = (hd->biClrUsed) ? hd->biClrUsed : 1 << hd->biBitCount;*/
Shinya Kitaoka 120a6e
    if (hd->biClrUsed)
Shinya Kitaoka 120a6e
      cmaplen = hd->biClrUsed;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      cmaplen = 1 << hd->biBitCount;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (i = 0; i < cmaplen; i++) {
Shinya Kitaoka 120a6e
      b[i] = getc(fp);
Shinya Kitaoka 120a6e
      g[i] = getc(fp);
Shinya Kitaoka 120a6e
      r[i] = getc(fp);
Shinya Kitaoka 120a6e
      if (hd->biSize != BMP_WIN_OS2_OLD) {
Shinya Kitaoka 120a6e
        getc(fp);
Shinya Kitaoka 120a6e
        hd->biPad -= 4;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (BMP_FERROR(fp)) {
Shinya Kitaoka 120a6e
      retCode = UNEXPECTED_EOF;
Shinya Kitaoka 120a6e
      goto ERROR;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (BMP_DEBUG) {
Shinya Kitaoka 120a6e
      printf("LoadBMP:  BMP colormap:  (RGB order)\n");
Shinya Kitaoka 120a6e
      for (i = 0; i < cmaplen; i++) printf("%02x%02x%02x  ", r[i], g[i], b[i]);
Shinya Kitaoka 120a6e
      printf("\n\n");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (hd->biSize != BMP_WIN_OS2_OLD) {
Shinya Kitaoka 120a6e
    /* Waste any unused bytes between the colour map (if present)
Shinya Kitaoka 120a6e
and the start of the actual bitmap data.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (hd->biPad > 0) {
Shinya Kitaoka 120a6e
      (void)getc(fp);
Shinya Kitaoka 120a6e
      hd->biPad--;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* create 32 bit image buffer */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pic = (LPIXEL *)img->buffer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* load up the image */
Shinya Kitaoka 120a6e
  switch (hd->biBitCount) {
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    rv          = loadBMP1(fp, pic, hd->biWidth, hd->biHeight, r, g, b);
Shinya Kitaoka 120a6e
    CASE 4 : rv = loadBMP4(fp, pic, hd->biWidth, hd->biHeight,
Shinya Kitaoka 120a6e
                           hd->biCompression, r, g, b);
Shinya Kitaoka 120a6e
    CASE 8 : rv = loadBMP8(fp, pic, hd->biWidth, hd->biHeight,
Shinya Kitaoka 120a6e
                           hd->biCompression, r, g, b);
Shinya Kitaoka 120a6e
    CASE 24 : rv = loadBMP24(fp, pic, hd->biWidth, hd->biHeight);
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    retCode = UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (rv) {
Shinya Kitaoka 120a6e
    retCode = UNEXPECTED_EOF;
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fclose(fp);
Shinya Kitaoka 120a6e
  release_bmp_header(hd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  *pimg = img;
Shinya Kitaoka 120a6e
  return OK;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ERROR:
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  fclose(fp);
Shinya Kitaoka 120a6e
  release_bmp_header(hd);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (img) {
Shinya Kitaoka 120a6e
    TFREE(img->buffer)
Shinya Kitaoka 120a6e
    TFREE(img)
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return retCode;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif /* __LIBSIMAGE__ */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static int img_read_bmp_region(const MYSTRING fname, IMAGE **pimg, int x1,
Shinya Kitaoka 120a6e
                               int y1, int x2, int y2, int scale) {
Shinya Kitaoka 120a6e
  UCHAR r[256], g[256], b[256] /*  ,*map[3]  */;
Shinya Kitaoka 120a6e
  LPIXEL *line   = NULL;
Shinya Kitaoka 120a6e
  UINT line_size = 0;
Shinya Kitaoka 120a6e
  BMP_HEADER *hd = NULL;
Shinya Kitaoka 120a6e
  EXT_INFO_REGION info;
Shinya Kitaoka 120a6e
  BMP_SUBTYPE subtype;
Shinya Kitaoka 120a6e
  LPIXEL *pic, *appo;
Shinya Kitaoka 120a6e
  IMAGE *img = NULL;
Shinya Kitaoka 120a6e
  UINT start_offset;
Shinya Kitaoka 120a6e
  UINT c, i, j;
Shinya Kitaoka 120a6e
  char buf[512];
Shinya Kitaoka 120a6e
  FILE *fp;
Shinya Kitaoka 120a6e
  UINT pad;
Shinya Kitaoka 120a6e
  enum BMP_ERROR_CODE bmp_error = OK;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* initialize some variables */
Shinya Kitaoka 120a6e
  i = pad = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* returns  'NULL' on unsuccess */
Shinya Kitaoka 120a6e
  pic = (LPIXEL *)NULL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* open image file */
Shinya Kitaoka 120a6e
  fp = _wfopen(fname, L"rb");
Shinya Kitaoka 120a6e
  if (!fp) {
Shinya Kitaoka 120a6e
    return CANT_OPEN_FILE;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* load up the image header */
Shinya Kitaoka 120a6e
  load_bmp_header(fp, &hd);
Shinya Kitaoka 120a6e
  if (!hd) goto ERROR;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* error checking */
Shinya Kitaoka 120a6e
  if ((hd->biBitCount != 1 && hd->biBitCount != 4 && hd->biBitCount != 8 &&
Shinya Kitaoka 120a6e
       hd->biBitCount != 24) ||
Shinya Kitaoka 120a6e
      hd->biPlanes != 1 || hd->biCompression > BMP_BI_RLE4) {
Rozhuk Ivan 823a31
    snprintf(buf, sizeof(buf),
Rozhuk Ivan 823a31
             "Bogus BMP File! (bitCount=%d, Planes=%d, Compression=%d)",
Rozhuk Ivan 823a31
             hd->biBitCount, hd->biPlanes, hd->biCompression);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bmp_error = UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* error checking */
Shinya Kitaoka 120a6e
  if (((hd->biBitCount == 1 || hd->biBitCount == 24) &&
Shinya Kitaoka 120a6e
       hd->biCompression != BMP_BI_RGB) ||
Shinya Kitaoka 120a6e
      (hd->biBitCount == 4 && hd->biCompression == BMP_BI_RLE8) ||
Shinya Kitaoka 120a6e
      (hd->biBitCount == 8 && hd->biCompression == BMP_BI_RLE4)) {
Rozhuk Ivan 823a31
    snprintf(buf, sizeof(buf),
Rozhuk Ivan 823a31
             "Bogus BMP File!  (bitCount=%d, Compression=%d)",
Rozhuk Ivan 823a31
             hd->biBitCount, hd->biCompression);
Shinya Kitaoka 120a6e
    bmp_error = UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  img = new_img();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  img->type = TOONZRGB;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  img->xsize   = hd->biWidth;
Shinya Kitaoka 120a6e
  img->ysize   = hd->biHeight;
Shinya Kitaoka 120a6e
  img->xSBsize = hd->biWidth;
Shinya Kitaoka 120a6e
  img->ySBsize = hd->biHeight;
Shinya Kitaoka 120a6e
  img->x_dpi   = (double)(hd->biXPelsPerMeter / 39);
Shinya Kitaoka 120a6e
  img->y_dpi   = (double)(hd->biYPelsPerMeter / 39);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  hd->biPad = 0;
Shinya Kitaoka 120a6e
  if (hd->biSize != BMP_WIN_OS2_OLD) {
Shinya Kitaoka 120a6e
    /* skip ahead to colormap, using biSize */
Shinya Kitaoka 120a6e
    c = hd->biSize - 40; /* 40 bytes read from biSize to biClrImportant */
Shinya Kitaoka 120a6e
    for (i    = 0; i < c; i++) getc(fp);
Shinya Kitaoka 120a6e
    hd->biPad = hd->bfOffBits - (hd->biSize + 14);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* load up colormap, if any */
Shinya Kitaoka 120a6e
  if (hd->biBitCount != 24) {
Shinya Kitaoka 120a6e
    int i, cmaplen;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*cmaplen = (hd->biClrUsed) ? hd->biClrUsed : 1 << hd->biBitCount;*/
Shinya Kitaoka 120a6e
    if (hd->biClrUsed)
Shinya Kitaoka 120a6e
      cmaplen = hd->biClrUsed;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      cmaplen = hd->biBitCount;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (i = 0; i < cmaplen; i++) {
Shinya Kitaoka 120a6e
      b[i] = getc(fp);
Shinya Kitaoka 120a6e
      g[i] = getc(fp);
Shinya Kitaoka 120a6e
      r[i] = getc(fp);
Shinya Kitaoka 120a6e
      if (hd->biSize != BMP_WIN_OS2_OLD) {
Shinya Kitaoka 120a6e
        getc(fp);
Shinya Kitaoka 120a6e
        hd->biPad -= 4;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (BMP_FERROR(fp)) {
Shinya Kitaoka 120a6e
      bmp_error = UNEXPECTED_EOF;
Shinya Kitaoka 120a6e
      goto ERROR;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (BMP_DEBUG) {
Shinya Kitaoka 120a6e
      printf("LoadBMP:  BMP colormap:  (RGB order)\n");
Shinya Kitaoka 120a6e
      for (i = 0; i < cmaplen; i++) printf("%02x%02x%02x  ", r[i], g[i], b[i]);
Shinya Kitaoka 120a6e
      printf("\n\n");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (hd->biSize != BMP_WIN_OS2_OLD) {
Shinya Kitaoka 120a6e
    /* Waste any unused bytes between the colour map (if present)
Shinya Kitaoka 120a6e
and the start of the actual bitmap data.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    while (hd->biPad > 0) {
Shinya Kitaoka 120a6e
      (void)getc(fp);
Shinya Kitaoka 120a6e
      hd->biPad--;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* get information about the portion of the image to load */
Shinya Kitaoka 120a6e
  get_info_region(&info, x1, y1, x2, y2, scale, (int)hd->biWidth,
Shinya Kitaoka 120a6e
                  (int)hd->biHeight, TNZ_BOTLEFT);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* create 32 bit image buffer */
Shinya Kitaoka 120a6e
  if (!allocate_pixmap(img, info.xsize, info.ysize)) {
Shinya Kitaoka 120a6e
    bmp_error = OUT_OF_MEMORY;
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  start_offset = info.y_offset * info.xsize + info.x_offset;
Shinya Kitaoka 120a6e
  pic          = ((LPIXEL *)img->buffer) + start_offset;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (line_size < hd->biWidth + 32) {
Shinya Kitaoka 120a6e
    line_size = hd->biWidth + 32;
Shinya Kitaoka 120a6e
    if (!line)
Shinya Kitaoka 120a6e
      TCALLOC((LPIXEL *)line, (size_t)line_size)
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      TREALLOC(line, line_size)
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!line) {
Shinya Kitaoka 120a6e
    bmp_error = OUT_OF_MEMORY;
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (hd->biBitCount) {
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    pad           = ((hd->biWidth + 31) / 32) * 32;
Shinya Kitaoka 120a6e
    CASE 4 : pad  = ((hd->biWidth + 7) / 8) * 8;
Shinya Kitaoka 120a6e
    CASE 8 : pad  = ((hd->biWidth + 3) / 4) * 4;
Shinya Kitaoka 120a6e
    CASE 24 : pad = (4 - ((hd->biWidth * 3) % 4)) & 0x03;
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    /* segnala errore ed esci */
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  subtype = bmp_get_colorstyle(img);
Shinya Kitaoka 120a6e
  if (subtype == BMP_NONE) goto ERROR;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (info.y_offset > 0) info.scanNrow++;
Shinya Kitaoka 120a6e
  if (info.x_offset > 0) info.scanNcol++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*  print_info_region(&info);      */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (info.startScanRow > 0)
Shinya Kitaoka 120a6e
    skip_bmp_lines(fp, hd->biWidth, (unsigned int)(info.startScanRow - 1),
Shinya Kitaoka 120a6e
                   (unsigned int)SEEK_CUR, subtype);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < (UINT)info.scanNrow; i++) {
Shinya Kitaoka 120a6e
    if (load_lineBMP24(fp, line, hd->biWidth, pad)) goto ERROR;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*  QUESTO SWITCH VA AGGIUSTATO!
Shinya Kitaoka 120a6e
switch (subtype)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
CASE BMP_BW:
Shinya Kitaoka 120a6e
 if (load_lineBMP1(fp, line, hd->biWidth, pad, map))
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
CASE BMP_GREY16:
Shinya Kitaoka 120a6e
__OR BMP_CMAPPED16:
Shinya Kitaoka 120a6e
 if (load_lineBMP4(fp, line, hd->biWidth, pad, map))
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
CASE BMP_GREY16C:
Shinya Kitaoka 120a6e
__OR BMP_CMAPPED16C:
Shinya Kitaoka 120a6e
 if (load_lineBMPC4(fp, line, hd->biWidth, i, map)==-1)
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
CASE BMP_GREY256:
Shinya Kitaoka 120a6e
__OR BMP_CMAPPED256:
Shinya Kitaoka 120a6e
 if (load_lineBMP8(fp, line, hd->biWidth, pad, map))
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
CASE BMP_GREY256C:
Shinya Kitaoka 120a6e
__OR BMP_CMAPPED256C:
Shinya Kitaoka 120a6e
 if (load_lineBMPC8(fp, line, hd->biWidth, i, map)==-1)
Shinya Kitaoka 120a6e
    goto ERROR;
Shinya Kitaoka 120a6e
CASE BMP_RGB:
Shinya Kitaoka 120a6e
 if (load_lineBMP24(fp, line, hd->biWidth, pad))
Shinya Kitaoka 120a6e
    goto ERROR;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
    for (appo = pic, j = c = 0; j < (UINT)info.scanNcol; j++, c += info.step)
Shinya Kitaoka 120a6e
      *appo++ = *(line + info.startScanCol + c);
Shinya Kitaoka 120a6e
    pic += info.xsize;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    skip_bmp_lines(fp, hd->biWidth, (unsigned int)(info.step - 1),
Shinya Kitaoka 120a6e
                   (unsigned int)SEEK_CUR, subtype);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if (BMP_FERROR(fp))
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
bmp_error(fname, "File appears truncated.  Winging it.\n");
Shinya Kitaoka 120a6e
goto ERROR;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  fclose(fp);
Shinya Kitaoka 120a6e
  release_bmp_header(hd);
Shinya Kitaoka 120a6e
  TFREE(line);
Shinya Kitaoka 120a6e
  *pimg = img;
Shinya Kitaoka 120a6e
  return OK;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ERROR:
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  printf("error: (row=%d)\n", i);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  fclose(fp);
Shinya Kitaoka 120a6e
  release_bmp_header(hd);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (img) free_img(img);
Shinya Kitaoka 120a6e
  TFREE(line);
Shinya Kitaoka 120a6e
  return bmp_error;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static int loadBMP1(FILE *fp, LPIXEL *pic, UINT w, UINT h, UCHAR *r, UCHAR *g,
Shinya Kitaoka 120a6e
                    UCHAR *b)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, j, c, bitnum, padw, rv;
Shinya Kitaoka 120a6e
  UCHAR byte;
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Shinya Kitaoka 120a6e
  UCHAR *map[3];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  map[0] = r;
Shinya Kitaoka 120a6e
  map[1] = g;
Shinya Kitaoka 120a6e
  map[2] = b;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rv = c = 0;
Shinya Kitaoka 120a6e
  padw   = ((w + 31) / 32) * 32; /* 'w', padded to be a multiple of 32 */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < h; i++) {
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Shinya Kitaoka 120a6e
    pp = pic + (i * w);
Shinya Kitaoka 120a6e
    rv = load_lineBMP1(fp, pp, w, padw, map);
Shinya Kitaoka 120a6e
    if (rv) break;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    pp = pic + (i * w);
Shinya Kitaoka 120a6e
    for (j = bitnum = 0; j < padw; j++, bitnum++) {
Shinya Kitaoka 120a6e
      if ((bitnum & 7) == 0) /* read the next byte */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        c      = getc(fp);
Shinya Kitaoka 120a6e
        bitnum = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (j < w) {
Shinya Kitaoka 120a6e
        byte = (c & 0x80) ? 1 : 0;
Shinya Kitaoka 120a6e
        c <<= 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        pp->r = r[byte];
Shinya Kitaoka 120a6e
        pp->g = g[byte];
Shinya Kitaoka 120a6e
        pp->b = b[byte];
Shinya Kitaoka 120a6e
        pp->m = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        pp++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (BMP_FERROR(fp)) break;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) rv = 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return rv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int load_lineBMP1(FILE *fp, LPIXEL *pic, UINT w, UINT padw, UCHAR **map)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT j, c, bitnum;
Shinya Kitaoka 120a6e
  UCHAR byte;
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (c = 0, pp = pic, j = bitnum = 0; j < padw; j++, bitnum++) {
Shinya Kitaoka 120a6e
    if ((bitnum & 7) == 0) /* read the next byte */
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      c      = getc(fp);
Shinya Kitaoka 120a6e
      bitnum = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (j < w) {
Shinya Kitaoka 120a6e
      byte = (c & 0x80) ? 1 : 0;
Shinya Kitaoka 120a6e
      c <<= 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pp->r = map[0][byte];
Shinya Kitaoka 120a6e
      pp->g = map[1][byte];
Shinya Kitaoka 120a6e
      pp->b = map[2][byte];
Shinya Kitaoka 120a6e
      pp->m = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pp++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return (BMP_FERROR(fp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int skip_rowsBMP1(FILE *fp, UINT w, UINT pad, UINT rows, int whence)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT offset = pad * rows;
Shinya Kitaoka 120a6e
  UINT i, bitnum;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = bitnum = 0; i < offset; i++, bitnum++) {
Shinya Kitaoka 120a6e
    if ((bitnum & 7) == 0) {
Shinya Kitaoka 120a6e
      getc(fp);
Shinya Kitaoka 120a6e
      bitnum = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return (BMP_FERROR(fp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static int loadBMP4(FILE *fp, LPIXEL *pic, UINT w, UINT h, UINT comp, UCHAR *r,
Shinya Kitaoka 120a6e
                    UCHAR *g, UCHAR *b)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, j, c, c1, x, y, nybnum, padw, rv;
Shinya Kitaoka 120a6e
  UCHAR byte;
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Shinya Kitaoka 120a6e
  UCHAR *map[3];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  map[0] = r;
Shinya Kitaoka 120a6e
  map[1] = g;
Shinya Kitaoka 120a6e
  map[2] = b;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rv = 0;
Shinya Kitaoka 120a6e
  c = c1 = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (comp == BMP_BI_RGB) /* read uncompressed data */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    padw = ((w + 7) / 8) * 8; /* 'w' padded to a multiple of 8pix (32 bits) */
Shinya Kitaoka 120a6e
    for (i = 0; i < h; i++) {
Shinya Kitaoka 120a6e
      pp = pic + (i * w);
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Shinya Kitaoka 120a6e
      rv = load_lineBMP4(fp, pp, w, padw, map);
Shinya Kitaoka 120a6e
      if (rv) break;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      for (j = nybnum = 0; j < padw; j++, nybnum++) {
Shinya Kitaoka 120a6e
        if ((nybnum & 1) == 0) /* read next byte */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          c      = getc(fp);
Shinya Kitaoka 120a6e
          nybnum = 0;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (j < w) {
Shinya Kitaoka 120a6e
          byte = (c & 0xf0) >> 4;
Shinya Kitaoka 120a6e
          c <<= 4;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          pp->r = r[byte];
Shinya Kitaoka 120a6e
          pp->g = g[byte];
Shinya Kitaoka 120a6e
          pp->b = b[byte];
Shinya Kitaoka 120a6e
          pp->m = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          pp++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (BMP_FERROR(fp)) break;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else if (comp == BMP_BI_RLE4) /* read RLE4 compressed data */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    x = y = 0;
Shinya Kitaoka 120a6e
    pp    = pic + x + (y)*w;
Shinya Kitaoka 120a6e
    while (y < h) {
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      rv = load_lineBMPC4(fp, pp, w, y, map);
Shinya Kitaoka 120a6e
      if (rv == -1) {
Shinya Kitaoka 120a6e
        rv = 1;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      } else if (rv == -2) {
Shinya Kitaoka 120a6e
        rv = 0;
Shinya Kitaoka 120a6e
        y++;
Shinya Kitaoka 120a6e
        pp = pic + y * w;
Shinya Kitaoka 120a6e
      } else if (rv == -3) {
Shinya Kitaoka 120a6e
        rv = 0;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        y += (rv / w);
Shinya Kitaoka 120a6e
        pp = pic + rv;
Shinya Kitaoka 120a6e
        rv = 0;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      c = getc(fp);
Shinya Kitaoka 120a6e
      if ((int)c == EOF) {
Shinya Kitaoka 120a6e
        rv = 1;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (c) /* encoded mode */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        c1 = getc(fp);
Shinya Kitaoka 120a6e
        for (i = 0; i < c; i++, x++, pp++) {
Shinya Kitaoka 120a6e
          byte  = (i & 1) ? (c1 & 0x0f) : ((c1 >> 4) & 0x0f);
Shinya Kitaoka 120a6e
          pp->r = r[byte];
Shinya Kitaoka 120a6e
          pp->g = g[byte];
Shinya Kitaoka 120a6e
          pp->b = b[byte];
Shinya Kitaoka 120a6e
          pp->m = 255;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else /* c==0x00  :  escape codes */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        c = getc(fp);
Shinya Kitaoka 120a6e
        if ((int)c == EOF) {
Shinya Kitaoka 120a6e
          rv = 1;
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (c == 0x00) /* end of line */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          x = 0;
Shinya Kitaoka 120a6e
          y++;
Shinya Kitaoka 120a6e
          if (y < h) pp = pic + x + (y)*w;
Shinya Kitaoka 120a6e
        } else if (c == 0x01)
Shinya Kitaoka 120a6e
          break;            /* end of  pic */
Shinya Kitaoka 120a6e
        else if (c == 0x02) /* delta */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          c = getc(fp);
Shinya Kitaoka 120a6e
          x += c;
Shinya Kitaoka 120a6e
          c = getc(fp);
Shinya Kitaoka 120a6e
          y += c;
Shinya Kitaoka 120a6e
          if (y < h) pp = pic + x + (y)*w;
Shinya Kitaoka 120a6e
        } else /* absolute mode */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          for (i = 0; i < c; i++, x++, pp++) {
Shinya Kitaoka 120a6e
            if ((i & 1) == 0) c1 = getc(fp);
Shinya Kitaoka 120a6e
            byte                 = (i & 1) ? (c1 & 0x0f) : ((c1 >> 4) & 0x0f);
Shinya Kitaoka 120a6e
            pp->r                = r[byte];
Shinya Kitaoka 120a6e
            pp->g                = g[byte];
Shinya Kitaoka 120a6e
            pp->b                = b[byte];
Shinya Kitaoka 120a6e
            pp->m                = 255;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          if (((c & 3) == 1) || ((c & 3) == 2)) /* read pad byte */
Shinya Kitaoka 120a6e
            getc(fp);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (BMP_FERROR(fp)) break;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    return 1;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) rv = 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return rv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int load_lineBMP4(FILE *fp, LPIXEL *pic, UINT w, UINT padw, UCHAR **map)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT nybnum, j, c;
Shinya Kitaoka 120a6e
  UCHAR byte;
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (c = 0, pp = pic, j = nybnum = 0; j < padw; j++, nybnum++) {
Shinya Kitaoka 120a6e
    if ((nybnum & 1) == 0) /* read next byte */
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      c      = getc(fp);
Shinya Kitaoka 120a6e
      nybnum = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (j < w) {
Shinya Kitaoka 120a6e
      byte = (c & 0xf0) >> 4;
Shinya Kitaoka 120a6e
      c <<= 4;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pp->r = map[0][byte];
Shinya Kitaoka 120a6e
      pp->g = map[1][byte];
Shinya Kitaoka 120a6e
      pp->b = map[2][byte];
Shinya Kitaoka 120a6e
      pp->m = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pp++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return (BMP_FERROR(fp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int skip_rowsBMP4(FILE *fp, UINT w, UINT pad, UINT rows, int whence)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT offset = pad * rows;
Shinya Kitaoka 120a6e
  UINT i, nybnum;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = nybnum = 0; i < offset; i++, nybnum++) {
Shinya Kitaoka 120a6e
    if ((nybnum & 1) == 0) {
Shinya Kitaoka 120a6e
      getc(fp);
Shinya Kitaoka 120a6e
      nybnum = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return (BMP_FERROR(fp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int load_lineBMPC4(FILE *fp, LPIXEL *pic, UINT w, UINT y, UCHAR **map)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, c, c1, x;
Shinya Kitaoka 120a6e
  UCHAR byte;
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
*  Codici di ritorno:
Shinya Kitaoka 120a6e
*
Shinya Kitaoka 120a6e
*     -1:   incontrata la file del file       (EOF)
Shinya Kitaoka 120a6e
*     -2:   incontrata la fine della linea    (Escape code 0x00 0x00)
Shinya Kitaoka 120a6e
*     -3:   incontrata la fine dell' immagine (Escape code 0x00 0x01)
Shinya Kitaoka 120a6e
*    altro:   incontrato un delta               (Escape code 0x00 0x02)
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* initialize some variables */
Shinya Kitaoka 120a6e
  x  = 0;
Shinya Kitaoka 120a6e
  pp = pic;
Shinya Kitaoka 120a6e
  c = c1 = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (1) {
Shinya Kitaoka 120a6e
    c = getc(fp);
Shinya Kitaoka 120a6e
    if ((int)c == EOF) return -1;
Shinya Kitaoka 120a6e
    if (c) { /* encoded mode */
Shinya Kitaoka 120a6e
      c1 = getc(fp);
Shinya Kitaoka 120a6e
      for (i = 0; i < c; i++, x++, pp++) {
Shinya Kitaoka 120a6e
        byte  = (i & 1) ? (c1 & 0x0f) : ((c1 >> 4) & 0x0f);
Shinya Kitaoka 120a6e
        pp->r = map[0][byte];
Shinya Kitaoka 120a6e
        pp->g = map[1][byte];
Shinya Kitaoka 120a6e
        pp->b = map[2][byte];
Shinya Kitaoka 120a6e
        pp->m = 255;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else /* c==0x00  :  escape codes */
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      c = getc(fp);
Shinya Kitaoka 120a6e
      if ((int)c == EOF) return -1;
Shinya Kitaoka 120a6e
      if (c == 0x00) /* end of line */
Shinya Kitaoka 120a6e
        return -2;
Shinya Kitaoka 120a6e
      else if (c == 0x01) /* end of pic */
Shinya Kitaoka 120a6e
        return -3;
Shinya Kitaoka 120a6e
      else if (c == 0x02) /* delta */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        c = getc(fp);
Shinya Kitaoka 120a6e
        x += c;
Shinya Kitaoka 120a6e
        c = getc(fp);
Shinya Kitaoka 120a6e
        y += c;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        return (x + y * w);
Shinya Kitaoka 120a6e
      } else /* absolute mode */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        for (i = 0; i < c; i++, x++, pp++) {
Shinya Kitaoka 120a6e
          if ((i & 1) == 0) c1 = getc(fp);
Shinya Kitaoka 120a6e
          byte                 = (i & 1) ? (c1 & 0x0f) : ((c1 >> 4) & 0x0f);
Shinya Kitaoka 120a6e
          pp->r                = map[0][byte];
Shinya Kitaoka 120a6e
          pp->g                = map[1][byte];
Shinya Kitaoka 120a6e
          pp->b                = map[2][byte];
Shinya Kitaoka 120a6e
          pp->m                = 255;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (((c & 3) == 1) || ((c & 3) == 2)) /* read pad byte */
Shinya Kitaoka 120a6e
          getc(fp);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (BMP_FERROR(fp)) break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int skip_rowsBMPC4(FILE *fp, UINT rows)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, c, c1, rv = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (rows > 0) {
Shinya Kitaoka 120a6e
    c = getc(fp);
Shinya Kitaoka 120a6e
    switch (c) {
Shinya Kitaoka 120a6e
    case 0x00:
Shinya Kitaoka 120a6e
      c = getc(fp);
Shinya Kitaoka 120a6e
      switch (c) {
Shinya Kitaoka 120a6e
      case 0x00:
Shinya Kitaoka 120a6e
        rows--;
Shinya Kitaoka 120a6e
        CASE 0x01 : rows = 0;
luz paz 6454c4
        CASE 0x02 : c1   = getc(fp); /* x buffer offset */
luz paz 6454c4
        c1               = getc(fp); /* y buffer offset */
Shinya Kitaoka 120a6e
        rows -= c1;
Shinya Kitaoka 120a6e
      DEFAULT:
Shinya Kitaoka 120a6e
        for (i = 0; i < c; i++) {
Shinya Kitaoka 120a6e
          if ((i & 1) == 0) getc(fp);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (((c & 3) == 1) || ((c & 3) == 2)) getc(fp);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    DEFAULT:
Shinya Kitaoka 120a6e
      c1 = getc(fp);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) rv = 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return rv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static int loadBMP8(FILE *fp, LPIXEL *pic, UINT w, UINT h, UINT comp, UCHAR *r,
Shinya Kitaoka 120a6e
                    UCHAR *g, UCHAR *b)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, j, c, c1, padw, x, y, rv;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Shinya Kitaoka 120a6e
  UCHAR *map[3];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  map[0] = r;
Shinya Kitaoka 120a6e
  map[1] = g;
Shinya Kitaoka 120a6e
  map[2] = b;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rv = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (comp == BMP_BI_RGB) /* read uncompressed data */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    padw = ((w + 3) / 4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */
Shinya Kitaoka 120a6e
    for (i = 0; i < h; i++) {
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Shinya Kitaoka 120a6e
      pp = pic + (i * w);
Shinya Kitaoka 120a6e
      rv = load_lineBMP8(fp, pp, w, padw, map);
Shinya Kitaoka 120a6e
      if (rv) break;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      pp = pic + (i * w);
Shinya Kitaoka 120a6e
      for (j = 0; j < padw; j++) {
Shinya Kitaoka 120a6e
        c                     = getc(fp);
Shinya Kitaoka 120a6e
        if ((int)c == EOF) rv = 1;
Shinya Kitaoka 120a6e
        if (j < w) {
Shinya Kitaoka 120a6e
          pp->r = r[c];
Shinya Kitaoka 120a6e
          pp->g = g[c];
Shinya Kitaoka 120a6e
          pp->b = b[c];
Shinya Kitaoka 120a6e
          pp->m = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          pp++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (BMP_FERROR(fp)) break;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else if (comp == BMP_BI_RLE8) /* read RLE8 compressed data */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    x = y = 0;
Shinya Kitaoka 120a6e
    pp    = pic + x + y * w;
Shinya Kitaoka 120a6e
    while (y < h) {
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      rv = load_lineBMPC8(fp, pp, w, y, map);
Shinya Kitaoka 120a6e
      if (rv == -1) {
Shinya Kitaoka 120a6e
        rv = 1;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      } else if (rv == -2) {
Shinya Kitaoka 120a6e
        rv = 0;
Shinya Kitaoka 120a6e
        y++;
Shinya Kitaoka 120a6e
        pp = pic + y * w;
Shinya Kitaoka 120a6e
      } else if (rv == -3) {
Shinya Kitaoka 120a6e
        rv = 0;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        y += (rv / w);
Shinya Kitaoka 120a6e
        pp = pic + rv;
Shinya Kitaoka 120a6e
        rv = 0;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      c = getc(fp);
Shinya Kitaoka 120a6e
      if ((int)c == EOF) {
Shinya Kitaoka 120a6e
        rv = 1;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (c) { /* encoded mode */
Shinya Kitaoka 120a6e
        c1 = getc(fp);
Shinya Kitaoka 120a6e
        for (i = 0; i < c; i++, x++, pp++) {
Shinya Kitaoka 120a6e
          pp->r = r[c1];
Shinya Kitaoka 120a6e
          pp->g = g[c1];
Shinya Kitaoka 120a6e
          pp->b = b[c1];
Shinya Kitaoka 120a6e
          pp->m = 255;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else /* c==0x00  :  escape codes */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        c = getc(fp);
Shinya Kitaoka 120a6e
        if ((int)c == EOF) {
Shinya Kitaoka 120a6e
          rv = 1;
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (c == 0x00) /* end of line */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          x = 0;
Shinya Kitaoka 120a6e
          y++;
Shinya Kitaoka 120a6e
          pp = pic + x + y * w;
Shinya Kitaoka 120a6e
        } else if (c == 0x01)
Shinya Kitaoka 120a6e
          break;            /* end of pic */
Shinya Kitaoka 120a6e
        else if (c == 0x02) /* delta */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          c = getc(fp);
Shinya Kitaoka 120a6e
          x += c;
Shinya Kitaoka 120a6e
          c = getc(fp);
Shinya Kitaoka 120a6e
          y += c;
Shinya Kitaoka 120a6e
          pp = pic + x + y * w;
Shinya Kitaoka 120a6e
        } else /* absolute mode */
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          for (i = 0; i < c; i++, x++, pp++) {
Shinya Kitaoka 120a6e
            c1 = getc(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            pp->r = r[c1];
Shinya Kitaoka 120a6e
            pp->g = g[c1];
Shinya Kitaoka 120a6e
            pp->b = b[c1];
Shinya Kitaoka 120a6e
            pp->m = 255;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          if (c & 1) /* odd length run: read an extra pad byte */
Shinya Kitaoka 120a6e
            getc(fp);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (BMP_FERROR(fp)) break;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    return 1;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) rv = 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return rv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int load_lineBMP8(FILE *fp, LPIXEL *pic, UINT w, UINT padw, UCHAR **map)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT j, c, rv = 0;
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (pp = pic, j = 0; j < padw; j++) {
Shinya Kitaoka 120a6e
    c = getc(fp);
Shinya Kitaoka 120a6e
    if ((int)c == EOF) {
Shinya Kitaoka 120a6e
      rv = 1;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (j < w) {
Shinya Kitaoka 120a6e
      pp->r = map[0][c];
Shinya Kitaoka 120a6e
      pp->g = map[1][c];
Shinya Kitaoka 120a6e
      pp->b = map[2][c];
Shinya Kitaoka 120a6e
      pp->m = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pp++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) rv = 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return rv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int skip_rowsBMP8(FILE *fp, UINT w, UINT pad, UINT rows, int whence)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT offset = pad * rows;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  fseek(fp, (long)offset, whence);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return (BMP_FERROR(fp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int load_lineBMPC8(FILE *fp, LPIXEL *pic, UINT w, UINT y, UCHAR **map)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int i, c, c1, x;
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
*  Codici di ritorno:
Shinya Kitaoka 120a6e
*
Shinya Kitaoka 120a6e
*     -1:   incontrata la file del file       (EOF)
Shinya Kitaoka 120a6e
*     -2:   incontrata la fine della linea    (Escape code 0x00 0x00)
Shinya Kitaoka 120a6e
*     -3:   incontrata la fine dell' immagine (Escape code 0x00 0x01)
Shinya Kitaoka 120a6e
*  altro:   incontrato un delta               (Escape code 0x00 0x02)
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x  = 0;
Shinya Kitaoka 120a6e
  pp = pic;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (1) {
Shinya Kitaoka 120a6e
    c = getc(fp);
Shinya Kitaoka 120a6e
    if (c == EOF) return -1;
Shinya Kitaoka 120a6e
    if (c) { /* encoded mode */
Shinya Kitaoka 120a6e
      c1 = getc(fp);
Shinya Kitaoka 120a6e
      for (i = 0; i < c; i++, x++, pp++) {
Shinya Kitaoka 120a6e
        pp->r = map[0][c1];
Shinya Kitaoka 120a6e
        pp->g = map[1][c1];
Shinya Kitaoka 120a6e
        pp->b = map[2][c1];
Shinya Kitaoka 120a6e
        pp->m = 255;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else /* c==0x00  :  escape codes */
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      c = getc(fp);
Shinya Kitaoka 120a6e
      if (c == EOF) return -1;
Shinya Kitaoka 120a6e
      if (c == 0x00) /* end of line */
Shinya Kitaoka 120a6e
        return -2;
Shinya Kitaoka 120a6e
      else if (c == 0x01) /* end of pic */
Shinya Kitaoka 120a6e
        return -3;
Shinya Kitaoka 120a6e
      else if (c == 0x02) /* delta */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        c = getc(fp);
Shinya Kitaoka 120a6e
        x += c;
Shinya Kitaoka 120a6e
        c = getc(fp);
Shinya Kitaoka 120a6e
        y += c;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        return (x + y * w);
Shinya Kitaoka 120a6e
      } else /* absolute mode */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        for (i = 0; i < c; i++, x++, pp++) {
Shinya Kitaoka 120a6e
          c1 = getc(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          pp->r = map[0][c1];
Shinya Kitaoka 120a6e
          pp->g = map[1][c1];
Shinya Kitaoka 120a6e
          pp->b = map[2][c1];
Shinya Kitaoka 120a6e
          pp->m = 255;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (c & 1) /* odd length run: read an extra pad byte */
Shinya Kitaoka 120a6e
          getc(fp);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int skip_rowsBMPC8(FILE *fp, UINT rows)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int i, c, c1, rv = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (rows > 0) {
Shinya Kitaoka 120a6e
    c = getc(fp);
Shinya Kitaoka 120a6e
    switch (c) {
Shinya Kitaoka 120a6e
    case 0x00:
Shinya Kitaoka 120a6e
      c = getc(fp);
Shinya Kitaoka 120a6e
      switch (c) {
Shinya Kitaoka 120a6e
      case 0x00:
Shinya Kitaoka 120a6e
        rows--;
Shinya Kitaoka 120a6e
        CASE 0x01 : rows = 0;
luz paz 6454c4
        CASE 0x02 : c1   = getc(fp); /* x buffer offset */
luz paz 6454c4
        c1               = getc(fp); /* y buffer offset */
Shinya Kitaoka 120a6e
        rows -= c1;
Shinya Kitaoka 120a6e
      DEFAULT:
Shinya Kitaoka 120a6e
        for (i = 0; i < c; i++) getc(fp);
Shinya Kitaoka 120a6e
        if (c & 1) getc(fp);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    DEFAULT:
Shinya Kitaoka 120a6e
      c1 = getc(fp);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) rv = 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return rv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int loadBMP24(FILE *fp, LPIXEL *pic, UINT w, UINT h)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, j, padb, rv;
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rv = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  padb = (4 - ((w * 3) % 4)) & 0x03; /* # of pad bytes to read at EOscanline */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < h; i++) {
Toshihiro Shimizu 890ddd
#ifdef BMP_READ_LINE_BY_LINE
Shinya Kitaoka 120a6e
    pp = pic + i * w;
Shinya Kitaoka 120a6e
    rv = load_lineBMP24(fp, pp, w, padb);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    for (pp = pic + i * w, j = 0; j < w; j++, pp++) {
Shinya Kitaoka 120a6e
      pp->b = getc(fp); /* blue  */
Shinya Kitaoka 120a6e
      pp->g = getc(fp); /* green */
Shinya Kitaoka 120a6e
      pp->r = getc(fp); /* red   */
Shinya Kitaoka 120a6e
      pp->m = 255;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (j = 0; j < padb; j++) getc(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rv = (BMP_FERROR(fp));
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    if (rv) break;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return rv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int load_lineBMP24(FILE *fp, LPIXEL *pic, UINT w, UINT padb)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  LPIXEL *pp;
Shinya Kitaoka 120a6e
  UINT j;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (pp = pic, j = 0; j < w; j++, pp++) {
Shinya Kitaoka 120a6e
    pp->b = getc(fp); /* blue  */
Shinya Kitaoka 120a6e
    pp->g = getc(fp); /* green */
Shinya Kitaoka 120a6e
    pp->r = getc(fp); /* red   */
Shinya Kitaoka 120a6e
    pp->m = 255;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (j = 0; j < padb; j++) getc(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return (BMP_FERROR(fp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int skip_rowsBMP24(FILE *fp, UINT w, UINT pad, UINT rows, int whence)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT offset = (w * 3 + pad) * rows;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  fseek(fp, (long)offset, whence);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return (BMP_FERROR(fp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*-- BMP WRITE --------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
BMP_SUBTYPE bmp_get_colorstyle(IMAGE *img)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  return img->type;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int write_bmp_header(FILE *fp, BMP_HEADER *hd)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  putc('B', fp);
Shinya Kitaoka 120a6e
  putc('M', fp); /* BMP file magic number           */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->bfSize);
Shinya Kitaoka 120a6e
  putshort(fp, 0); /* reserved1                       */
Shinya Kitaoka 120a6e
  putshort(fp, 0); /* reserved2                       */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->bfOffBits); /* offset from BOfile to BObitmap */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->biSize);       /* size of bitmap info header     */
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->biWidth);      /* width                          */
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->biHeight);     /* height                         */
Shinya Kitaoka 120a6e
  putshort(fp, (int)hd->biPlanes);   /* must be '1'                    */
Shinya Kitaoka 120a6e
  putshort(fp, (int)hd->biBitCount); /* 1,4,8, or 24                   */
Shinya Kitaoka 120a6e
  putint(fp,
Shinya Kitaoka 38fd86
         (int)hd->biCompression);   /* BMP_BI_RGB, BMP_BI_RLE8 or BMP_BI_RLE4 */
Shinya Kitaoka 38fd86
  putint(fp, (int)hd->biSizeImage); /* size of raw image data         */
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->biXPelsPerMeter); /* dpi * 39" per meter            */
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->biYPelsPerMeter); /* dpi * 39" per meter            */
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->biClrUsed);       /* colors used in cmap            */
Shinya Kitaoka 120a6e
  putint(fp, (int)hd->biClrImportant);  /* same as above                  */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int write_bmp_palette(FILE *fp, int nc, UCHAR *b, UCHAR *g, UCHAR *r)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < nc; i++) {
Shinya Kitaoka 120a6e
    putc(b[i], fp);
Shinya Kitaoka 120a6e
    putc(g[i], fp);
Shinya Kitaoka 120a6e
    putc(r[i], fp);
Shinya Kitaoka 120a6e
    putc(0, fp);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef __LIBSIMAGE__
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int img_write_bmp(const MYSTRING fname, IMAGE *img)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int (*write_function)(FILE * fp, UCHAR * pic, UINT w, UINT h, UCHAR * map);
Shinya Kitaoka 120a6e
  int h, w, i, nc, nbits, bperlin, comp;
Shinya Kitaoka 120a6e
  UCHAR val;
Shinya Kitaoka 120a6e
  UCHAR pc2nc[256], r1[256], g1[256], b1[256];
Shinya Kitaoka 120a6e
  UCHAR *pic, *graypic;
Shinya Kitaoka 120a6e
  BMP_SUBTYPE subtype;
Shinya Kitaoka 120a6e
  BMP_HEADER hd;
Shinya Kitaoka 120a6e
  FILE *fp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  subtype = bmp_get_colorstyle(img);
Shinya Kitaoka 120a6e
  if (subtype == BMP_NONE) return UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fp = _wfopen(fname, L"wb");
Shinya Kitaoka 120a6e
  if (!fp) return CANT_OPEN_FILE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  graypic = NULL;
Shinya Kitaoka 120a6e
  nc      = 0;
Shinya Kitaoka 120a6e
  nbits   = 0;
Shinya Kitaoka 120a6e
  comp    = 0;
Shinya Kitaoka 120a6e
  h       = img->ysize;
Shinya Kitaoka 120a6e
  w       = img->xsize;
Shinya Kitaoka 120a6e
  pic     = (UCHAR *)img->buffer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (subtype) {
Shinya Kitaoka 120a6e
  case BMP_BW:
Shinya Kitaoka 120a6e
    __OR BMP_GREY16 : __OR BMP_GREY16C :
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                      __OR BMP_CMAPPED256 : __OR BMP_CMAPPED256C
Shinya Kitaoka 120a6e
                                            : return UNSUPPORTED_BMP_FORMAT;
Shinya Kitaoka 120a6e
    CASE BMP_GREY256 : __OR BMP_GREY256C : nbits = 8;
Shinya Kitaoka 120a6e
    CASE BMP_RGB : nbits                         = 24;
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    goto BMP_WRITE_ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* number bytes written per line */
Shinya Kitaoka 120a6e
  bperlin = ((w * nbits + 31) / 32) * 4;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* compute filesize and write it */
Shinya Kitaoka 120a6e
  i = 14 +         /* size of bitmap file header */
Shinya Kitaoka 120a6e
      40 +         /* size of bitmap info header */
Shinya Kitaoka 120a6e
      (nc * 4) +   /* size of colormap */
Shinya Kitaoka 120a6e
      bperlin * h; /* size of image data */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (nbits) {
Shinya Kitaoka 120a6e
  case 4:
Shinya Kitaoka 120a6e
    comp          = (comp == TRUE) ? BMP_BI_RLE4 : BMP_BI_RGB;
Shinya Kitaoka 120a6e
    CASE 8 : comp = (comp == TRUE) ? BMP_BI_RLE8 : BMP_BI_RGB;
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    comp = BMP_BI_RGB;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* fill image header */
Shinya Kitaoka 120a6e
  hd.bfSize          = i;
Shinya Kitaoka 120a6e
  hd.bfOffBits       = 14 + 40 + (nc * 4);
Shinya Kitaoka 120a6e
  hd.biSize          = 40;
Shinya Kitaoka 120a6e
  hd.biWidth         = w;
Shinya Kitaoka 120a6e
  hd.biHeight        = h;
Shinya Kitaoka 120a6e
  hd.biPlanes        = 1;
Shinya Kitaoka 120a6e
  hd.biBitCount      = nbits;
Shinya Kitaoka 120a6e
  hd.biCompression   = comp;
Shinya Kitaoka 120a6e
  hd.biSizeImage     = bperlin * h;
Shinya Kitaoka 120a6e
  hd.biXPelsPerMeter = 0 * 39;
Shinya Kitaoka 120a6e
  hd.biYPelsPerMeter = 0 * 39;
Shinya Kitaoka 120a6e
  hd.biClrUsed       = nc;
Shinya Kitaoka 120a6e
  hd.biClrImportant  = nc;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!write_bmp_header(fp, &hd)) goto BMP_WRITE_ERROR;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  write_bmp_palette(fp, nc, b1, g1, r1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (nbits) {
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    write_function                                  = writeBMP1;
Shinya Kitaoka 120a6e
    CASE 4 : if (comp == BMP_BI_RGB) write_function = writeBMP4;
Shinya Kitaoka 120a6e
    else write_function                             = writeBMPC4;
Shinya Kitaoka 120a6e
    CASE 8 : if (comp == BMP_BI_RGB) write_function = writeBMP8;
Shinya Kitaoka 120a6e
    else write_function                             = writeBMPC8;
Shinya Kitaoka 120a6e
    CASE 24 : write_function                        = writeBMP24;
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    goto BMP_WRITE_ERROR;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* write out the image */
Shinya Kitaoka 120a6e
  val = write_function(fp, pic, (unsigned int)w, (unsigned int)h, pc2nc);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (graypic) free(graypic);
Shinya Kitaoka 120a6e
  fclose(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* 0 failed , 1 ok */
Shinya Kitaoka 120a6e
  return val == 1 ? OK : WRITE_ERROR;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
BMP_WRITE_ERROR:
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  fclose(fp);
Shinya Kitaoka 120a6e
  if (graypic) free(graypic);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  _wremove(fname);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return WRITE_ERROR;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif /* __LIBSIMAGE__ */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int writeBMP1(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, j, c, bitnum, padw;
Shinya Kitaoka 120a6e
  UCHAR *pp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  padw = ((w + 31) / 32) * 32; /* 'w', padded to be a multiple of 32 */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < h; i++) {
Shinya Kitaoka 120a6e
    pp = pic8 + (i * w);
Toshihiro Shimizu 890ddd
#ifdef BMP_WRITE_LINE_BY_LINE
Shinya Kitaoka 120a6e
    if (line_writeBMP1(fp, pp, w, padw, pc2nc) == FALSE) return FALSE;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    for (j = bitnum = c = 0; j <= padw; j++, bitnum++) {
Shinya Kitaoka 120a6e
      if (bitnum == 8) /* write the next byte */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        putc((int)c, fp);
Shinya Kitaoka 120a6e
        bitnum = c = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      c <<= 1;
Shinya Kitaoka 120a6e
      if (j < w) {
Shinya Kitaoka 120a6e
        c |= (pc2nc[*pp++] & 0x01);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static int line_writeBMP1(FILE *fp, UCHAR *pic8, UINT w, UINT padw,
Shinya Kitaoka 120a6e
                          UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UCHAR *pp = pic8;
Shinya Kitaoka 120a6e
  UINT j, c, bitnum;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (j = bitnum = c = 0; j <= padw; j++, bitnum++) {
Shinya Kitaoka 120a6e
    if (bitnum == 8) /* write the next byte */
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      putc((int)c, fp);
Shinya Kitaoka 120a6e
      bitnum = c = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    c <<= 1;
Shinya Kitaoka 120a6e
    if (j < w) {
Shinya Kitaoka 120a6e
      c |= (pc2nc[*pp++] & 0x01);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int writeBMP4(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, j, c, nybnum, padw;
Shinya Kitaoka 120a6e
  UCHAR *pp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  padw = ((w + 7) / 8) * 8; /* 'w' padded to a multiple of 8pix (32 bits) */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < h; i++) {
Shinya Kitaoka 120a6e
    pp = pic8 + (i * w);
Toshihiro Shimizu 890ddd
#ifdef BMP_WRITE_LINE_BY_LINE
Shinya Kitaoka 120a6e
    if (line_writeBMP4(fp, pp, w, padw, pc2nc) == FALSE) return FALSE;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    for (j = nybnum = c = 0; j <= padw; j++, nybnum++) {
Shinya Kitaoka 120a6e
      if (nybnum == 2) /* write next byte */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        putc((int)(c & 0xff), fp);
Shinya Kitaoka 120a6e
        nybnum = c = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      c <<= 4;
Shinya Kitaoka 120a6e
      if (j < w) {
Shinya Kitaoka 120a6e
        c |= (pc2nc[*pp] & 0x0f);
Shinya Kitaoka 120a6e
        pp++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static int line_writeBMP4(FILE *fp, UCHAR *pic8, UINT w, UINT padw,
Shinya Kitaoka 120a6e
                          UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT j, c, nybnum;
Shinya Kitaoka 120a6e
  UCHAR *pp = pic8;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (j = nybnum = c = 0; j <= padw; j++, nybnum++) {
Shinya Kitaoka 120a6e
    if (nybnum == 2) /* write next byte */
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      putc((int)(c & 0xff), fp);
Shinya Kitaoka 120a6e
      nybnum = c = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    c <<= 4;
Shinya Kitaoka 120a6e
    if (j < w) {
Shinya Kitaoka 120a6e
      c |= (pc2nc[*pp] & 0x0f);
Shinya Kitaoka 120a6e
      pp++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int writeBMPC4(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UCHAR *pp1, *pp2, *pp3, byte1, byte2;
Shinya Kitaoka 120a6e
  UINT i, cnt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < h; i++) {
Shinya Kitaoka 120a6e
    pp1 = pic8 + i * w;
Shinya Kitaoka 120a6e
    pp2 = pp1 + 2;
Shinya Kitaoka 120a6e
    pp3 = pp1 + w + 2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; pp2 < pp3; pp2 += 2) {
Shinya Kitaoka 120a6e
      cnt = 2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      byte1 = ((pc2nc[*pp1] << 4) & 0xf0) | (pc2nc[*(pp1 + 1)] & 0x0f);
Shinya Kitaoka 120a6e
      byte2 = ((pc2nc[*pp2] << 4) & 0xf0) | (pc2nc[*(pp2 + 1)] & 0x0f);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (byte1 != byte2) {
Shinya Kitaoka 120a6e
        putc((int)cnt, fp);
Shinya Kitaoka 120a6e
        putc(byte1, fp);
Shinya Kitaoka 120a6e
        pp1 = pp2;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        while (cnt <= 254 && pp2 < pp3) {
Shinya Kitaoka 120a6e
          cnt += 2;
Shinya Kitaoka 120a6e
          pp2 += 2;
Shinya Kitaoka 120a6e
          byte2 = ((pc2nc[*pp2] << 4) & 0xf0) | (pc2nc[*(pp2 + 1)] & 0x0f);
Shinya Kitaoka 120a6e
          if (byte1 != byte2 || cnt >= 254 || pp2 + 2 > pp3) {
Shinya Kitaoka 120a6e
            if (pp2 + 2 > pp3) cnt -= 2;
Shinya Kitaoka 120a6e
            putc((int)cnt, fp);
Shinya Kitaoka 120a6e
            putc(byte1, fp);
Shinya Kitaoka 120a6e
            break;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        pp1 = pp2;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    putc(0x00, fp);
Shinya Kitaoka 120a6e
    putc(0x00, fp);
Shinya Kitaoka 120a6e
    if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  putc(0x00, fp);
Shinya Kitaoka 120a6e
  putc(0x01, fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static int line_writeBMPC4(FILE *fp, UCHAR *pic8, UINT w, UINT row,
Shinya Kitaoka 120a6e
                           UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UCHAR *pp1, *pp2, *pp3, byte1, byte2;
Shinya Kitaoka 120a6e
  UINT cnt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pp1 = pic8 + row * w;
Shinya Kitaoka 120a6e
  pp2 = pp1 + 2;
Shinya Kitaoka 120a6e
  pp3 = pp1 + w + 2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; pp2 < pp3; pp2 += 2) {
Shinya Kitaoka 120a6e
    cnt = 2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    byte1 = ((pc2nc[*pp1] << 4) & 0xf0) | (pc2nc[*(pp1 + 1)] & 0x0f);
Shinya Kitaoka 120a6e
    byte2 = ((pc2nc[*pp2] << 4) & 0xf0) | (pc2nc[*(pp2 + 1)] & 0x0f);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (byte1 != byte2) {
Shinya Kitaoka 120a6e
      putc((int)cnt, fp);
Shinya Kitaoka 120a6e
      putc(byte1, fp);
Shinya Kitaoka 120a6e
      pp1 = pp2;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      while (cnt <= 254 && pp2 < pp3) {
Shinya Kitaoka 120a6e
        cnt += 2;
Shinya Kitaoka 120a6e
        pp2 += 2;
Shinya Kitaoka 120a6e
        byte2 = ((pc2nc[*pp2] << 4) & 0xf0) | (pc2nc[*(pp2 + 1)] & 0x0f);
Shinya Kitaoka 120a6e
        if (byte1 != byte2 || cnt >= 254 || pp2 + 2 > pp3) {
Shinya Kitaoka 120a6e
          if (pp2 + 2 > pp3) cnt -= 2;
Shinya Kitaoka 120a6e
          putc((int)cnt, fp);
Shinya Kitaoka 120a6e
          putc(byte1, fp);
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      pp1 = pp2;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  putc(0x00, fp);
Shinya Kitaoka 120a6e
  putc(0x00, fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int writeBMP8(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, j, padw;
Shinya Kitaoka 120a6e
  UCHAR *pp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  padw = ((w + 3) / 4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < h; i++) {
Shinya Kitaoka 120a6e
    pp = pic8 + (i * w);
Toshihiro Shimizu 890ddd
#ifdef BMP_WRITE_LINE_BY_LINE
Shinya Kitaoka 120a6e
    if (line_writeBMP8(fp, pp, w, padw, pc2nc) == FALSE) return FALSE;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    /* for (j=0; j
Shinya Kitaoka 120a6e
    for (j = 0; j < w; j++) {
Shinya Kitaoka 120a6e
      putc(*pp, fp);
Shinya Kitaoka 120a6e
      pp++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (; j < padw; j++) putc(0, fp);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static int line_writeBMP8(FILE *fp, UCHAR *pic8, UINT w, UINT padw,
Shinya Kitaoka 120a6e
                          UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UCHAR *pp = pic8;
Shinya Kitaoka 120a6e
  UINT j;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (j = 0; j < w; j++) putc(pc2nc[*pp++], fp);
Shinya Kitaoka 120a6e
  for (; j < padw; j++) putc(0, fp);
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int writeBMPC8(FILE *fp, UCHAR *pic8, UINT w, UINT h, UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UCHAR *pp1, *pp2, *pp3, byte1, byte2;
Shinya Kitaoka 120a6e
  UINT i, cnt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < h; i++) {
Shinya Kitaoka 120a6e
    pp1 = pic8 + i * w;
Shinya Kitaoka 120a6e
    pp2 = pp1 + 1;
Shinya Kitaoka 120a6e
    pp3 = pp1 + w + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; pp2 < pp3; pp2++) {
Shinya Kitaoka 120a6e
      cnt = 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      byte1 = pc2nc[*pp1];
Shinya Kitaoka 120a6e
      byte2 = pc2nc[*pp2];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (byte1 != byte2) {
Shinya Kitaoka 120a6e
        putc((int)cnt, fp);
Shinya Kitaoka 120a6e
        putc(byte1, fp);
Shinya Kitaoka 120a6e
        pp1 = pp2;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        while (cnt <= 254 && pp2 < pp3) {
Shinya Kitaoka 120a6e
          cnt++;
Shinya Kitaoka 120a6e
          pp2++;
Shinya Kitaoka 120a6e
          byte2 = pc2nc[*pp2];
Shinya Kitaoka 120a6e
          if (byte1 != byte2 || cnt >= 254 || pp2 + 1 > pp3) {
Shinya Kitaoka 120a6e
            if (pp2 + 1 > pp3) cnt--;
Shinya Kitaoka 120a6e
            putc((int)cnt, fp);
Shinya Kitaoka 120a6e
            putc(byte1, fp);
Shinya Kitaoka 120a6e
            break;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        pp1 = pp2;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    putc(0x00, fp);
Shinya Kitaoka 120a6e
    putc(0x00, fp);
Shinya Kitaoka 120a6e
    if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  putc(0x00, fp);
Shinya Kitaoka 120a6e
  putc(0x01, fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static int line_writeBMPC8(FILE *fp, UCHAR *pic8, UINT w, UINT row,
Shinya Kitaoka 120a6e
                           UCHAR *pc2nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UCHAR *pp1, *pp2, *pp3, byte1, byte2;
Shinya Kitaoka 120a6e
  UINT cnt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pp1 = pic8 + row * w;
Shinya Kitaoka 120a6e
  pp2 = pp1 + 1;
Shinya Kitaoka 120a6e
  pp3 = pp1 + w + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; pp2 < pp3; pp2++) {
Shinya Kitaoka 120a6e
    cnt = 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    byte1 = pc2nc[*pp1];
Shinya Kitaoka 120a6e
    byte2 = pc2nc[*pp2];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (byte1 != byte2) {
Shinya Kitaoka 120a6e
      putc((int)cnt, fp);
Shinya Kitaoka 120a6e
      putc(byte1, fp);
Shinya Kitaoka 120a6e
      pp1 = pp2;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      while (cnt <= 254 && pp2 < pp3) {
Shinya Kitaoka 120a6e
        cnt++;
Shinya Kitaoka 120a6e
        pp2++;
Shinya Kitaoka 120a6e
        byte2 = pc2nc[*pp2];
Shinya Kitaoka 120a6e
        if (byte1 != byte2 || cnt >= 254 || pp2 + 1 > pp3) {
Shinya Kitaoka 120a6e
          if (pp2 + 1 > pp3) cnt--;
Shinya Kitaoka 120a6e
          putc((int)cnt, fp);
Shinya Kitaoka 120a6e
          putc(byte1, fp);
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      pp1 = pp2;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  putc(0x00, fp);
Shinya Kitaoka 120a6e
  putc(0x00, fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int writeBMP24(FILE *fp, UCHAR *pic24, UINT w, UINT h, UCHAR *whence)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT i, j, padb;
Shinya Kitaoka 120a6e
  LPIXEL *pixel;
Shinya Kitaoka 120a6e
  UCHAR *pp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* pc2nc not used */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  padb = (4 - ((w * 3) % 4)) & 0x03; /* # of pad bytes to write at EOscanline */
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < h; i++) {
Shinya Kitaoka 120a6e
    pp    = pic24 + (i * w * 4);
Shinya Kitaoka 120a6e
    pixel = (LPIXEL *)pp;
Toshihiro Shimizu 890ddd
#ifdef BMP_WRITE_LINE_BY_LINE
Shinya Kitaoka 120a6e
    if (line_writeBMP24(fp, pixel, w, padb) == FALSE) return FALSE;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    for (j = 0; j < w; j++) {
Shinya Kitaoka 120a6e
      putc(pixel->b, fp);
Shinya Kitaoka 120a6e
      putc(pixel->g, fp);
Shinya Kitaoka 120a6e
      putc(pixel->r, fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pixel++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (j = 0; j < padb; j++) putc(0, fp);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static int line_writeBMP24(FILE *fp, LPIXEL *pp, UINT w, UINT padb)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  UINT j;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (j = 0; j < w; j++) {
Shinya Kitaoka 120a6e
    putc(pp->b, fp);
Shinya Kitaoka 120a6e
    putc(pp->g, fp);
Shinya Kitaoka 120a6e
    putc(pp->r, fp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    pp++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (j = 0; j < padb; j++) putc(0, fp);
Shinya Kitaoka 120a6e
  if (BMP_FERROR(fp)) return FALSE;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef __LIBSIMAGE__
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef UNUSED_REDUCE_COLORS
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Shinya Kitaoka 120a6e
static UCHAR *reduce_colors(UCHAR *buffin, int xsize, int ysize, UCHAR *rmap,
Shinya Kitaoka 120a6e
                            UCHAR *gmap, UCHAR *bmap, int nc)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  LPIXEL *curr_pix, *next_pix, *prev_pix, *buffer;
Shinya Kitaoka 120a6e
  static LPIXEL *mbuffer = NULL;
Shinya Kitaoka 120a6e
  static UCHAR *ret_buf  = NULL;
Shinya Kitaoka 120a6e
  static int outbuf_size = 0;
Shinya Kitaoka 120a6e
  static int buffin_size = 0;
Shinya Kitaoka 120a6e
  int r1, g1, b1, dim;
Shinya Kitaoka 120a6e
  int i, j, tmp;
Shinya Kitaoka 120a6e
  int imax, jmax;
Shinya Kitaoka 120a6e
  UCHAR *outbuf;
Shinya Kitaoka 120a6e
  USHORT val;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  dim = xsize * ysize;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (dim > outbuf_size) {
Shinya Kitaoka 120a6e
    if (!ret_buf)
Shinya Kitaoka 120a6e
      TCALLOC(ret_buf, dim)
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      TREALLOC(ret_buf, dim);
Shinya Kitaoka 120a6e
    if (!ret_buf) return NULL;
Shinya Kitaoka 120a6e
    outbuf_size = dim;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (dim > buffin_size) {
Shinya Kitaoka 120a6e
    if (!mbuffer)
Shinya Kitaoka 120a6e
      TCALLOC(mbuffer, dim)
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      TREALLOC(mbuffer, dim);
Shinya Kitaoka 120a6e
    if (!ret_buf) return NULL;
Shinya Kitaoka 120a6e
    buffin_size = dim;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  memcpy(mbuffer, buffin, dim * sizeof(LPIXEL));
Shinya Kitaoka 120a6e
  buffer = mbuffer;
Shinya Kitaoka 120a6e
  outbuf = ret_buf;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  imax = ysize - 1;
Shinya Kitaoka 120a6e
  jmax = xsize - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < ysize; i++) {
Shinya Kitaoka 120a6e
    curr_pix = buffer;
Shinya Kitaoka 120a6e
    buffer += xsize;
Shinya Kitaoka 120a6e
    next_pix = buffer;
Shinya Kitaoka 120a6e
    prev_pix = NIL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (j = 0; j < xsize; j++) {
Shinya Kitaoka 120a6e
      r1 = curr_pix->r;
Shinya Kitaoka 120a6e
      g1 = curr_pix->g;
Shinya Kitaoka 120a6e
      b1 = curr_pix->b;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      val = BMP_REDUCE_COLORS(r1, g1, b1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      *(outbuf++) = (unsigned char)val;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /* errors on colors */
Shinya Kitaoka 120a6e
      r1 -= rmap[val];
Shinya Kitaoka 120a6e
      g1 -= gmap[val];
Shinya Kitaoka 120a6e
      b1 -= bmap[val];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (j != jmax) BMP_ADD_ERROR(curr_pix[1], 7) /*  RIGHT   */
Shinya Kitaoka 120a6e
      if (i != imax)                               /*  UP      */
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        BMP_ADD_ERROR(*next_pix, 5)
Shinya Kitaoka 120a6e
        if (j > 0) BMP_ADD_ERROR(*prev_pix, 3)       /* UP LEFT  */
Shinya Kitaoka 120a6e
        if (j != jmax) BMP_ADD_ERROR(next_pix[1], 1) /* UP RIGHT */
Shinya Kitaoka 120a6e
        prev_pix = next_pix;
Shinya Kitaoka 120a6e
        next_pix++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      curr_pix++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ret_buf;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif /* __LIBSIMAGE__ */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
int make_bmp_palette(int colors, int grey, UCHAR *r, UCHAR *g, UCHAR *b)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int i, j, ind, val;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (colors) {
Shinya Kitaoka 120a6e
  case 2:
Shinya Kitaoka 120a6e
    for (i = 0; i < 2; i++) r[i] = g[i] = b[i] = i * 255;
Shinya Kitaoka 120a6e
    CASE 16 : for (i = 0; i < 16; i++) {
Shinya Kitaoka 120a6e
      for (j = 0; j < 16; j++) {
Shinya Kitaoka 120a6e
        ind    = i * 16 + j;
Shinya Kitaoka 120a6e
        val    = i * 16;
Shinya Kitaoka 120a6e
        r[ind] = g[ind] = b[ind] = val;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    CASE 256 : if (grey) {
Shinya Kitaoka 120a6e
      for (i = 0; i < 256; i++) r[i] = g[i] = b[i] = i;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      for (i = 0; i < 256; i++) {
Shinya Kitaoka 120a6e
        r[i] = BMP_RMAP(i);
Shinya Kitaoka 120a6e
        g[i] = BMP_GMAP(i);
Shinya Kitaoka 120a6e
        b[i] = BMP_BMAP(i);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  DEFAULT:
Shinya Kitaoka 120a6e
    return FALSE;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return TRUE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static UINT getshort(FILE *fp)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int c = getc(fp), c1 = getc(fp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return ((UINT)c) + (((UINT)c1) << 8);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static UINT getint(FILE *fp)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int c = getc(fp), c1 = getc(fp), c2 = getc(fp), c3 = getc(fp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return (((UINT)c) << 0) + (((UINT)c1) << 8) + (((UINT)c2) << 16) +
Shinya Kitaoka 120a6e
         (((UINT)c3) << 24);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static void putshort(FILE *fp, int i)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int c = (((UINT)i)) & 0xff, c1 = (((UINT)i) >> 8) & 0xff;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  putc(c, fp);
Shinya Kitaoka 120a6e
  putc(c1, fp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
static void putint(FILE *fp, int i)
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  int c = ((UINT)i) & 0xff, c1 = (((UINT)i) >> 8) & 0xff,
Shinya Kitaoka 120a6e
      c2 = (((UINT)i) >> 16) & 0xff, c3 = (((UINT)i) >> 24) & 0xff;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  putc(c, fp);
Shinya Kitaoka 120a6e
  putc(c1, fp);
Shinya Kitaoka 120a6e
  putc(c2, fp);
Shinya Kitaoka 120a6e
  putc(c3, fp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int writebmp(const MYSTRING filename, int xsize, int ysize, void *buffer,
Shinya Kitaoka 120a6e
             int bpp) {
Shinya Kitaoka 120a6e
  IMAGE img;
Shinya Kitaoka 120a6e
  img.xsize  = xsize;
Shinya Kitaoka 120a6e
  img.ysize  = ysize;
Shinya Kitaoka 120a6e
  img.buffer = buffer;
Shinya Kitaoka 120a6e
  switch (bpp) {
Shinya Kitaoka 120a6e
  case 8:
Shinya Kitaoka 120a6e
    img.type           = BMP_GREY256C;
Shinya Kitaoka 120a6e
    CASE 32 : img.type = BMP_RGB;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return img_write_bmp(filename, &img);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int readbmp(const MYSTRING filename, int *xsize, int *ysize, void **buffer) {
Shinya Kitaoka 120a6e
  IMAGE *img;
Shinya Kitaoka 120a6e
  int retCode = img_read_bmp(filename, &img);
Shinya Kitaoka 120a6e
  if (retCode != OK) {
Shinya Kitaoka 120a6e
    *xsize = *ysize = 0;
Shinya Kitaoka 120a6e
    *buffer         = 0;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    *xsize      = img->xsize;
Shinya Kitaoka 120a6e
    *ysize      = img->ysize;
Shinya Kitaoka 120a6e
    *buffer     = img->buffer;
Shinya Kitaoka 120a6e
    img->buffer = 0;
Shinya Kitaoka 120a6e
    free_img(img);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return retCode;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int readbmpregion(const MYSTRING filename, void **pimg, int x1, int y1, int x2,
Shinya Kitaoka 120a6e
                  int y2, int scale) {
Shinya Kitaoka 120a6e
  IMAGE *img;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int retCode = img_read_bmp_region(filename, &img, x1, y1, x2, y2, scale);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (retCode != OK) {
Shinya Kitaoka 120a6e
    *pimg = 0;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    *pimg = img->buffer;
Shinya Kitaoka 120a6e
    free(img);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return retCode;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int readbmp_size(const MYSTRING fname, int *lx, int *ly) {
Shinya Kitaoka 120a6e
  IMAGE *img;
Shinya Kitaoka 120a6e
  int retCode = img_read_bmp_generic(fname, BMP_READ_INFO, &img);
Shinya Kitaoka 120a6e
  if (retCode == OK) {
Shinya Kitaoka 120a6e
    *lx = img->xsize;
Shinya Kitaoka 120a6e
    *ly = img->ysize;
Shinya Kitaoka 120a6e
    free(img);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return retCode;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int readbmp_bbox(const MYSTRING fname, int *x0, int *y0, int *x1, int *y1) {
Shinya Kitaoka 120a6e
  IMAGE *img;
Shinya Kitaoka 120a6e
  int retCode = img_read_bmp_generic(fname, BMP_READ_INFO, &img);
Shinya Kitaoka 120a6e
  if (retCode == OK) {
Shinya Kitaoka 120a6e
    *x0 = 0;
Shinya Kitaoka 120a6e
    *x1 = 0;
Shinya Kitaoka 120a6e
    *x1 = img->xsize - 1;
Shinya Kitaoka 120a6e
    *y1 = img->ysize - 1;
Shinya Kitaoka 120a6e
    free(img);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return retCode;
Toshihiro Shimizu 890ddd
}