summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools
diff options
context:
space:
mode:
author Oliver Stöneberg <firewave@users.noreply.github.com>2013-06-20 10:08:31 +0000
committer Oliver Stöneberg <firewave@users.noreply.github.com>2013-06-20 10:08:31 +0000
commit0c2201318cd00f5389bec1ae056af1b9657f2004 (patch)
tree300e431bc2c52fd2bb5a7a5b9f597332911e2ca7 /src/tools
parent619b0109b1cbcc6a7f074b6c577dd7c2cf5c505b (diff)
added pngcmp to tools (nw)
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/pngcmp.c226
-rw-r--r--src/tools/tools.mak15
2 files changed, 241 insertions, 0 deletions
diff --git a/src/tools/pngcmp.c b/src/tools/pngcmp.c
new file mode 100644
index 00000000000..7b1a18d3cb1
--- /dev/null
+++ b/src/tools/pngcmp.c
@@ -0,0 +1,226 @@
+/***************************************************************************
+
+ pngcmp.c
+
+ PNG comparison (based on regrep.c)
+
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "osdcore.h"
+#include "png.h"
+
+#include <new>
+
+/***************************************************************************
+ CONSTANTS & DEFINES
+***************************************************************************/
+
+#define BITMAP_SPACE 4
+
+/***************************************************************************
+ PROTOTYPES
+***************************************************************************/
+
+static int generate_png_diff(const astring& imgfile1, const astring& imgfile2, const astring& outfilename);
+
+/***************************************************************************
+ MAIN
+***************************************************************************/
+
+/*-------------------------------------------------
+ main - main entry point
+-------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+ /* first argument is the directory */
+ if (argc < 4)
+ {
+ fprintf(stderr, "Usage:\npngcmp <image1> <image2> <outfile>\n");
+ return 10;
+ }
+ astring imgfilename1(argv[1]);
+ astring imgfilename2(argv[2]);
+ astring outfilename(argv[3]);
+
+ try {
+ return generate_png_diff(imgfilename1, imgfilename2, outfilename);
+ }
+ catch(...)
+ {
+ printf("Exception occured");
+ return 1000;
+ }
+}
+
+/*-------------------------------------------------
+ generate_png_diff - create a new PNG file
+ that shows multiple differing PNGs side by
+ side with a third set of differences
+-------------------------------------------------*/
+
+static int generate_png_diff(const astring& imgfile1, const astring& imgfile2, const astring& outfilename)
+{
+ bitmap_argb32 bitmap1;
+ bitmap_argb32 bitmap2;
+ bitmap_argb32 finalbitmap;
+ int width, height, maxwidth;
+ core_file *file = NULL;
+ file_error filerr;
+ png_error pngerr;
+ int error = 100;
+ bool bitmaps_differ;
+ int x, y;
+
+ /* open the source image */
+ filerr = core_fopen(imgfile1, OPEN_FLAG_READ, &file);
+ if (filerr != FILERR_NONE)
+ {
+ printf("Could not open %s (%d)\n", imgfile1.cstr(), filerr);
+ goto error;
+ }
+
+ /* load the source image */
+ pngerr = png_read_bitmap(file, bitmap1);
+ core_fclose(file);
+ if (pngerr != PNGERR_NONE)
+ {
+ printf("Could not read %s (%d)\n", imgfile1.cstr(), pngerr);
+ goto error;
+ }
+
+ /* open the source image */
+ filerr = core_fopen(imgfile2, OPEN_FLAG_READ, &file);
+ if (filerr != FILERR_NONE)
+ {
+ printf("Could not open %s (%d)\n", imgfile2.cstr(), filerr);
+ goto error;
+ }
+
+ /* load the source image */
+ pngerr = png_read_bitmap(file, bitmap2);
+ core_fclose(file);
+ if (pngerr != PNGERR_NONE)
+ {
+ printf("Could not read %s (%d)\n", imgfile2.cstr(), pngerr);
+ goto error;
+ }
+
+ /* if the sizes are different, we differ; otherwise start off assuming we are the same */
+ bitmaps_differ = (bitmap2.width() != bitmap1.width() || bitmap2.height() != bitmap1.height());
+
+ /* compare scanline by scanline */
+ for (y = 0; y < bitmap2.height() && !bitmaps_differ; y++)
+ {
+ UINT32 *base = &bitmap1.pix32(y);
+ UINT32 *curr = &bitmap2.pix32(y);
+
+ /* scan the scanline */
+ for (x = 0; x < bitmap2.width(); x++)
+ if (*base++ != *curr++)
+ break;
+ bitmaps_differ = (x != bitmap2.width());
+ }
+
+ if (bitmaps_differ)
+ {
+ /* determine the size of the final bitmap */
+ height = width = 0;
+ {
+ /* determine the maximal width */
+ maxwidth = MAX(bitmap1.width(), bitmap2.width());
+ width = bitmap1.width() + BITMAP_SPACE + maxwidth + BITMAP_SPACE + maxwidth;
+
+ /* add to the height */
+ height += MAX(bitmap1.height(), bitmap2.height());
+ }
+
+ /* allocate the final bitmap */
+ finalbitmap.allocate(width, height);
+
+ /* now copy and compare each set of bitmaps */
+ int curheight = MAX(bitmap1.height(), bitmap2.height());
+ /* iterate over rows in these bitmaps */
+ for (y = 0; y < curheight; y++)
+ {
+ UINT32 *src1 = (y < bitmap1.height()) ? &bitmap1.pix32(y) : NULL;
+ UINT32 *src2 = (y < bitmap2.height()) ? &bitmap2.pix32(y) : NULL;
+ UINT32 *dst1 = &finalbitmap.pix32(y);
+ UINT32 *dst2 = &finalbitmap.pix32(y, bitmap1.width() + BITMAP_SPACE);
+ UINT32 *dstdiff = &finalbitmap.pix32(y, bitmap1.width() + BITMAP_SPACE + maxwidth + BITMAP_SPACE);
+
+ /* now iterate over columns */
+ for (x = 0; x < maxwidth; x++)
+ {
+ int pix1 = -1, pix2 = -2;
+
+ if (src1 != NULL && x < bitmap1.width())
+ pix1 = dst1[x] = src1[x];
+ if (src2 != NULL && x < bitmap2.width())
+ pix2 = dst2[x] = src2[x];
+ dstdiff[x] = (pix1 != pix2) ? 0xffffffff : 0xff000000;
+ }
+ }
+
+ /* write the final PNG */
+ filerr = core_fopen(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, &file);
+ if (filerr != FILERR_NONE)
+ {
+ printf("Could not open %s (%d)\n", outfilename.cstr(), filerr);
+ goto error;
+ }
+ pngerr = png_write_bitmap(file, NULL, finalbitmap, 0, NULL);
+ core_fclose(file);
+ if (pngerr != PNGERR_NONE)
+ {
+ printf("Could not write %s (%d)\n", outfilename.cstr(), pngerr);
+ goto error;
+ }
+ }
+
+ /* if we get here, we are error free */
+ if (bitmaps_differ)
+ error = 1;
+ else
+ error = 0;
+
+error:
+ if (error == -1)
+ osd_rmfile(outfilename);
+ return error;
+}
diff --git a/src/tools/tools.mak b/src/tools/tools.mak
index 105fc33678e..038250b6964 100644
--- a/src/tools/tools.mak
+++ b/src/tools/tools.mak
@@ -61,6 +61,7 @@ TOOLS += \
srcclean$(EXE) \
src2html$(EXE) \
split$(EXE) \
+ pngcmp$(EXE) \
@@ -192,3 +193,17 @@ SPLITOBJS = \
split$(EXE): $(SPLITOBJS) $(LIBUTIL) $(LIBOCORE) $(ZLIB) $(EXPAT)
@echo Linking $@...
$(LD) $(LDFLAGS) $^ $(LIBS) -o $@
+
+
+
+#-------------------------------------------------
+# pngcmp
+#-------------------------------------------------
+
+PNGCMPOBJS = \
+ $(TOOLSOBJ)/pngcmp.o \
+
+pngcmp$(EXE): $(PNGCMPOBJS) $(LIBUTIL) $(LIBOCORE) $(ZLIB)
+ @echo Linking $@...
+ $(LD) $(LDFLAGS) $^ $(LIBS) -o $@
+