From: b Date: Wed, 30 Nov 2022 18:28:28 +0000 (+0000) Subject: npb ready but debug needed X-Git-Url: http://bicyclesonthemoon.info/git-projects/?a=commitdiff_plain;h=055c0446962bdb3f87d393af5dcab6b2650f9e6c;p=ott%2Fenhance npb ready but debug needed --- diff --git a/core.c b/core.c index 4283561..5e80a17 100644 --- a/core.c +++ b/core.c @@ -514,6 +514,21 @@ int load_picture (uint_fast16_t id, char *path, struct IL_full_info *info, FLAG_ return convert_picture(id, info, flags); } +int load_picture_mem (uint_fast16_t id, const void *address, ILuint size, struct IL_full_info *info, FLAG_TYPE *flags) +{ + if (id >= n_pictures) + return EINVAL; + + // if(!(picture[id].open)) + create_picture(id); + + ilBindImage(picture[id].handle); + if (!ilLoadL(IL_TYPE_UNKNOWN, address, size)) + return EIO; + + return convert_picture(id, info, flags); +} + int build_picture (uint_fast16_t id, ILint width, ILint height, ILint frames, struct IL_full_info *info, FLAG_TYPE *flags) { struct IL_full_info reference_info; @@ -702,6 +717,24 @@ int perform_action_1picture ( ); } +int perform_action_1picture_1pixel ( + uint_fast16_t id, + ILint x, ILint y, ILint f, + ACTION_F *function, + FLAG_TYPE flags, + void *data +) +{ + return perform_action_1picture ( + id, + x, y, f, + 1, 1, 1, + function, + flags | IN_WINDOW, + data + ); +} + int perform_action ( uint_fast16_t n, uint_fast16_t *id, @@ -1470,7 +1503,7 @@ int copy_pixels (ILuint n, struct PixelInfo *p, void *data) { if (!(p[1].flags & EFF_GRAY)) return EINVAL; - p[1].value = p[0].value + p[1].value = p[0].value; } else { @@ -1513,7 +1546,7 @@ int fill_color (ILuint n, struct PixelInfo *p, void *data) } -ILuint copy_1p_alpha (ILint64 src, ILint64 dst, ILint64 alpha, iILint64 max) +ILuint copy_1p_alpha (ILint64 src, ILint64 dst, ILint64 alpha, ILint64 max) { ILint64 v = (src * alpha + dst * (max - alpha)) / max; return (ILuint)v; diff --git a/core.h b/core.h index 15af406..2c9f2fe 100644 --- a/core.h +++ b/core.h @@ -1,7 +1,7 @@ /* core.h The tool with multiple enhancements and manipulations of pictures -29.11.2022 +30.11.2022 Copyright (C) 2022 Balthasar Szczepański @@ -179,7 +179,7 @@ struct ColorInfo ILuint value; ILuint alpha; ILuint index; -} +}; typedef int (ACTION_F)(ILuint n, struct PixelInfo *info, void *data); @@ -201,6 +201,7 @@ int reserve_pictures (uint_fast16_t n); void get_flags (struct IL_full_info *info, FLAG_TYPE *flags); int convert_picture (uint_fast16_t id, struct IL_full_info *info, FLAG_TYPE *flags); int load_picture (uint_fast16_t id, char *path, struct IL_full_info *info, FLAG_TYPE *flags); +int load_picture_mem (uint_fast16_t id, const void *address, ILuint size, struct IL_full_info *info, FLAG_TYPE *flags); int save_picture (uint_fast16_t id, char *path, FLAG_TYPE flags); int build_picture (uint_fast16_t id, ILint width, ILint height, ILint frames, struct IL_full_info *info, FLAG_TYPE *flags); int build_picture_from_info (uint_fast16_t id, struct IL_full_info *reference_info, struct IL_full_info *info, FLAG_TYPE *flags); @@ -209,6 +210,14 @@ int get_info (uint_fast16_t id, struct IL_full_info *info, ILint frame); ILuint upscale_value (ILubyte x, ILint bytes); ILubyte downscale_value (ILuint x, ILint bytes); +int perform_action_1picture_1pixel ( + uint_fast16_t id, + ILint x, ILint y, ILint f, + ACTION_F *function, + FLAG_TYPE flags, + void *data +); + int perform_action_1picture ( uint_fast16_t id, ILint x0, ILint y0, ILint f0, @@ -238,5 +247,5 @@ int perform_action_palette_mix ( int copy_pixels (ILuint n, struct PixelInfo *p, void *data); -ILuint copy_1p_alpha (ILint64 src, ILint64 dst, ILint64 alpha, iILint64 max); +ILuint copy_1p_alpha (ILint64 src, ILint64 dst, ILint64 alpha, ILint64 max); int fill_color (ILuint n, struct PixelInfo *p, void *data); \ No newline at end of file diff --git a/enhance.c b/enhance.c index 7fc3a75..42ac72d 100644 --- a/enhance.c +++ b/enhance.c @@ -1,7 +1,7 @@ /* enhance.c The tool with multiple enhancements and manipulations of pictures -29.11.2022 +30.11.2022 Copyright (C) 2022 Balthasar Szczepański @@ -60,6 +60,8 @@ int main (int argc, char **argv) f = &subtool_reveal; else if (strcmp(argv[1], "diff")==0) f = &subtool_diff; + else if (strcmp(argv[1], "npb")==0) + f = &subtool_npb; else finish(EINVAL, "Unknown mode.\n"); diff --git a/f2h.c b/f2h.c index 32fb519..fefc018 100644 --- a/f2h.c +++ b/f2h.c @@ -1,7 +1,7 @@ /* f2h.c make file into h -29.11.2022 +30.11.2022 Copyright (C) 2022 Balthasar Szczepański @@ -90,7 +90,7 @@ int main (int argc, char **argv) (i==0) ? "\n\t" : " ", x ); - ++size + ++size; } fputs ("\n};\n", outfile); fprintf( diff --git a/npb.c b/npb.c index 1c03b99..422ebd9 100644 --- a/npb.c +++ b/npb.c @@ -1,7 +1,7 @@ /* npb.c Take a picture and add a newpixbot to it! -29.11.2022 +30.11.2022 Copyright (C) 2013 - 2015, 2022 Balthasar Szczepański @@ -28,6 +28,7 @@ on Pentium III libdevil must be recompiled with #include #include +#include #include "core.h" #include "npb.h" @@ -38,15 +39,30 @@ on Pentium III libdevil must be recompiled with #include "npb_ong1.h" #include "npb_403.h" -#define NPB0_L 21 -#define NPB0_R 116 -#define NPB0_T 122 -#define NPB0_B 189 +#define NPB0_L 21 +#define NPB0_R 116 +#define NPB0_T 122 +#define NPB0_B 189 -#define NPB1_L 22 -#define NPB1_R 154 -#define NPB1_T 69 -#define NPB1_B 162 +#define NPB1_L 22 +#define NPB1_R 154 +#define NPB1_T 69 +#define NPB1_B 162 + +#define NPB2_L 36 +#define NPB2_R 199 +#define NPB2_T 171 +#define NPB2_B 171 + +#define NPB_ONG1_L -74 +#define NPB_ONG1_R 102 +#define NPB_ONG1_T 66 +#define NPB_ONG1_B 69 + +#define NPB_403_L 224 +#define NPB_403_R 265 +#define NPB_403_T 261 +#define NPB_403_B 261 char NPB_MISSING_ARGS[] = "Missing parameters.\nnpb [-o -4 -r -b -c] inPix outPix\n"; @@ -58,29 +74,38 @@ int subtool_npb (int argc, char **argv, int argi, char **err) uint_fast8_t corners = 0; uint_fast8_t fullsize = 0; uint_fast8_t fill_white = 0; + uint_fast8_t npb_after = 0; uint_fast8_t expand_left = 0; uint_fast8_t expand_right = 0; uint_fast8_t expand_up = 0; uint_fast8_t expand_down = 0; uint_fast8_t border_outside = 0; + uint_fast8_t fixed_frame = 0; ILuint cut_border = 0; ILuint new_border = 2; ILuint max = 0xFF; //upscale_value(0xFF, info[0].image_bpc); // bpc=1 - ILuint effective_width, effective_height; + ILint width_content, height_content, x0_content_own, y0_content_own, x0_content_global, y0_content_global; + ILint width_border, height_border, x0_border, y0_border; + ILint width_npb, height_npb, x0_npb, y0_npb; + ILint width_total, height_total; const uint8_t *npb_pix; uint_fast32_t npb_size; - ILuint x_l, x_r, y_t, y_b; + ILint space_l, space_r, space_t, space_b; struct ColorInfo color; - struct IL_full_info info[3]; - FLAG_TYPE flags [3] = { - CANNOT_BE_GRAY | CANNOT_BE_INDEXED | NOT_WRITABLE, - CANNOT_BE_GRAY | CANNOT_BE_INDEXED | NOT_WRITABLE | MUST_HAVE_ALPHA, - CANNOT_BE_GRAY | CANNOT_BE_INDEXED | NOT_READABLE | MUST_HAVE_ALPHA, - } - ILuint x0[3]; - ILuint y0[3]; + struct IL_full_info info_content; + struct IL_full_info info_npb; + struct IL_full_info info_total; + FLAG_TYPE flags_content = CANNOT_BE_GRAY | CANNOT_BE_INDEXED | NOT_WRITABLE; + FLAG_TYPE flags_npb = CANNOT_BE_GRAY | CANNOT_BE_INDEXED | NOT_WRITABLE | MUST_HAVE_ALPHA; + FLAG_TYPE flags_total = CANNOT_BE_GRAY | CANNOT_BE_INDEXED | MUST_HAVE_ALPHA; + + uint_fast16_t id[2]; + FLAG_TYPE flags[2]; + ILint x0[2]; + ILint y0[2]; + ILint f0[2] = {0, 0}; struct option long_options[] = { {"ong1", no_argument, NULL, 'o'}, @@ -96,6 +121,8 @@ int subtool_npb (int argc, char **argv, int argi, char **err) int opt; int r; + /* we get options first */ + optind = argi; while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { @@ -108,10 +135,10 @@ int subtool_npb (int argc, char **argv, int argi, char **err) t403 = 1; break; case 'r': - sscanf(optarg, "%lu, &cut_border); + sscanf(optarg, "%u", &cut_border); break; case 'b': - sscanf(optarg, "%lu, &new_border); + sscanf(optarg, "%u", &new_border); fullsize = 1; break; case 'c': @@ -129,56 +156,580 @@ int subtool_npb (int argc, char **argv, int argi, char **err) return EINVAL; } - r = reserve_pictures(1); + r = reserve_pictures(3); if (r) { *err = CREATE_FAILED; return r; } - r = load_picture(0, argv[optind], &(info[0]), &(flags[0]); + /* load content to insert to npb */ + + r = load_picture(0, argv[optind], &(info_content), &(flags_content)); if (r) { *err = LOAD_FAILED; return r; } - effective_width = (info[0].image_width > (2*cut_border)) ? (info[0].image_width - (2*cut_border)) : 0; - effective_height = (info[0].image_height > (2*cut_border)) ? (info[0].image_height - (2*cut_border)) : 0; + /* determine actually used rectangle without border */ + + width_content = (info_content.image_width > (2*cut_border)) ? (info_content.image_width - (2*cut_border)) : 0; + height_content = (info_content.image_height > (2*cut_border)) ? (info_content.image_height - (2*cut_border)) : 0; + x0_content_own = cut_border; + y0_content_own = cut_border; + + /* select npb mode */ if (t403) { npb_pix = npb_403; npb_size = npb_403_size; + space_l = NPB_403_L; + space_r = NPB_403_R; + space_t = NPB_403_T; + space_b = NPB_403_B; + expand_right = 1; + expand_up = 1; + border_outside = 1; + fill_white = 1; } else if (ong1) { npb_pix = npb_ong1; npb_size = npb_ong1_size; + space_l = NPB_ONG1_L; + space_r = NPB_ONG1_R; + space_t = NPB_ONG1_T; + space_b = NPB_ONG1_B; + expand_left = 1; + expand_up = 1; + npb_after = 1; } - else if ((effective_width <= NPB0_X_MAX) && (effective_height <= NPB0_Y_MAX) && (!fullsize)) + else if ((width_content <= (NPB0_R - NPB0_L + 1)) && (height_content <= (NPB0_B - NPB0_T + 1)) && (!fullsize)) { npb_pix = npb0; npb_size = npb0_size; + space_l = NPB0_L; + space_r = NPB0_R; + space_t = NPB0_T; + space_b = NPB0_B; fill_white = 1; new_border = 0; + npb_after = 1; + fixed_frame = 1; } - else if ((effective_width <= NPB1_X_MAX) && (effective_height <= NPB1_Y_MAX) && (!fullsize)) + else if ((width_content <= (NPB1_R - NPB1_L + 1)) && (height_content <= (NPB1_B - NPB1_T + 1)) && (!fullsize)) { npb_pix = npb1; npb_size = npb1_size; + space_l = NPB1_L; + space_r = NPB1_R; + space_t = NPB1_T; + space_b = NPB1_B; fill_white = 1; new_border = 0; + npb_after = 1; + fixed_frame = 1; } else { npb_pix = npb2; npb_size = npb2_size; + space_l = NPB2_L; + space_r = NPB2_R; + space_t = NPB2_T; + space_b = NPB2_B; + expand_left = 1; + expand_up = 1; + npb_after = 1; } - - + + /* load selected npb */ + + r = load_picture_mem(1, npb_pix, npb_size, &(info_npb), &(flags_npb)); + if (r) + { + *err = LOAD_FAILED; + return r; + } + + /* determine rectangle of content with new border */ + + if (border_outside) + { + width_border = width_content; + height_border = height_content; + } + else + { + width_border = width_content + new_border * 2; + height_border = height_content + new_border * 2; + } + + /* npb rectangle too */ + + width_npb = info_npb.image_width; + height_npb = info_npb.image_width; + x0_npb = 0; + y0_npb = 0; + + /* initial total size, to update later */ + + width_total = width_npb; + height_total = height_npb; + + /* determine content border placement in full picture */ + + if (expand_right && (width_border <= (space_r - space_l +1))) + x0_border = space_l; + else if (expand_left && (width_border <= (space_r - space_l +1))) + x0_border = space_r - width_border + 1; + else + x0_border = (space_l + space_r + 1 - width_border) / 2; + + if (expand_down && (height_border <= (space_b - space_t +1))) + y0_border = space_t; + else if (expand_up && (height_border <= (space_b - space_t +1))) + y0_border = space_b - height_border + 1; + else + y0_border = (space_t + space_b + 1 - height_border) / 2; + + /* determine content placement in border in full picture */ + + if (border_outside) + { + x0_content_global = x0_border; + y0_content_global = y0_border; + } + else + { + x0_content_global = x0_border + new_border; + y0_content_global = y0_border + new_border; + } + + /* adjust full picture size & offsets if content doesn't fit */ + + if (width_total < (x0_border + width_border)) + width_total = x0_border + width_border; + if (height_total < (y0_border + height_border)) + height_total = y0_border + height_border; + if (x0_border < 0) + { + width_total -= x0_border; + x0_npb -= x0_border; + x0_content_global -= x0_border; + x0_border = 0; + } + if (y0_border < 0) + { + height_total -= y0_border; + y0_npb -= y0_border; + y0_content_global -= y0_border; + y0_border = 0; + } + + /* adjust for external border */ + + if (border_outside) + { + width_total += 2 * new_border; + height_total += 2 * new_border; + x0_border += new_border; + y0_border += new_border; + x0_content_global += new_border; + y0_content_global += new_border; + x0_npb += new_border; + y0_npb += new_border; + } + + /* ok setup done, now perform actions */ + + /* 1: create target picture */ + + r = build_picture(2, width_total, height_total, 1, &info_total, &flags_total); + if (r!=0) + { + *err = LOAD_FAILED; + return r; + } + + /* 2: init background */ + + color.red = max; + color.green = max; + color.blue = max; + color.alpha = (border_outside && fill_white) ? max : 0; + + r = perform_action_1picture( + 2, //id + border_outside ? new_border : 0, //x0 + border_outside ? new_border : 0, //y0 + 0, //f0 + border_outside ? (width_total - 2 * new_border) : width_total, //width + border_outside ? (height_total - 2 * new_border) : height_total, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + /* 3: draw border outside */ + + if (border_outside && (new_border >0)) + { + color.red = 0; + color.green = 0; + color.blue = 0; + color.alpha = max; + + r = perform_action_1picture( //top + 2, //id + 0, //x0 + 0, //y0 + 0, //f0 + width_total, //width + new_border, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture( //bottom + 2, //id + 0, //x0 + height_total - new_border, //y0 + 0, //f0 + width_total, //width + new_border, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture( //left + 2, //id + 0, //x0 + new_border, //y0 + 0, //f0 + new_border, //width + height_total - 2*new_border, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture( //right + 2, //id + width_total - new_border, //x0 + new_border, //y0 + 0, //f0 + new_border, //width + height_total - 2*new_border, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + if (corners) + { + r = perform_action_1picture_1pixel( //top-left + 2, //id + new_border, //x0 + new_border, //y0 + 0, //f0 + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture_1pixel( //top-right + 2, //id + width_total - new_border - 1, //x0 + new_border, //y0 + 0, //f0 + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture_1pixel( //bottom-right + 2, //id + width_total - new_border - 1, //x0 + height_total - new_border - 1, //y0 + 0, //f0 + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture_1pixel( //bottom-left + 2, //id + new_border, //x0 + height_total - new_border - 1, //y0 + 0, //f0 + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + } + } + + /* 4: insert npb before */ + + if (!npb_after) + { + id[0] = 1; //npb + id[1] = 2; //total + x0[0] = 0; + x0[1] = x0_npb; + y0[0] = 0; + y0[1] = y0_npb; + flags[0] = flags_npb | IN_WINDOW; + flags[1] = flags_total | IN_WINDOW; + + r = perform_action( + 2, //n + id, + x0, y0, f0, + width_npb, height_npb, 1, + ©_pixels, + flags, + &max //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + } + + /* 5: fill_background */ + + if ((!border_outside) && fill_white) + { + color.red = max; + color.green = max; + color.blue = max; + color.alpha = max; + + r = perform_action_1picture( + 2, //id + fixed_frame ? space_l : x0_content_global, //x0 + fixed_frame ? space_t : y0_content_global, //y0 + 0, //f0 + fixed_frame ? (space_r - space_l + 1) : width_content, //width + fixed_frame ? (space_b - space_t + 1) : height_content, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + } + + /* 6: insert content */ + + id[0] = 0; //content + id[1] = 2; //total + x0[0] = x0_content_own; + x0[1] = x0_content_global; + y0[0] = y0_content_own; + y0[1] = y0_content_global; + flags[0] = flags_content | IN_WINDOW; + flags[1] = flags_total | IN_WINDOW; + + r = perform_action( + 2, //n + id, + x0, y0, f0, + width_content, height_content, 1, + ©_pixels, + flags, + &max //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + /* 7: draw border */ + + if ((!border_outside) && (new_border >0)) + { + color.red = 0; + color.green = 0; + color.blue = 0; + color.alpha = max; + + r = perform_action_1picture( //top + 2, //id + corners ? (x0_border + 1) : x0_border, //x0 + y0_border, //y0 + 0, //f0 + corners ? (width_border - 2) : width_border, //width + new_border, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture( //bottom + 2, //id + corners ? (x0_border + 1) : x0_border, //x0 + y0_border + height_border - new_border, //y0 + 0, //f0 + corners ? (width_border - 2) : width_border, //width + new_border, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture( //left + 2, //id + x0_border, //x0 + corners ? (y0_border + 1) : y0_content_global , //y0 + 0, //f0 + new_border, //width + corners ? (height_border - 2) : height_content, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + + r = perform_action_1picture( //right + 2, //id + x0_border + width_border - new_border, //x0 + corners ? (y0_border + 1) : y0_content_global , //y0 + 0, //f0 + new_border, //width + corners ? (height_border - 2) : height_content, //height + 1, //frames + &fill_color, //function + flags_total | IN_WINDOW | NOT_READABLE, //flags + &color //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + } + + /* 8: insert npb after */ + + if (npb_after) + { + id[0] = 1; //npb + id[1] = 2; //total + x0[0] = 0; + x0[1] = x0_npb; + y0[0] = 0; + y0[1] = y0_npb; + flags[0] = flags_npb | IN_WINDOW; + flags[1] = flags_total | IN_WINDOW; + + r = perform_action( + 2, //n + id, + x0, y0, f0, + width_npb, height_npb, 1, + ©_pixels, + flags, + &max //data + ); + if (r!=0) + { + *err = CONVERT_FAILED; + return r; + } + } + + /* 9: ok, done, now save */ + + r = save_picture(2, argv[optind+1], flags_total); + if (r!=0) + { + *err = SAVE_FAILED; + return r; + } + + return 0; } - +/* #define INPIX_MUSTARD 1 #define OUTPIX_MUSTARD 2 #define NPBPIX_MUSTARD 3 diff --git a/testimg/133x94.png b/testimg/133x94.png new file mode 100644 index 0000000..32985cf Binary files /dev/null and b/testimg/133x94.png differ diff --git a/testimg/133x95.png b/testimg/133x95.png new file mode 100644 index 0000000..3bc655c Binary files /dev/null and b/testimg/133x95.png differ diff --git a/testimg/134x94.png b/testimg/134x94.png new file mode 100644 index 0000000..1d59a4a Binary files /dev/null and b/testimg/134x94.png differ diff --git a/testimg/96x68.png b/testimg/96x68.png new file mode 100644 index 0000000..72562bd Binary files /dev/null and b/testimg/96x68.png differ diff --git a/testimg/96x69.png b/testimg/96x69.png new file mode 100644 index 0000000..3851ca8 Binary files /dev/null and b/testimg/96x69.png differ diff --git a/testimg/97x68.png b/testimg/97x68.png new file mode 100644 index 0000000..1736103 Binary files /dev/null and b/testimg/97x68.png differ