puppylinux-woof-CE / woof-CE

woof - the Puppy builder
GNU General Public License v2.0
395 stars 285 forks source link

Improve pngoverlay #1470

Closed 01micko closed 5 years ago

01micko commented 5 years ago

I knocked up a quick respin of pngoverlay if anyone is interested. Save the code to pngoverlay-cairo.c

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 * (c)2019 Michael Amadio. Gold Coast QLD, Australia 01micko@gmail.com
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>

#include <cairo.h>

#define PROG "pngoverlay-cairo"
#define THIS_VERSION "0.1"
#define D 48

void usage(){
    printf("%s-%s\n\n", PROG , THIS_VERSION);
    printf("\tGenerate a PNG file overlayed from a source and overlay\nA 48x48 PNG output icon is generated\n\n");
    printf("Usage :\n");
    printf("%s [source path] [overlay path] [output path]\n", PROG);
    printf("\tvalid PNG paths are required\n");
    exit (EXIT_SUCCESS);
}

struct { 
    /* allows a png icon */
    cairo_surface_t *overlay_image;
    /* allows a background - png only */
    cairo_surface_t *background_image;
}glob;

static const char *get_user_out_file(char *destination){
    static char out_file[PATH_MAX];
    if (destination != NULL) {
        snprintf(out_file, sizeof(out_file), "%s", destination);
    } else {
        fprintf(stderr, "Failed to recognise directory\n");
        exit (EXIT_FAILURE);
    }
    return out_file;
}

static void paint_img (char *sicon,
                        char *oicon,
                        char *dest) {

    /* input icon */
    if (sicon != NULL) {
        if (access(sicon, R_OK) == -1) {
            fprintf(stderr, "Failed to access image %s\n", sicon);
            exit (EXIT_FAILURE);
        }
    }   
    /* overlay icon */
    if (oicon != NULL) {
        if (access(oicon, R_OK) == -1) {
            fprintf(stderr, "Failed to access image %s\n", oicon);
            exit (EXIT_FAILURE);
        }
    }

    char destimg[PATH_MAX];
    cairo_surface_t *cd;
    cd = cairo_image_surface_create
                            (CAIRO_FORMAT_ARGB32, D, D);
    snprintf(destimg, sizeof(destimg), "%s", get_user_out_file(dest));
    cairo_t *d;
    d = cairo_create(cd);

    /* background icon and position */
    cairo_rectangle(d, 0.0, 0.0, D, D);
    glob.background_image = cairo_image_surface_create_from_png(sicon);
    cairo_set_source_surface(d, glob.background_image, 0, 0);
    cairo_paint(d);

    /* overlay icon and position */
    glob.overlay_image = cairo_image_surface_create_from_png(oicon);
    cairo_set_source_surface(d, glob.overlay_image, 0, 0);
    cairo_paint(d);

    /* error check */
    cairo_status_t res = cairo_surface_status(cd);
    const char *ret;
    ret = cairo_status_to_string (res);
    if (res != CAIRO_STATUS_SUCCESS) {
        cairo_surface_destroy(cd);
        cairo_destroy(d);
        fprintf(stderr, "Cairo : %s\n", ret);
        exit (EXIT_FAILURE);
    }
    cairo_surface_write_to_png (cd, destimg);

    /* cleanup */
    cairo_surface_destroy(glob.overlay_image);
    cairo_surface_destroy(glob.background_image);
    cairo_surface_destroy(cd);
    cairo_destroy(d);
    fprintf(stdout, "image saved to %s\n", destimg);
}

int main(int argc, char **argv) {
    if (argc < 4) {
        fprintf(stderr, "3 arguments required\n\n");
        usage();
        return 1;
    }
    char svalue[PATH_MAX]; /* source png */
    char nvalue[PATH_MAX]; /* overlay png */
    char ovalue[PATH_MAX]; /* output path png */
    strcpy(svalue, argv[1]);
    strcpy(nvalue, argv[2]);
    strcpy(ovalue, argv[3]);

    paint_img(svalue, nvalue, ovalue);
    return 0;
}

and the Makefile

CC?=gcc
CFLAGS+=-Wall -pedantic -std=gnu99 $(shell pkg-config --cflags cairo)
LDFLAGS+=-lcairo
PROG=pngoverlay-cairo
INSTALL_PATH=/usr/sbin

all: $(PROG)

$(PROG): $(PROG).o
    $(CC) -o $@ $^ $(LDFLAGS)

$(PROG).o: $(PROG).c
    $(CC) -o $@ $(CFLAGS) -c $^

install:
    install -s -m 0755 $(PROG) $(DESTDIR)$(INSTALL_PATH)

uninstall:
    rm $(INSTALL_PATH)/$(PROG)

clean:
    -rm -f *.o $(PROG)

It doesn't check the file extension or anything really but cairo itself does check if a valid PNG is sourced and will close the program accordingly and all resources should then be freed. It doesn't check icon size either. The prog is hardwired to 48x48 so any other size will produce rubbish. garbage > prog > more garbage

What it does do is work outside of X, and in place, so no silly copying of the file to the location of the png's. The exec is mucho smallero too. (~11k stripped 64).

There are some other handy snippets too,

icon_switcher snippet (mid way thru func_switch())

#new standardised icons to show when mounted...
    rm -f ${SYSROOT}/usr/local/lib/X11/pixmaps/*_mntd*.png
    (cd ${SYSROOT}/usr/local/lib/X11/pixmaps
    for ONEDRV in card drive floppy optical usbdrv; do
        pngoverlay.sh ${ONEDRV}48.png closebox_outline48.png ${ONEDRV}_mntd48.png #background foreground output.
        pngoverlay.sh ${ONEDRV}48.png locked_outline48.png ${ONEDRV}_mntd_boot48.png
    done)

and the matching pngoverlay.sh

#!/bin/sh
# Barry Kauler 2011 GPL3 (/usr/share/doc/legal)
#pngoverlay.sh is an alternative to pngoverlay written by vovchik (in BaCon)
# (vovchik's pngoverlay requires X to be running, which may be a disadvantage)
#requires netpbm svn rev 1543 or later, with pamcomp -mixtransparency
#requires three params, 1st and 2nd must exist:
# bottom-image top-image output-image
#overlays the two images, with common areas of transparency in output image.

if [ -x /usr/sbin/pngoverlay-cairo ];then
    /usr/sbin/pngoverlay-cairo "$@" && exit 0
fi

[ ! $3 ] && exit 1
[ ! -e "$1" ] && exit 1
[ ! -e "$2" ] && exit 1
[ "`echo -n "$1" | grep 'png$'`" = "" ] && exit 1
[ "`echo -n "$2" | grep 'png$'`" = "" ] && exit 1

pngtopam -alphapam "${1}" > /tmp/pngoverlay_${$}_1.pam
pngtopam -alphapam "${2}" > /tmp/pngoverlay_${$}_2.pam
#1st image on top, 2nd on bottom, 3rd is output...
pamcomp -mixtransparency /tmp/pngoverlay_${$}_2.pam /tmp/pngoverlay_${$}_1.pam > /tmp/pngoverlay_${$}_out.png 2> /dev/null
pamrgbatopng /tmp/pngoverlay_${$}_out.png > "${3}"
rm -f /tmp/pngoverlay_${$}_1.pam
rm -f /tmp/pngoverlay_${$}_2.pam
rm -f /tmp/pngoverlay_${$}_out.pam
wdlkmpx commented 5 years ago

I compiled this in slacko 140.. and tested it in dpup stretch. It works

It will be the only supported pngoverlay both in woof and in the running system.

There will also be a generic.petbuild just in case.

I have to build a slacko 140*64 + a raspup to compile pngoverlay.

01micko commented 5 years ago

I can do 64 and armhf if needed. I did do armhf but the USBHDD died on me... was building a devuan based raspi version .. all is not lost tho because I saved the config files.

01micko commented 5 years ago

I certainly have an ulterior motive for pngoverlay-cairo (which I don't care what it is named, so long as it is consistent) and that is that devuan armhf netpbm package is severely restricted so the script pngoverlay.sh failed for me. I really needed it to work in chroot too (using zwn) which woof should do to install packages anyway. It does however make cross building difficult.

Here is a sneak-peek at what I have, and it is certainly at alpha stage too because dpkg, apt and friends are working as well as the devx. If I hadn't have had the crappy hardware failure I'd be releasing this week, but alas...

rassuan_screeny_1

wdlkmpx commented 5 years ago

I was not able to compile (a generic arm) pngoverlay-cairo in my raspi 1.. it would not boot, the board seems to be dead.

zwn uses a woof-arch tarball, which has not been updated

wdlkmpx commented 5 years ago

Apparently there is a local store that sells raspis

raspi zero $22 raspi zero w $32 raspi zero - mini hdmi + mini usb adapters $12 raspi 1a+ $45 - hahaha rapis 2b $50 - another joke raspi 3b+ $67

I guess i can buy a raspi zero + raspi 3b+ ($100), i'm just so disappointed that my raspi 1 no longer works. Something happened and i wasn't there see it. I want to sell my barely used Hyperx Fury 8GB DDR3 RAM, my 2GB nvidia graphics card, my bluray burner, bluray player, also my 200+ old useless coins, my cheap electric/acoustic guitars, What else, everything else. Nothing makes sense since i sold my digitech death metal effect

woodenshoe-wi commented 5 years ago

This was compiled in raspup, which is based on Raspbian, not Debian. https://www.dropbox.com/s/v0t2lb9kyivf84v/pngoverlay-cairo?dl=1

It was working when I tested it on my raspi, hopefully it didn’t get corrupted on its way into Dropbox.

I have the opposite problem than 01micko, my raspis are fine but it is the hard drive in my PC that I think is failing.

@wdlkmpx if you are getting a constant red light on your pi without any blinking maybe something is wrong with the SD card. Once my pi wouldn’t boot after changing the SD card and after taking it out, wiping the contacts and putting it back in it booted. If you are not getting any lights then something could be wrong with the power adapter, power cable or USB power connector on the pi itself.

01micko commented 5 years ago

What else, everything else. Nothing makes sense since i sold my digitech death metal effect

Don't sell your guitars. Just get a cheapo champ or something (tube/valve) and plug in a pedal. My little vox 12ax7/el84 5 watt sounds great with a tube screamer. Remember,tone comes from the fingers.

01micko commented 5 years ago

BTW; the first line of the Makefile needs editing,

Should be CC=gcc , ommitting the ? , because for some reason gcc-6 armhf spat the dummy.

01micko commented 5 years ago

@woodenshoe-wi BTW, thanks for your efforts on RPI, without which my RPI3 would be collecting dust.

@wdlkmpx Get a website and a donation button.

wdlkmpx commented 5 years ago

The minimum version for the raspis is debian/raspbian stretch / devuan ascii.

Stuff was compiled in raspbian stretch, and i think woodendshoe-wi said that it needs to be compiled in a raspi 1 for a package to be compatible with all raspis.. some gcc stuff is activated or something.

I think that my raspi is indeed dead, i used different sd cards, OSes, hdmi cables, etc. There is no ACT (ivity) lights just a red light (power). It might be my fault, it was in several places, and perhaps someone or some little devil (cat) dropped it to the floor. I'll be 5 times more careful from now on. I'll be a different person.

But i read the raspis do indeed suddenly die [often].

I do like buying adapters and stuff as long it's cheap, i can find everything quite cheap, but the raspis are way overpriced here.

Reading https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=34061 i see the hdmi stuff does not always work, specially with big screens or something... requires tweaks in some cases

These lines might be worth adding to config.txt

hdmi_force_hotplug=1
 hdmi_drive=1
 config_hdmi_boost=9

https://www.raspberrypi.org/forums/viewtopic.php?t=92038

01micko commented 5 years ago

pngoverlay-cairo armhf I committed was compiled on my pi3 running a woofed version (I built over a year ago) of @woodenshoe-wi 's work on raspup so it might be good on pi1. I scavenged it out of the save dir on the micro sd after the USBHDD died. My pi1 died an age ago. Was the original 256MB version so pretty much useless with a modern pup running in RAM.

wdlkmpx commented 5 years ago

Yesterday i changed the logic to copy sfs's to ram (a bit). You might want to comment in the respective commit.

It's possible to create a cli-only raspup, maybe by duplicating the current raspian/stretch -> stretch-cli, only changing the pkgs_specs, which could be really small and fast for the old pi's, maybe for a small server or something. Such tiny boards.

But overall all apps/libs that are used are cached in ram or something and are unloaded after some time, i noticed this a long time ago. So even when the sfs's are not copied to ram, stuff is as fast as always, but there's more ram available.

As long as no write operations occur, the sd card should not suffer... is this statement true?

Seeing a flash drive with activity lights, there is not much activity, it mostly happen when a program is being opened (and being cached)..

Logic probably needs to be revised again.

woodenshoe-wi commented 5 years ago

I compile stuff on a raspi 1 to make sure it is compatible, but most of the time it should work fine compiling on newer ARM chips as long as the default settings of the Raspbian gcc are used. I don’t think 01micko’s Makefile is trying to automatically detect what CPU it is running on and optimize itself for that 😄. I wasn’t sure if the version I compiled would be compatible with 01micko’s build if it was based on devuan, because if devuan is following the Debian ARM builds, it would be for pi2 and higher chips.

I’m sure I’ve read that the official Rasbian builds are done on more powerful ARM chips and they scan the binaries for illegal instructions to see if the configuration needs to be tweaked to force compatibility.

As long as no write operations occur, the sd card should not suffer... is this statement true?

As far as I know this is true, and if the card could be kept mounted ro most of the time it probably wouldn’t get corrupted by improper shutdowns either.

I remember reading that when using slow media you actually get better performance with light compression like gzip than uncompressed. It also will boot faster without having to wait while copying to RAM.

The only reasons that I can think of that someone would need to be running totally in RAM would be if they want to remove the SD card after booting (I have not tried this, but if you are working on a project that involved using lots of Pis it could save on SD card costs), or network booting (I have not tried this either, but it is supposed to work after a fashion on a Pi3 and better on the newer models).

01micko commented 5 years ago

I now have a pi 0 and woofed up the latest raspup. pngoverlay-cairo works fine.

The only anomaly is that a 'save' icon appears after saving even though I am using a save folder on ext4. (EDIT: I see since 8358e777a18a283283414c7599f452aced834a71 this is expected)

Screenshot