Skip to content

Commit

Permalink
initial release candidate
Browse files Browse the repository at this point in the history
  • Loading branch information
tantanGH committed Mar 25, 2023
1 parent ab7af1a commit 974980e
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 67 deletions.
Binary file modified PNGBM010.ZIP
Binary file not shown.
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,37 @@
# png2bmp
# PNG2BMP.X

PNG to BMP converter for X680x0/Human68k

PNGファイルをBMPファイルに変換します。24bitRGBまたは32bitRGBAのPNGのみサポートしています。

---

### インストール方法

PNGBMxxx.ZIP をダウンロードして展開し、PNG2BMP.X をパスの通ったディレクトリに置きます。

---

### 使用方法

png2bmp [オプション] <PNGファイル名>

-o <出力ファイル名> ... 省略した場合はPNGファイルの拡張子を.bmpに変えたものになります
-s ... 半分のサイズに縮小します
-h ... ヘルプメッセージを表示します

060loadhigh.x を使ったハイメモリ上での実行に対応しています。

---

### Special Thanks

* xdev68k thanks to ファミべのよっしんさん
* HAS060.X on run68mac thanks to YuNKさん / M.Kamadaさん / GOROmanさん
* HLK301.X on run68mac thanks to SALTさん / GOROmanさん

---

### History

* 0.1.0 (2023/03/25) ... 初版
38 changes: 11 additions & 27 deletions src/bmp_encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
//
// init BMP encode handler
//
int32_t bmp_encode_init(BMP_ENCODE_HANDLE* bmp, FILE* fp, int16_t half_size) {
int32_t bmp_encode_init(BMP_ENCODE_HANDLE* bmp, FILE* fp) {

bmp->fp = fp;
bmp->half_size = half_size;

bmp->width = 0;
bmp->height = 0;
Expand All @@ -37,8 +36,8 @@ int32_t bmp_encode_write_header(BMP_ENCODE_HANDLE* bmp, uint32_t width, uint32_t

if (bmp == NULL || bmp->fp == NULL) goto exit;

bmp->width = bmp->half_size ? width/2 : width;
bmp->height = bmp->half_size ? height/2 : height;
bmp->width = width;
bmp->height = height;

bmp->padding_bytes = (4 - ((bmp->width * 3) % 4)) % 4;

Expand Down Expand Up @@ -94,30 +93,15 @@ int32_t bmp_encode_write(BMP_ENCODE_HANDLE* bmp, uint32_t pos_y, uint8_t* bmp_bu

int32_t rc = 0;

if (bmp->half_size) {
fseek(bmp->fp, BMP_HEADER_BYTES + (bmp->width * 3 + bmp->padding_bytes) * (bmp->height - (pos_y + bmp_buffer_lines)), SEEK_SET);
for (int16_t i = bmp_buffer_lines - 1; i >= 0; i--) {
if (i & 0x01) continue;
size_t len = fwrite(bmp_buffer + bmp->width * 3 * i, 1, bmp_buffer_line_bytes, bmp->fp);
if (len != bmp_buffer_line_bytes) {
rc = -1;
break;
}
if (bmp->padding_bytes > 0) {
fwrite(bmp->padding, 1, bmp->padding_bytes, bmp->fp);
}
fseek(bmp->fp, BMP_HEADER_BYTES + (bmp->width * 3 + bmp->padding_bytes) * (bmp->height - (pos_y + bmp_buffer_lines)), SEEK_SET);
for (int16_t i = bmp_buffer_lines - 1; i >= 0; i--) {
size_t len = fwrite(bmp_buffer + bmp->width * 3 * i, 1, bmp_buffer_line_bytes, bmp->fp);
if (len != bmp_buffer_line_bytes) {
rc = -1;
break;
}
} else {
fseek(bmp->fp, BMP_HEADER_BYTES + (bmp->width * 3 + bmp->padding_bytes) * (bmp->height - (pos_y + bmp_buffer_lines)), SEEK_SET);
for (int16_t i = bmp_buffer_lines - 1; i >= 0; i--) {
size_t len = fwrite(bmp_buffer + bmp->width * 3 * i, 1, bmp_buffer_line_bytes, bmp->fp);
if (len != bmp_buffer_line_bytes) {
rc = -1;
break;
}
if (bmp->padding_bytes > 0) {
fwrite(bmp->padding, 1, bmp->padding_bytes, bmp->fp);
}
if (bmp->padding_bytes > 0) {
fwrite(bmp->padding, 1, bmp->padding_bytes, bmp->fp);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/bmp_encode.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
#define BMP_HEADER_BYTES (54)

typedef struct {
int16_t half_size;
uint32_t width;
uint32_t height;
size_t padding_bytes;
uint8_t padding[4];
FILE* fp;
} BMP_ENCODE_HANDLE;

int32_t bmp_encode_init(BMP_ENCODE_HANDLE* bmp, FILE* fp, int16_t half_size);
int32_t bmp_encode_init(BMP_ENCODE_HANDLE* bmp, FILE* fp);
void bmp_encode_close(BMP_ENCODE_HANDLE* bmp);
int32_t bmp_encode_write_header(BMP_ENCODE_HANDLE* bmp, uint32_t width, uint32_t height);
int32_t bmp_encode_write(BMP_ENCODE_HANDLE* bmp, uint32_t pos_y, uint8_t* bmp_buffer, size_t bmp_buffer_line_bytes, size_t bmp_buffer_lines);
Expand Down
4 changes: 2 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ int32_t main(int32_t argc, uint8_t* argv[]) {
fo = fopen(out_name, "rb+");

BMP_ENCODE_HANDLE bmp_encode = { 0 };
bmp_encode_init(&bmp_encode, fo, half_size);
bmp_encode_init(&bmp_encode, fo);

PNG_DECODE_HANDLE png_decode = { 0 };
png_decode_init(&png_decode);
png_decode_init(&png_decode, half_size);
png_decode_set_bmp_encoder(&png_decode, &bmp_encode);

printf("converting...");
Expand Down
54 changes: 24 additions & 30 deletions src/png_decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@
//
// initialize PNG decode handle
//
void png_decode_init(PNG_DECODE_HANDLE* png) {
void png_decode_init(PNG_DECODE_HANDLE* png, int16_t half_size) {

png->input_buffer_size = 65536 * 4;
png->output_buffer_size = 131072 * 4;

png->use_high_memory = 0;
png->half_size = half_size;
png->line_data = NULL;

// actual width and height
png->actual_width = 512;
png->actual_height = 512;
png->pitch = 512;
// png->actual_width = 512;
// png->actual_height = 512;
// png->pitch = 512;

// for PNG decode
png->current_x = -1;
Expand Down Expand Up @@ -132,7 +133,11 @@ void png_decode_set_header(PNG_DECODE_HANDLE* png, PNG_HEADER* png_header) {

// BMP header
if (png->bmp != NULL) {
bmp_encode_write_header(png->bmp, png_header->width, png_header->height);
if (png->half_size) {
bmp_encode_write_header(png->bmp, png_header->width/2, png_header->height/2);
} else {
bmp_encode_write_header(png->bmp, png_header->width, png_header->height);
}
}
}

Expand Down Expand Up @@ -160,29 +165,15 @@ static void output_pixel(uint8_t* buffer, size_t buffer_size, int32_t* buffer_co
int32_t consumed_size = 0;
int32_t bytes_per_pixel = (png->png_header.color_type == PNG_COLOR_TYPE_RGBA) ? 4 : 3;
uint8_t* buffer_end = buffer + buffer_size;

// cropping check
int32_t cy = png->current_y;
// if (cy < 0 || cy >= png->actual_height) {
// // no need to output any pixels
// *buffer_consumed = buffer_size; // just consumed all
// return;
// }

// entry point
// volatile uint16_t* gvram_current = GVRAM + png->pitch * cy +
// (png->current_x >= 0 ? png->current_x : 0);
uint8_t* bitmap_data = png->line_data + (png->current_x >= 0 ? png->current_x * 3 : 0);
uint8_t* bitmap_data = png->line_data + (png->current_x < 0 ? 0 : png->half_size ? png->current_x/2 * 3 : png->current_x * 3);

while (buffer < buffer_end) {

if (png->current_x == -1) { // first byte of each scan line

// get filter mode
png->current_filter = *buffer++;
#ifdef DEBUG
//printf("g_current_filter=%d,g_current_y=%d\n",g_current_filter,g_current_y);
#endif

// next pixel
png->current_x++;

Expand Down Expand Up @@ -265,12 +256,11 @@ static void output_pixel(uint8_t* buffer, size_t buffer_size, int32_t* buffer_co
}

// write pixel data in BGR format
*bitmap_data++ = bf;
*bitmap_data++ = gf;
*bitmap_data++ = rf;
// if (png->current_x < png->actual_width) {
// *gvram_current++ = png->rgb555_r[rf] | png->rgb555_g[gf] | png->rgb555_b[bf] | 1;
// }
if (!png->half_size || (png->current_x & 0x01) == 0) {
*bitmap_data++ = bf;
*bitmap_data++ = gf;
*bitmap_data++ = rf;
}

// cache r,g,b for downstream filtering
if (png->current_x > 0) {
Expand All @@ -292,11 +282,15 @@ static void output_pixel(uint8_t* buffer, size_t buffer_size, int32_t* buffer_co

// next scan line
if (png->current_x >= png->png_header.width) {
bmp_encode_write(png->bmp, png->current_y, png->line_data, png->png_header.width * 3, 1);
if (png->half_size) {
if ((png->current_y & 0x01) == 0) {
bmp_encode_write(png->bmp, png->current_y/2, png->line_data, png->png_header.width/2 * 3, 1);
}
} else {
bmp_encode_write(png->bmp, png->current_y, png->line_data, png->png_header.width * 3, 1);
}
png->current_x = -1;
png->current_y++;
// if (png->current_y >= png->actual_height) break; // Y cropping
// gvram_current = GVRAM + png->pitch * png->current_y;
bitmap_data = png->line_data;
}

Expand Down
11 changes: 6 additions & 5 deletions src/png_decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ typedef struct {
// input parameters
int32_t input_buffer_size;
int32_t output_buffer_size;
int32_t use_high_memory;
int16_t use_high_memory;
int16_t half_size;

// BMP encoder
BMP_ENCODE_HANDLE* bmp;
Expand All @@ -37,9 +38,9 @@ typedef struct {
uint8_t* line_data;

// actual screen size
int32_t actual_width;
int32_t actual_height;
int32_t pitch;
// int32_t actual_width;
// int32_t actual_height;
// int32_t pitch;

// current decode state
int32_t current_x;
Expand All @@ -62,7 +63,7 @@ typedef struct {
} PNG_DECODE_HANDLE;

// prototype declarations
void png_decode_init(PNG_DECODE_HANDLE* png);
void png_decode_init(PNG_DECODE_HANDLE* png, int16_t half_size);
void png_decode_set_bmp_encoder(PNG_DECODE_HANDLE* png, BMP_ENCODE_HANDLE* bmp);
void png_decode_set_header(PNG_DECODE_HANDLE* png, PNG_HEADER* png_header);
void png_decode_close(PNG_DECODE_HANDLE* png);
Expand Down

0 comments on commit 974980e

Please sign in to comment.