Skip to content

Commit

Permalink
Added x/ba-bm.bmp
Browse files Browse the repository at this point in the history
The code for this is kind of ugly. Sorry.
  • Loading branch information
jsummers committed Dec 5, 2016
1 parent fe7fb3d commit f6d6f88
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -4,4 +4,5 @@
/g
/q
/b
/x
/stamp
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -26,7 +26,7 @@ stamp: $(BMPSUITE)
touch stamp

checksums checksums.tmp: stamp
md5sum -b g/* q/* b/* | LC_ALL=C sort -k2 > $@
md5sum -b g/* q/* b/* x/* | LC_ALL=C sort -k2 > $@

# check2 is not portable, due to differences in sort order, and in md5sum's
# output. But it's useful for development, because it can find unlisted files.
Expand All @@ -40,5 +40,5 @@ check: stamp

clean:
rm -f $(BMPSUITE) *.o
rm -f stamp g/*.bmp q/*.bmp b/*.bmp
rm -f stamp g/*.bmp q/*.bmp b/*.bmp x/*.bmp

60 changes: 44 additions & 16 deletions bmpsuite.c
Expand Up @@ -145,6 +145,8 @@ struct context {
int palette_reserve; // Reserve palette color #0
int cbsize_flag;
int trnstype; // Transparency type: 0=none, 1=binary, 2=full
int ba_fmt;
int ba_hdr_size;
};

static void set_int16(struct context *c, size_t offset, int v)
Expand Down Expand Up @@ -752,7 +754,7 @@ static void write_palette(struct context *c)
int r,g,b;
int bppe; // bytes per palette entry

offs = 14+c->headersize+c->bitfieldssize;
offs = c->ba_hdr_size+14+c->headersize+c->bitfieldssize;
bppe = (c->headersize<=12) ? 3 : 4;

if(c->bpp==8) {
Expand Down Expand Up @@ -877,26 +879,37 @@ static void write_palette(struct context *c)
}
}

static void write_fileheader(struct context *c)
static void write_ba_header(struct context *c)
{
c->mem[0]='B';
c->mem[1]='M';
c->mem[1]='A';
set_int32(c, 2, 14+14+c->headersize);
}

static void write_fileheader(struct context *c, int offset)
{
c->mem[offset+0]='B';
c->mem[offset+1]='M';
if(c->bad_bfSize)
set_int32(c,2,0x7ddddddd);
set_int32(c,offset+2,0x7ddddddd);
else if(c->cbsize_flag)
set_int32(c,2,14+c->headersize);
set_int32(c,offset+2,14+c->headersize);
else
set_int32(c,2,(int)c->mem_used);
set_int32(c,10,c->bitsoffset);
set_int32(c,offset+2,(int)(c->mem_used - c->ba_hdr_size));

// One might think that for BA format, the bitsoffset field would be
// relative to the corresponding BM header. But it is not. It is an
// absolute file position.
set_int32(c,offset+10,c->bitsoffset);
}

static void write_bitmapcoreheader(struct context *c)
static void write_bitmapcoreheader(struct context *c, int offset)
{
set_int32(c,14+0,c->headersize);
set_int16(c,14+4,c->w);
set_int16(c,14+6,c->h);
set_int16(c,14+8,1); // planes
set_int16(c,14+10,c->bpp);
set_int32(c,offset+0,c->headersize);
set_int16(c,offset+4,c->w);
set_int16(c,offset+6,c->h);
set_int16(c,offset+8,1); // planes
set_int16(c,offset+10,c->bpp);
}

static unsigned int fixed_2_30(double x)
Expand Down Expand Up @@ -1034,10 +1047,12 @@ static int make_bmp(struct context *c)
write_lprofile(c);
}
if(c->headersize<=12)
write_bitmapcoreheader(c);
write_bitmapcoreheader(c, c->ba_hdr_size + 14);
else
write_bitmapinfoheader(c);
write_fileheader(c);

if(c->ba_fmt) write_ba_header(c);
write_fileheader(c, c->ba_hdr_size);
return 1;
}

Expand Down Expand Up @@ -1070,6 +1085,10 @@ static int make_bmp_file(struct context *c)

static void set_calculated_fields(struct context *c)
{
if(c->ba_fmt) {
c->ba_hdr_size = 14;
c->cbsize_flag = 1;
}

if(c->bpp==8 && c->pal_entries!=256) {
c->clr_used = c->pal_entries;
Expand All @@ -1092,7 +1111,7 @@ static void set_calculated_fields(struct context *c)
c->palettesize = c->pal_entries*4;
}

c->bitsoffset = 14 + c->headersize + c->bitfieldssize + c->palettesize + c->extrabytessize;
c->bitsoffset = c->ba_hdr_size + 14 + c->headersize + c->bitfieldssize + c->palettesize + c->extrabytessize;

if(c->rletrns || (c->bf[I_A] && c->nbits[I_A]==1)) {
c->trnstype = 1; // binary transparency
Expand Down Expand Up @@ -1153,6 +1172,7 @@ static int run(struct global_context *glctx, struct context *c)
my_mkdir("g");
my_mkdir("q");
my_mkdir("b");
my_mkdir("x");

defaultbmp(glctx, c);
c->filename = "g/pal8.bmp";
Expand Down Expand Up @@ -1975,6 +1995,14 @@ static int run(struct global_context *glctx, struct context *c)
set_calculated_fields(c);
if(!make_bmp_file(c)) goto done;

defaultbmp(glctx, c);
c->filename = "x/ba-bm.bmp";
c->ba_fmt = 1;
c->headersize = 12;
c->pal_entries = 256;
set_calculated_fields(c);
if(!make_bmp_file(c)) goto done;

retval = 1;
done:
return retval;
Expand Down
1 change: 1 addition & 0 deletions checksums
Expand Up @@ -84,3 +84,4 @@ a995a24795c9e311d6604292b8010848 *q/rgba32-1010102.bmp
99e94394bfa9d520a276f0aa6c68a905 *q/rgba32.bmp
2c165dabce8761faf8a3639fd7372124 *q/rgba32abf.bmp
c04f75a033b3572a35d88a9b9907e98c *q/rgba32h56.bmp
7b167c2602cdd20ee2c677d9d9d47ecf *x/ba-bm.bmp
10 changes: 10 additions & 0 deletions html/bmpsuite.html
Expand Up @@ -689,6 +689,16 @@ <h1>BMP Suite Image List</h1>
can&rsquo;t confirm that this file is correct.</td>
</tr>

<tr>
<td class=q>x/ba-bm.bmp</td>
<td>OS/2v2</td>
<td class=b><img src="pal8.png"></td>
<td class=b><img src="../x/ba-bm.bmp"></td>
<td>This image uses the OS/2v2 &ldquo;Bitmap Array&rdquo; (BA) container
format. Although a BA file may contain multiple images, this file has
only one.</td>
</tr>

<tr>
<td class=bad>b/badbitcount.bmp</td>
<td>3</td>
Expand Down
3 changes: 3 additions & 0 deletions readme.txt
Expand Up @@ -43,6 +43,9 @@ Files in the "b" directory I consider to be "bad":
These are clearly invalid or unreasonable. Make sure your program doesn't crash
when reading them.

The "x" directory contains files in formats related to BMP, that you might not
consider to truly be in "BMP format".

The individual BMP files are described in the html/bmpsuite.html file.

The generation utility is written in C, and is contained in the bmpsuite.c
Expand Down

0 comments on commit f6d6f88

Please sign in to comment.