KiCad PCB EDA Suite
bitmap_io.cpp File Reference
#include <stdio.h>
#include "bitmap.h"
#include "bitmap_io.h"
#include "bitops.h"

Go to the source code of this file.

Classes

struct  bmp_info_s
 

Macros

#define INTBITS   ( 8 * sizeof( int ) )
 
#define TRY(x)
 
#define TRY_EOF(x)
 
#define TRY_STD(x)
 
#define COLTABLE(c)   ( ( c ) < bmpinfo.ncolors ? coltable[( c )] : 0 )
 

Typedefs

typedef struct bmp_info_s bmp_info_t
 

Functions

static int bm_readbody_bmp (FILE *f, double threshold, potrace_bitmap_t **bmp)
 
static int bm_readbody_pnm (FILE *f, double threshold, potrace_bitmap_t **bmp, int magic)
 
static int fgetc_ws (FILE *f)
 
static int readnum (FILE *f)
 
static int readbit (FILE *f)
 
int bm_read (FILE *f, double threshold, potrace_bitmap_t **bmp)
 
static int bmp_readint (FILE *f, int n, unsigned int *p)
 
static void bmp_pad_reset (void)
 
static int bmp_pad (FILE *f)
 
static int bmp_forward (FILE *f, int pos)
 
void bm_writepbm (FILE *f, potrace_bitmap_t *bm)
 
int bm_print (FILE *f, potrace_bitmap_t *bm)
 

Variables

const char * bm_read_error = NULL
 
static int bmp_count = 0
 
static int bmp_pos = 0
 

Macro Definition Documentation

#define COLTABLE (   c)    ( ( c ) < bmpinfo.ncolors ? coltable[( c )] : 0 )

Definition at line 603 of file bitmap_io.cpp.

Referenced by bm_readbody_bmp().

#define INTBITS   ( 8 * sizeof( int ) )

Definition at line 18 of file bitmap_io.cpp.

Referenced by bm_readbody_bmp().

#define TRY (   x)
Value:
if( x ) \
goto try_error

Definition at line 23 of file bitmap_io.cpp.

Referenced by bm_readbody_bmp().

#define TRY_EOF (   x)
Value:
if( x ) \
goto eof

Definition at line 26 of file bitmap_io.cpp.

Referenced by bm_readbody_bmp().

#define TRY_STD (   x)
Value:
if( x ) \
goto std_error

Definition at line 29 of file bitmap_io.cpp.

Referenced by bm_readbody_bmp(), and bm_readbody_pnm().

Typedef Documentation

typedef struct bmp_info_s bmp_info_t

Definition at line 515 of file bitmap_io.cpp.

Function Documentation

int bm_print ( FILE *  f,
potrace_bitmap_t bm 
)

Definition at line 1146 of file bitmap_io.cpp.

References BM_GET, potrace_bitmap_s::h, and potrace_bitmap_s::w.

1147 {
1148  int x, y;
1149  int xx, yy;
1150  int d;
1151  int sw, sh;
1152 
1153  sw = bm->w < 79 ? bm->w : 79;
1154  sh = bm->w < 79 ? bm->h : bm->h * sw * 44 / ( 79 * bm->w );
1155 
1156  for( yy = sh - 1; yy >= 0; yy-- )
1157  {
1158  for( xx = 0; xx < sw; xx++ )
1159  {
1160  d = 0;
1161 
1162  for( x = xx * bm->w / sw; x < ( xx + 1 ) * bm->w / sw; x++ )
1163  {
1164  for( y = yy * bm->h / sh; y < ( yy + 1 ) * bm->h / sh; y++ )
1165  {
1166  if( BM_GET( bm, x, y ) )
1167  {
1168  d++;
1169  }
1170  }
1171  }
1172 
1173  fputc( d ? '*' : ' ', f );
1174  }
1175 
1176  fputc( '\n', f );
1177  }
1178 
1179  return 0;
1180 }
#define BM_GET(bm, x, y)
Definition: bitmap.h:42
int bm_read ( FILE *  f,
double  threshold,
potrace_bitmap_t **  bmp 
)

Definition at line 159 of file bitmap_io.cpp.

References bm_readbody_bmp(), bm_readbody_pnm(), and fgetc_ws().

160 {
161  int magic[2];
162 
163  /* read magic number. We ignore whitespace and comments before the
164  * magic, for the benefit of concatenated files in P1-P3 format.
165  * Multiple P1-P3 images in a single file are not formally allowed
166  * by the PNM standard, but there is no harm in being lenient. */
167 
168  magic[0] = fgetc_ws( f );
169 
170  if( magic[0] == EOF )
171  {
172  return -3;
173  }
174 
175  magic[1] = fgetc( f );
176 
177  if( magic[0] == 'P' && magic[1] >= '1' && magic[1] <= '6' )
178  {
179  return bm_readbody_pnm( f, threshold, bmp, magic[1] );
180  }
181 
182  if( magic[0] == 'B' && magic[1] == 'M' )
183  {
184  return bm_readbody_bmp( f, threshold, bmp );
185  }
186 
187  return -4;
188 }
static int bm_readbody_bmp(FILE *f, double threshold, potrace_bitmap_t **bmp)
Definition: bitmap_io.cpp:612
static int bm_readbody_pnm(FILE *f, double threshold, potrace_bitmap_t **bmp, int magic)
Definition: bitmap_io.cpp:195
static int fgetc_ws(FILE *f)
Definition: bitmap_io.cpp:38
static int bm_readbody_bmp ( FILE *  f,
double  threshold,
potrace_bitmap_t **  bmp 
)
static

Definition at line 612 of file bitmap_io.cpp.

References bmp_info_s::AlphaMask, bmp_info_s::bits, bmp_info_s::BlueMask, bm_flip(), bm_free(), bm_index, bm_new(), BM_PUT, bm_read_error, bm_resize(), BM_UPUT, BM_WORDSIZE, bmp_forward(), bmp_pad(), bmp_pad_reset(), bmp_pos, bmp_readint(), bmp_info_s::ColorsImportant, COLTABLE, bmp_info_s::comp, bmp_info_s::ctbits, bmp_info_s::DataOffset, bmp_info_s::FileSize, bmp_info_s::GreenMask, bmp_info_s::h, bmp_info_s::ImageSize, bmp_info_s::InfoSize, INTBITS, lobit(), bmp_info_s::ncolors, bmp_info_s::Planes, bmp_info_s::RedMask, bmp_info_s::reserved, bmp_info_s::topdown, TRY, TRY_EOF, TRY_STD, bmp_info_s::w, bmp_info_s::XpixelsPerM, and bmp_info_s::YpixelsPerM.

Referenced by bm_read().

613 {
614  bmp_info_t bmpinfo;
615  int* coltable;
616  unsigned int b, c;
617  unsigned int i;
618  potrace_bitmap_t* bm;
619  int mask;
620  unsigned int x, y;
621  int col[2];
622  unsigned int bitbuf;
623  unsigned int n;
624  unsigned int redshift, greenshift, blueshift;
625  int col1[2];
626  int realheight; /* in case of incomplete file, keeps track of how
627  * many scan lines actually contain data */
628 
629  bm_read_error = NULL;
630  bm = NULL;
631  coltable = NULL;
632 
633  bmp_pos = 2; /* set file position */
634 
635  /* file header (minus magic number) */
636  TRY( bmp_readint( f, 4, &bmpinfo.FileSize ) );
637  TRY( bmp_readint( f, 4, &bmpinfo.reserved ) );
638  TRY( bmp_readint( f, 4, &bmpinfo.DataOffset ) );
639 
640  /* info header */
641  TRY( bmp_readint( f, 4, &bmpinfo.InfoSize ) );
642 
643  if( bmpinfo.InfoSize == 40 || bmpinfo.InfoSize == 64 || bmpinfo.InfoSize == 108
644  || bmpinfo.InfoSize == 124 )
645  {
646  /* Windows or new OS/2 format */
647  bmpinfo.ctbits = 32; /* sample size in color table */
648  TRY( bmp_readint( f, 4, &bmpinfo.w ) );
649  TRY( bmp_readint( f, 4, &bmpinfo.h ) );
650  TRY( bmp_readint( f, 2, &bmpinfo.Planes ) );
651  TRY( bmp_readint( f, 2, &bmpinfo.bits ) );
652  TRY( bmp_readint( f, 4, &bmpinfo.comp ) );
653  TRY( bmp_readint( f, 4, &bmpinfo.ImageSize ) );
654  TRY( bmp_readint( f, 4, &bmpinfo.XpixelsPerM ) );
655  TRY( bmp_readint( f, 4, &bmpinfo.YpixelsPerM ) );
656  TRY( bmp_readint( f, 4, &bmpinfo.ncolors ) );
657  TRY( bmp_readint( f, 4, &bmpinfo.ColorsImportant ) );
658 
659  if( bmpinfo.InfoSize >= 108 )
660  {
661  /* V4 and V5 bitmaps */
662  TRY( bmp_readint( f, 4, &bmpinfo.RedMask ) );
663  TRY( bmp_readint( f, 4, &bmpinfo.GreenMask ) );
664  TRY( bmp_readint( f, 4, &bmpinfo.BlueMask ) );
665  TRY( bmp_readint( f, 4, &bmpinfo.AlphaMask ) );
666  }
667 
668  if( bmpinfo.w > 0x7fffffff )
669  {
670  goto format_error;
671  }
672 
673  if( bmpinfo.h > 0x7fffffff )
674  {
675  bmpinfo.h = ( -bmpinfo.h ) & 0xffffffff;
676  bmpinfo.topdown = 1;
677  }
678  else
679  {
680  bmpinfo.topdown = 0;
681  }
682 
683  if( bmpinfo.h > 0x7fffffff )
684  {
685  goto format_error;
686  }
687  }
688  else if( bmpinfo.InfoSize == 12 )
689  {
690  /* old OS/2 format */
691  bmpinfo.ctbits = 24; /* sample size in color table */
692  TRY( bmp_readint( f, 2, &bmpinfo.w ) );
693  TRY( bmp_readint( f, 2, &bmpinfo.h ) );
694  TRY( bmp_readint( f, 2, &bmpinfo.Planes ) );
695  TRY( bmp_readint( f, 2, &bmpinfo.bits ) );
696  bmpinfo.comp = 0;
697  bmpinfo.ncolors = 0;
698  bmpinfo.topdown = 0;
699  }
700  else
701  {
702  goto format_error;
703  }
704 
705  if( bmpinfo.comp == 3 && bmpinfo.InfoSize < 108 )
706  {
707  /* bitfield feature is only understood with V4 and V5 format */
708  goto format_error;
709  }
710 
711  if( bmpinfo.comp > 3 || bmpinfo.bits > 32 )
712  {
713  goto format_error;
714  }
715 
716  /* forward to color table (e.g., if bmpinfo.InfoSize == 64) */
717  TRY( bmp_forward( f, 14 + bmpinfo.InfoSize ) );
718 
719  if( bmpinfo.Planes != 1 )
720  {
721  bm_read_error = "cannot handle bmp planes";
722  goto format_error; /* can't handle planes */
723  }
724 
725  if( bmpinfo.ncolors == 0 && bmpinfo.bits <= 8 )
726  {
727  bmpinfo.ncolors = 1 << bmpinfo.bits;
728  }
729 
730  /* color table, present only if bmpinfo.bits <= 8. */
731  if( bmpinfo.bits <= 8 )
732  {
733  coltable = (int*) calloc( bmpinfo.ncolors, sizeof( int ) );
734 
735  if( !coltable )
736  {
737  goto std_error;
738  }
739 
740  /* NOTE: since we are reading a bitmap, we can immediately convert
741  * the color table entries to bits. */
742  for( i = 0; i < bmpinfo.ncolors; i++ )
743  {
744  TRY( bmp_readint( f, bmpinfo.ctbits / 8, &c ) );
745  c = ( ( c >> 16 ) & 0xff ) + ( ( c >> 8 ) & 0xff ) + ( c & 0xff );
746  coltable[i] = ( c > 3 * threshold * 255 ? 0 : 1 );
747 
748  if( i < 2 )
749  {
750  col1[i] = c;
751  }
752  }
753  }
754 
755  /* forward to data */
756  if( bmpinfo.InfoSize != 12 )
757  {
758  /* not old OS/2 format */
759  TRY( bmp_forward( f, bmpinfo.DataOffset ) );
760  }
761 
762  /* allocate bitmap */
763  bm = bm_new( bmpinfo.w, bmpinfo.h );
764 
765  if( !bm )
766  {
767  goto std_error;
768  }
769 
770  realheight = 0;
771 
772  switch( bmpinfo.bits + 0x100 * bmpinfo.comp )
773  {
774  default:
775  goto format_error; break;
776 
777  case 0x001: /* monochrome palette */
778 
779  if( col1[0] < col1[1] )
780  {
781  /* make the darker color black */
782  mask = 0xff;
783  }
784  else
785  {
786  mask = 0;
787  }
788 
789  /* raster data */
790  for( y = 0; y < bmpinfo.h; y++ )
791  {
792  realheight = y + 1;
793  bmp_pad_reset();
794 
795  for( i = 0; 8 * i < bmpinfo.w; i++ )
796  {
797  TRY_EOF( bmp_readint( f, 1, &b ) );
798  b ^= mask;
799  *bm_index( bm, i * 8, y ) |= ( (potrace_word) b )
800  << ( 8 * ( BM_WORDSIZE - 1 - ( i % BM_WORDSIZE ) ) );
801  }
802 
803  TRY( bmp_pad( f ) );
804  }
805 
806  break;
807 
808  case 0x002: /* 2-bit to 8-bit palettes */
809  case 0x003:
810  case 0x004:
811  case 0x005:
812  case 0x006:
813  case 0x007:
814  case 0x008:
815 
816  for( y = 0; y < bmpinfo.h; y++ )
817  {
818  realheight = y + 1;
819  bmp_pad_reset();
820  bitbuf = 0; /* bit buffer: bits in buffer are high-aligned */
821  n = 0; /* number of bits currently in bitbuffer */
822 
823  for( x = 0; x < bmpinfo.w; x++ )
824  {
825  if( n < bmpinfo.bits )
826  {
827  TRY_EOF( bmp_readint( f, 1, &b ) );
828  bitbuf |= b << ( INTBITS - 8 - n );
829  n += 8;
830  }
831 
832  b = bitbuf >> ( INTBITS - bmpinfo.bits );
833  bitbuf <<= bmpinfo.bits;
834  n -= bmpinfo.bits;
835  BM_UPUT( bm, x, y, COLTABLE( b ) );
836  }
837 
838  TRY( bmp_pad( f ) );
839  }
840 
841  break;
842 
843  case 0x010: /* 16-bit encoding */
844  /* can't do this format because it is not well-documented and I
845  * don't have any samples */
846  bm_read_error = "cannot handle bmp 16-bit coding";
847  goto format_error;
848  break;
849 
850  case 0x018: /* 24-bit encoding */
851  case 0x020: /* 32-bit encoding */
852 
853  for( y = 0; y < bmpinfo.h; y++ )
854  {
855  realheight = y + 1;
856  bmp_pad_reset();
857 
858  for( x = 0; x < bmpinfo.w; x++ )
859  {
860  TRY_EOF( bmp_readint( f, bmpinfo.bits / 8, &c ) );
861  c = ( ( c >> 16 ) & 0xff ) + ( ( c >> 8 ) & 0xff ) + ( c & 0xff );
862  BM_UPUT( bm, x, y, c > 3 * threshold * 255 ? 0 : 1 );
863  }
864 
865  TRY( bmp_pad( f ) );
866  }
867 
868  break;
869 
870  case 0x320: /* 32-bit encoding with bitfields */
871 
872  if( bmpinfo.RedMask == 0 || bmpinfo.GreenMask == 0 || bmpinfo.BlueMask == 0 )
873  {
874  goto format_error;
875  }
876 
877  redshift = lobit( bmpinfo.RedMask );
878  greenshift = lobit( bmpinfo.GreenMask );
879  blueshift = lobit( bmpinfo.BlueMask );
880 
881  for( y = 0; y < bmpinfo.h; y++ )
882  {
883  realheight = y + 1;
884  bmp_pad_reset();
885 
886  for( x = 0; x < bmpinfo.w; x++ )
887  {
888  TRY_EOF( bmp_readint( f, bmpinfo.bits / 8, &c ) );
889  c = ( ( c & bmpinfo.RedMask ) >> redshift )
890  + ( ( c & bmpinfo.GreenMask ) >> greenshift )
891  + ( ( c & bmpinfo.BlueMask ) >> blueshift );
892  BM_UPUT( bm, x, y, c > 3 * threshold * 255 ? 0 : 1 );
893  }
894 
895  TRY( bmp_pad( f ) );
896  }
897 
898  break;
899 
900  case 0x204: /* 4-bit runlength compressed encoding (RLE4) */
901  x = 0;
902  y = 0;
903 
904  while( 1 )
905  {
906  TRY_EOF( bmp_readint( f, 1, &b ) ); /* opcode */
907  TRY_EOF( bmp_readint( f, 1, &c ) ); /* argument */
908 
909  if( b > 0 )
910  {
911  /* repeat count */
912  col[0] = COLTABLE( ( c >> 4 ) & 0xf );
913  col[1] = COLTABLE( c & 0xf );
914 
915  for( i = 0; i < b && x < bmpinfo.w; i++ )
916  {
917  if( x >= bmpinfo.w )
918  {
919  x = 0;
920  y++;
921  }
922 
923  if( x >= bmpinfo.w || y >= bmpinfo.h )
924  {
925  break;
926  }
927 
928  realheight = y + 1;
929  BM_PUT( bm, x, y, col[i & 1] );
930  x++;
931  }
932  }
933  else if( c == 0 )
934  {
935  /* end of line */
936  y++;
937  x = 0;
938  }
939  else if( c == 1 )
940  {
941  /* end of bitmap */
942  break;
943  }
944  else if( c == 2 )
945  {
946  /* "delta": skip pixels in x and y directions */
947  TRY_EOF( bmp_readint( f, 1, &b ) ); /* x offset */
948  TRY_EOF( bmp_readint( f, 1, &c ) ); /* y offset */
949  x += b;
950  y += c;
951  }
952  else
953  {
954  /* verbatim segment */
955  for( i = 0; i < c; i++ )
956  {
957  if( ( i & 1 ) == 0 )
958  {
959  TRY_EOF( bmp_readint( f, 1, &b ) );
960  }
961 
962  if( x >= bmpinfo.w )
963  {
964  x = 0;
965  y++;
966  }
967 
968  if( x >= bmpinfo.w || y >= bmpinfo.h )
969  {
970  break;
971  }
972 
973  realheight = y + 1;
974  BM_PUT( bm, x, y, COLTABLE( ( b >> ( 4 - 4 * ( i & 1 ) ) ) & 0xf ) );
975  x++;
976  }
977 
978  if( ( c + 1 ) & 2 )
979  {
980  /* pad to 16-bit boundary */
981  TRY_EOF( bmp_readint( f, 1, &b ) );
982  }
983  }
984  }
985 
986  break;
987 
988  case 0x108: /* 8-bit runlength compressed encoding (RLE8) */
989  x = 0;
990  y = 0;
991 
992  while( 1 )
993  {
994  TRY_EOF( bmp_readint( f, 1, &b ) ); /* opcode */
995  TRY_EOF( bmp_readint( f, 1, &c ) ); /* argument */
996 
997  if( b > 0 )
998  {
999  /* repeat count */
1000  for( i = 0; i < b; i++ )
1001  {
1002  if( x >= bmpinfo.w )
1003  {
1004  x = 0;
1005  y++;
1006  }
1007 
1008  if( x >= bmpinfo.w || y >= bmpinfo.h )
1009  {
1010  break;
1011  }
1012 
1013  realheight = y + 1;
1014  BM_PUT( bm, x, y, COLTABLE( c ) );
1015  x++;
1016  }
1017  }
1018  else if( c == 0 )
1019  {
1020  /* end of line */
1021  y++;
1022  x = 0;
1023  }
1024  else if( c == 1 )
1025  {
1026  /* end of bitmap */
1027  break;
1028  }
1029  else if( c == 2 )
1030  {
1031  /* "delta": skip pixels in x and y directions */
1032  TRY_EOF( bmp_readint( f, 1, &b ) ); /* x offset */
1033  TRY_EOF( bmp_readint( f, 1, &c ) ); /* y offset */
1034  x += b;
1035  y += c;
1036  }
1037  else
1038  {
1039  /* verbatim segment */
1040  for( i = 0; i < c; i++ )
1041  {
1042  TRY_EOF( bmp_readint( f, 1, &b ) );
1043 
1044  if( x >= bmpinfo.w )
1045  {
1046  x = 0;
1047  y++;
1048  }
1049 
1050  if( x >= bmpinfo.w || y >= bmpinfo.h )
1051  {
1052  break;
1053  }
1054 
1055  realheight = y + 1;
1056  BM_PUT( bm, x, y, COLTABLE( b ) );
1057  x++;
1058  }
1059 
1060  if( c & 1 )
1061  {
1062  /* pad input to 16-bit boundary */
1063  TRY_EOF( bmp_readint( f, 1, &b ) );
1064  }
1065  }
1066  }
1067 
1068  break;
1069  } /* switch */
1070 
1071  /* skip any potential junk after the data section, but don't
1072  * complain in case EOF is encountered */
1073  bmp_forward( f, bmpinfo.FileSize );
1074 
1075  free( coltable );
1076 
1077  if( bmpinfo.topdown )
1078  {
1079  bm_flip( bm );
1080  }
1081 
1082  *bmp = bm;
1083  return 0;
1084 
1085 eof:
1086  TRY_STD( bm_resize( bm, realheight ) );
1087  free( coltable );
1088 
1089  if( bmpinfo.topdown )
1090  {
1091  bm_flip( bm );
1092  }
1093 
1094  *bmp = bm;
1095  return 1;
1096 
1097 format_error:
1098 try_error:
1099  free( coltable );
1100  bm_free( bm );
1101 
1102  if( !bm_read_error )
1103  {
1104  bm_read_error = "invalid bmp file";
1105  }
1106 
1107  return -2;
1108 
1109 std_error:
1110  free( coltable );
1111  bm_free( bm );
1112  return -1;
1113 }
static void bm_flip(potrace_bitmap_t *bm)
Definition: bitmap.h:217
unsigned int Planes
Definition: bitmap_io.cpp:500
static int bmp_forward(FILE *f, int pos)
Definition: bitmap_io.cpp:581
#define TRY_EOF(x)
Definition: bitmap_io.cpp:26
unsigned int DataOffset
Definition: bitmap_io.cpp:496
static void bm_free(potrace_bitmap_t *bm)
Definition: bitmap.h:102
static int bmp_pos
Definition: bitmap_io.cpp:520
unsigned int FileSize
Definition: bitmap_io.cpp:494
#define bm_index(bm, x, y)
Definition: bitmap.h:33
#define BM_WORDSIZE
Definition: bitmap.h:24
#define BM_UPUT(bm, x, y, b)
Definition: bitmap.h:41
static int bmp_pad(FILE *f)
Definition: bitmap_io.cpp:558
unsigned int YpixelsPerM
Definition: bitmap_io.cpp:505
unsigned int reserved
Definition: bitmap_io.cpp:495
unsigned long potrace_word
Definition: potracelib.h:53
unsigned int ctbits
Definition: bitmap_io.cpp:512
unsigned int ColorsImportant
Definition: bitmap_io.cpp:507
#define INTBITS
Definition: bitmap_io.cpp:18
unsigned int comp
Definition: bitmap_io.cpp:502
static int bmp_readint(FILE *f, int n, unsigned int *p)
Definition: bitmap_io.cpp:524
static unsigned int lobit(unsigned int x)
Definition: bitops.h:59
const char * bm_read_error
Definition: bitmap_io.cpp:157
unsigned int InfoSize
Definition: bitmap_io.cpp:497
#define TRY_STD(x)
Definition: bitmap_io.cpp:29
static potrace_bitmap_t * bm_new(int w, int h)
Definition: bitmap.h:115
static int bm_resize(potrace_bitmap_t *bm, int h)
Definition: bitmap.h:237
#define TRY(x)
Definition: bitmap_io.cpp:23
unsigned int BlueMask
Definition: bitmap_io.cpp:510
unsigned int h
Definition: bitmap_io.cpp:499
unsigned int AlphaMask
Definition: bitmap_io.cpp:511
unsigned int GreenMask
Definition: bitmap_io.cpp:509
unsigned int RedMask
Definition: bitmap_io.cpp:508
#define COLTABLE(c)
Definition: bitmap_io.cpp:603
unsigned int ncolors
Definition: bitmap_io.cpp:506
unsigned int w
Definition: bitmap_io.cpp:498
unsigned int ImageSize
Definition: bitmap_io.cpp:503
unsigned int XpixelsPerM
Definition: bitmap_io.cpp:504
#define BM_PUT(bm, x, y, b)
Definition: bitmap.h:46
unsigned int bits
Definition: bitmap_io.cpp:501
static void bmp_pad_reset(void)
Definition: bitmap_io.cpp:550
static int bm_readbody_pnm ( FILE *  f,
double  threshold,
potrace_bitmap_t **  bmp,
int  magic 
)
static

Definition at line 195 of file bitmap_io.cpp.

References bm_flip(), bm_free(), bm_index, bm_new(), bm_read_error, bm_resize(), BM_UPUT, BM_WORDSIZE, max, readbit(), readnum(), and TRY_STD.

Referenced by bm_read().

196 {
197  potrace_bitmap_t* bm;
198  int x, y, i, b, b1, sum;
199  int bpr; /* bytes per row (as opposed to 4*bm->c) */
200  int w, h, max;
201  int realheight; /* in case of incomplete file, keeps track of how
202  * many scan lines actually contain data */
203 
204  bm = NULL;
205 
206  w = readnum( f );
207 
208  if( w < 0 )
209  {
210  goto format_error;
211  }
212 
213  h = readnum( f );
214 
215  if( h < 0 )
216  {
217  goto format_error;
218  }
219 
220  /* allocate bitmap */
221  bm = bm_new( w, h );
222 
223  if( !bm )
224  {
225  goto std_error;
226  }
227 
228  realheight = 0;
229 
230  switch( magic )
231  {
232  default:
233  /* not reached */
234  goto format_error;
235 
236  case '1':
237  /* read P1 format: PBM ascii */
238 
239  for( y = 0; y < h; y++ )
240  {
241  realheight = y + 1;
242 
243  for( x = 0; x < w; x++ )
244  {
245  b = readbit( f );
246 
247  if( b < 0 )
248  {
249  goto eof;
250  }
251 
252  BM_UPUT( bm, x, y, b );
253  }
254  }
255 
256  break;
257 
258  case '2':
259  /* read P2 format: PGM ascii */
260 
261  max = readnum( f );
262 
263  if( max < 1 )
264  {
265  goto format_error;
266  }
267 
268  for( y = 0; y < h; y++ )
269  {
270  realheight = y + 1;
271 
272  for( x = 0; x < w; x++ )
273  {
274  b = readnum( f );
275 
276  if( b < 0 )
277  {
278  goto eof;
279  }
280 
281  BM_UPUT( bm, x, y, b > threshold * max ? 0 : 1 );
282  }
283  }
284 
285  break;
286 
287  case '3':
288  /* read P3 format: PPM ascii */
289 
290  max = readnum( f );
291 
292  if( max < 1 )
293  {
294  goto format_error;
295  }
296 
297  for( y = 0; y < h; y++ )
298  {
299  realheight = y + 1;
300 
301  for( x = 0; x < w; x++ )
302  {
303  sum = 0;
304 
305  for( i = 0; i < 3; i++ )
306  {
307  b = readnum( f );
308 
309  if( b < 0 )
310  {
311  goto eof;
312  }
313 
314  sum += b;
315  }
316 
317  BM_UPUT( bm, x, y, sum > 3 * threshold * max ? 0 : 1 );
318  }
319  }
320 
321  break;
322 
323  case '4':
324  /* read P4 format: PBM raw */
325 
326  b = fgetc( f ); /* read single white-space character after height */
327 
328  if( b == EOF )
329  {
330  goto format_error;
331  }
332 
333  bpr = ( w + 7 ) / 8;
334 
335  for( y = 0; y < h; y++ )
336  {
337  realheight = y + 1;
338 
339  for( i = 0; i < bpr; i++ )
340  {
341  b = fgetc( f );
342 
343  if( b == EOF )
344  {
345  goto eof;
346  }
347 
348  *bm_index( bm, i * 8, y ) |= ( (potrace_word) b )
349  << ( 8 * ( BM_WORDSIZE - 1 - ( i % BM_WORDSIZE ) ) );
350  }
351  }
352 
353  break;
354 
355  case '5':
356  /* read P5 format: PGM raw */
357 
358  max = readnum( f );
359 
360  if( max < 1 )
361  {
362  goto format_error;
363  }
364 
365  b = fgetc( f ); /* read single white-space character after max */
366 
367  if( b == EOF )
368  {
369  goto format_error;
370  }
371 
372  for( y = 0; y < h; y++ )
373  {
374  realheight = y + 1;
375 
376  for( x = 0; x < w; x++ )
377  {
378  b = fgetc( f );
379 
380  if( b == EOF )
381  goto eof;
382 
383  if( max >= 256 )
384  {
385  b <<= 8;
386  b1 = fgetc( f );
387 
388  if( b1 == EOF )
389  goto eof;
390 
391  b |= b1;
392  }
393 
394  BM_UPUT( bm, x, y, b > threshold * max ? 0 : 1 );
395  }
396  }
397 
398  break;
399 
400  case '6':
401  /* read P6 format: PPM raw */
402 
403  max = readnum( f );
404 
405  if( max < 1 )
406  {
407  goto format_error;
408  }
409 
410  b = fgetc( f ); /* read single white-space character after max */
411 
412  if( b == EOF )
413  {
414  goto format_error;
415  }
416 
417  for( y = 0; y < h; y++ )
418  {
419  realheight = y + 1;
420 
421  for( x = 0; x < w; x++ )
422  {
423  sum = 0;
424 
425  for( i = 0; i < 3; i++ )
426  {
427  b = fgetc( f );
428 
429  if( b == EOF )
430  {
431  goto eof;
432  }
433 
434  if( max >= 256 )
435  {
436  b <<= 8;
437  b1 = fgetc( f );
438 
439  if( b1 == EOF )
440  goto eof;
441 
442  b |= b1;
443  }
444 
445  sum += b;
446  }
447 
448  BM_UPUT( bm, x, y, sum > 3 * threshold * max ? 0 : 1 );
449  }
450  }
451 
452  break;
453  }
454 
455  bm_flip( bm );
456  *bmp = bm;
457  return 0;
458 
459 eof:
460  TRY_STD( bm_resize( bm, realheight ) );
461  bm_flip( bm );
462  *bmp = bm;
463  return 1;
464 
465 format_error:
466  bm_free( bm );
467 
468  if( magic == '1' || magic == '4' )
469  {
470  bm_read_error = "invalid pbm file";
471  }
472  else if( magic == '2' || magic == '5' )
473  {
474  bm_read_error = "invalid pgm file";
475  }
476  else
477  {
478  bm_read_error = "invalid ppm file";
479  }
480 
481  return -2;
482 
483 std_error:
484  bm_free( bm );
485  return -1;
486 }
static void bm_flip(potrace_bitmap_t *bm)
Definition: bitmap.h:217
static void bm_free(potrace_bitmap_t *bm)
Definition: bitmap.h:102
#define bm_index(bm, x, y)
Definition: bitmap.h:33
#define BM_WORDSIZE
Definition: bitmap.h:24
#define BM_UPUT(bm, x, y, b)
Definition: bitmap.h:41
unsigned long potrace_word
Definition: potracelib.h:53
static int readbit(FILE *f)
Definition: bitmap_io.cpp:123
const char * bm_read_error
Definition: bitmap_io.cpp:157
#define TRY_STD(x)
Definition: bitmap_io.cpp:29
static potrace_bitmap_t * bm_new(int w, int h)
Definition: bitmap.h:115
static int bm_resize(potrace_bitmap_t *bm, int h)
Definition: bitmap.h:237
#define max(a, b)
Definition: auxiliary.h:86
static int readnum(FILE *f)
Definition: bitmap_io.cpp:73
void bm_writepbm ( FILE *  f,
potrace_bitmap_t bm 
)

Definition at line 1119 of file bitmap_io.cpp.

References bm_index, BM_WORDSIZE, potrace_bitmap_s::h, bmp_info_s::h, potrace_bitmap_s::w, and bmp_info_s::w.

1120 {
1121  int w, h, bpr, y, i, c;
1122 
1123  w = bm->w;
1124  h = bm->h;
1125 
1126  bpr = ( w + 7 ) / 8;
1127 
1128  fprintf( f, "P4\n%d %d\n", w, h );
1129 
1130  for( y = h - 1; y >= 0; y-- )
1131  {
1132  for( i = 0; i < bpr; i++ )
1133  {
1134  c = ( *bm_index( bm, i * 8, y ) >> ( 8 * ( BM_WORDSIZE - 1 - ( i % BM_WORDSIZE ) ) ) )
1135  & 0xff;
1136  fputc( c, f );
1137  }
1138  }
1139 }
#define bm_index(bm, x, y)
Definition: bitmap.h:33
#define BM_WORDSIZE
Definition: bitmap.h:24
static int bmp_forward ( FILE *  f,
int  pos 
)
static

Definition at line 581 of file bitmap_io.cpp.

References bmp_count, and bmp_pos.

Referenced by bm_readbody_bmp().

582 {
583  int b;
584 
585  while( bmp_pos < pos )
586  {
587  b = fgetc( f );
588 
589  if( b == EOF )
590  {
591  return 1;
592  }
593 
594  bmp_pos++;
595  bmp_count++;
596  }
597 
598  return 0;
599 }
static int bmp_pos
Definition: bitmap_io.cpp:520
static int bmp_count
Definition: bitmap_io.cpp:519
static int bmp_pad ( FILE *  f)
static

Definition at line 558 of file bitmap_io.cpp.

References bmp_count, and bmp_pos.

Referenced by bm_readbody_bmp().

559 {
560  int c, i, b;
561 
562  c = ( -bmp_count ) & 3;
563 
564  for( i = 0; i < c; i++ )
565  {
566  b = fgetc( f );
567 
568  if( b == EOF )
569  {
570  return 1;
571  }
572  }
573 
574  bmp_pos += c;
575  bmp_count = 0;
576  return 0;
577 }
static int bmp_pos
Definition: bitmap_io.cpp:520
static int bmp_count
Definition: bitmap_io.cpp:519
static void bmp_pad_reset ( void  )
static

Definition at line 550 of file bitmap_io.cpp.

References bmp_count.

Referenced by bm_readbody_bmp().

551 {
552  bmp_count = 0;
553 }
static int bmp_count
Definition: bitmap_io.cpp:519
static int bmp_readint ( FILE *  f,
int  n,
unsigned int *  p 
)
static

Definition at line 524 of file bitmap_io.cpp.

References bmp_count, and bmp_pos.

Referenced by bm_readbody_bmp().

525 {
526  int i;
527  unsigned int sum = 0;
528  int b;
529 
530  for( i = 0; i < n; i++ )
531  {
532  b = fgetc( f );
533 
534  if( b == EOF )
535  {
536  return 1;
537  }
538 
539  sum += (unsigned) b << ( 8 * i );
540  }
541 
542  bmp_count += n;
543  bmp_pos += n;
544  *p = sum;
545  return 0;
546 }
static int bmp_pos
Definition: bitmap_io.cpp:520
static int bmp_count
Definition: bitmap_io.cpp:519
static int fgetc_ws ( FILE *  f)
static

Definition at line 38 of file bitmap_io.cpp.

Referenced by bm_read(), readbit(), and readnum().

39 {
40  int c;
41 
42  while( 1 )
43  {
44  c = fgetc( f );
45 
46  if( c == '#' )
47  {
48  while( 1 )
49  {
50  c = fgetc( f );
51 
52  if( c == '\n' || c == EOF )
53  {
54  break;
55  }
56  }
57  }
58 
59  /* space, tab, line feed, carriage return, form-feed */
60  if( c != ' ' && c != '\t' && c != '\r' && c != '\n' && c != 12 )
61  {
62  return c;
63  }
64  }
65 }
static int readbit ( FILE *  f)
static

Definition at line 123 of file bitmap_io.cpp.

References fgetc_ws().

Referenced by bm_readbody_pnm().

124 {
125  int c;
126 
127  /* skip whitespace and comments */
128  while( 1 )
129  {
130  c = fgetc_ws( f );
131 
132  if( c == EOF )
133  {
134  return -1;
135  }
136 
137  if( c >= '0' && c <= '1' )
138  {
139  break;
140  }
141  }
142 
143  return c - '0';
144 }
static int fgetc_ws(FILE *f)
Definition: bitmap_io.cpp:38
static int readnum ( FILE *  f)
static

Definition at line 73 of file bitmap_io.cpp.

References fgetc_ws().

Referenced by bm_readbody_pnm().

74 {
75  int c;
76  int acc;
77 
78  /* skip whitespace and comments */
79  while( 1 )
80  {
81  c = fgetc_ws( f );
82 
83  if( c == EOF )
84  {
85  return -1;
86  }
87 
88  if( c >= '0' && c <= '9' )
89  {
90  break;
91  }
92  }
93 
94  /* first digit is already in c */
95  acc = c - '0';
96 
97  while( 1 )
98  {
99  c = fgetc( f );
100 
101  if( c == EOF )
102  {
103  break;
104  }
105 
106  if( c < '0' || c > '9' )
107  {
108  ungetc( c, f );
109  break;
110  }
111 
112  acc *= 10;
113  acc += c - '0';
114  }
115 
116  return acc;
117 }
static int fgetc_ws(FILE *f)
Definition: bitmap_io.cpp:38

Variable Documentation

const char* bm_read_error = NULL

Definition at line 157 of file bitmap_io.cpp.

Referenced by bm_readbody_bmp(), and bm_readbody_pnm().

int bmp_count = 0
static

Definition at line 519 of file bitmap_io.cpp.

Referenced by bmp_forward(), bmp_pad(), bmp_pad_reset(), and bmp_readint().

int bmp_pos = 0
static

Definition at line 520 of file bitmap_io.cpp.

Referenced by bm_readbody_bmp(), bmp_forward(), bmp_pad(), and bmp_readint().