Puppy In-House Development

Under development: PCMCIA, wireless, etc.
Message
Author
slenkar
Posts: 228
Joined: Sat 11 Jul 2009, 01:26

#381 Post by slenkar »

can you get skype for RLSD

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#382 Post by technosaurus »

another code snippet for testing
simple command line or X11 image viewer using stb_image and netsurf's framebuffer backend libnsfb

It is by no means a full fledged image viewer, just a hacky starting point for one

Code: Select all

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include "libnsfb.h"
#include "libnsfb_event.h"

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

int main(int argc, char **argv)
{
    nsfb_t *nsfb;
    nsfb_event_t event;
    unsigned char *obuf, *fbptr;
    int ocols, orows, fbstride=4, ch = 4;
    if (argc<2) return 1;

    obuf = stbi_load(argv[1], &ocols, &orows, &ch, 4);

    nsfb = nsfb_new((getenv("DISPLAY"))?NSFB_SURFACE_X:NSFB_SURFACE_LINUX);
    if (nsfb == NULL) {
        fwrite("can't allocate nsfb surface\n",1,32,stderr);
        return 2;
    }
    nsfb_set_geometry(nsfb, ocols, orows,NSFB_FMT_ARGB8888);
    if (nsfb_init(nsfb) == -1) {
        fwrite("can't initialise nsfb surface\n",1,30,stderr);
        nsfb_free(nsfb);
        return 3;
    }
    nsfb_get_buffer(nsfb, &fbptr, &fbstride);
    nsfb_bbox_t box = { .x0=0, .y0=0, .x1=ocols, .y1=orows };
	int i=0;
    while(i < (ocols * orows * 4)){
		*fbptr++=obuf[i+2];
		*fbptr++=obuf[i+1];
		*fbptr++=obuf[i];
		*fbptr++=0xff;
		i+=4;
	}
    nsfb_update(nsfb, &box);

    /* wait for quit event or timeout */
    while (1) {
	if (nsfb_event(nsfb, &event, 1000)  == false) {
	    break;
	}
	if (event.type == NSFB_EVENT_CONTROL) {
	    if (event.value.controlcode == NSFB_CONTROL_TIMEOUT) {
		/* timeout */
	    } else if (event.value.controlcode == NSFB_CONTROL_QUIT) {
		break;
	    }
	}
    }

    nsfb_free(nsfb);

    return 0;
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#383 Post by technosaurus »

and another for svg images using svgtiny ... TODO combine them

Code: Select all

/*
 * This file is part of Libsvgtiny
 * Licensed under the MIT License,
 *                http://opensource.org/licenses/mit-license.php
 * Copyright 2008 James Bursa <james@semichrome.net>
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdlib.h>
#include "libnsfb.h"
#include "libnsfb_plot.h"
#include "libnsfb_event.h"
#include <svgtiny.h>



static int setup_fb(void);

int main(int argc, char *argv[])
{
    nsfb_t *nsfb;
    nsfb_bbox_t screen_box;
    uint8_t *fbptr;
    int fbstride;
    nsfb_event_t event;
    FILE *fd;
    float scale = 1.0;
    struct stat sb;
    char *buffer;
    size_t size;
    size_t n;
    struct svgtiny_diagram *diagram;
    svgtiny_code code;

    if (argc != 2 && argc != 3) {
        fprintf(stderr, "Usage: %s FILE [SCALE]\n", argv[0]);
        return 1;
    }

    /* load file into memory buffer */
    fd = fopen(argv[1], "rb");
    if (!fd) {
        perror(argv[1]);
        return 1;
    }

    if (stat(argv[1], &sb)) {
        perror(argv[1]);
        return 1;
    }
    size = sb.st_size;

    buffer = malloc(size);
    if (!buffer) {
        fprintf(stderr, "Unable to allocate %lld bytes\n",
                (long long) size);
        return 1;
    }

    n = fread(buffer, 1, size, fd);
    if (n != size) {
        perror(argv[1]);
        return 1;
    }

    fclose(fd);

    /* read scale argument */
    if (argc == 3) {
        scale = atof(argv[2]);
        if (scale == 0)
            scale = 1.0;
    }

    /* create svgtiny object */
    diagram = svgtiny_create();
    if (!diagram) {
        fprintf(stderr, "svgtiny_create failed\n");
        return 1;
    }

    /* parse */
    code = svgtiny_parse(diagram, buffer, size, argv[1], 1000, 1000);
    if (code != svgtiny_OK) {
        fprintf(stderr, "svgtiny_parse failed: ");
        switch (code) {
        case svgtiny_OUT_OF_MEMORY:
            fprintf(stderr, "svgtiny_OUT_OF_MEMORY");
            break;
        case svgtiny_LIBDOM_ERROR:
            fprintf(stderr, "svgtiny_LIBDOM_ERROR");
            break;
        case svgtiny_NOT_SVG:
            fprintf(stderr, "svgtiny_NOT_SVG");
            break;
        case svgtiny_SVG_ERROR:
            fprintf(stderr, "svgtiny_SVG_ERROR: line %i: %s",
                    diagram->error_line,
                    diagram->error_message);
            break;
        default:
            fprintf(stderr, "unknown svgtiny_code %i", code);
            break;
        }
        fprintf(stderr, "\n");
    }

    free(buffer);

    nsfb = nsfb_new((getenv("DISPLAY"))?NSFB_SURFACE_X:NSFB_SURFACE_LINUX);
    if (nsfb == NULL) {
        fprintf(stderr, "Unable to initialise nsfb with x frontend\n");
        return 1;
    }

    if (nsfb_init(nsfb) == -1) {
        fprintf(stderr, "Unable to initialise nsfb frontend\n");
        return 2;
    }

    /* get the geometry of the whole screen */
    screen_box.x0 = screen_box.y0 = 0;
    nsfb_get_geometry(nsfb, &screen_box.x1, &screen_box.y1, NULL);

    nsfb_get_buffer(nsfb, &fbptr, &fbstride);

    /* claim the whole screen for update */
    nsfb_claim(nsfb, &screen_box);

    nsfb_plot_clg(nsfb, 0xffffffff);

    for (unsigned int i = 0; i != diagram->shape_count; i++) {
        nsfb_plot_pen_t pen;
        pen.stroke_colour = svgtiny_RED(diagram->shape[i].stroke) |
                            svgtiny_GREEN(diagram->shape[i].stroke) << 8|
                            svgtiny_BLUE(diagram->shape[i].stroke) << 16;
        pen.fill_colour = svgtiny_RED(diagram->shape[i].fill) |
                            svgtiny_GREEN(diagram->shape[i].fill) << 8|
                            svgtiny_BLUE(diagram->shape[i].fill) << 16;

        if (diagram->shape[i].fill == svgtiny_TRANSPARENT)
            pen.fill_type = NFSB_PLOT_OPTYPE_NONE;
        else
            pen.fill_type = NFSB_PLOT_OPTYPE_SOLID;

        if (diagram->shape[i].stroke == svgtiny_TRANSPARENT)
            pen.stroke_type = NFSB_PLOT_OPTYPE_NONE;
        else
            pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID;

        pen.stroke_width = scale * diagram->shape[i].stroke_width;

        if (diagram->shape[i].path) {
            nsfb_plot_pathop_t *fb_path;
            int fb_path_c;
            unsigned int j;
            fb_path = malloc(diagram->shape[i].path_length * 3 * sizeof(nsfb_plot_pathop_t));
            fb_path_c = 0;

            for (j = 0;
                 j != diagram->shape[i].path_length; ) {
                switch ((int) diagram->shape[i].path[j]) {
                case svgtiny_PATH_MOVE:
                    fb_path[fb_path_c].operation = NFSB_PLOT_PATHOP_MOVE;
                    fb_path[fb_path_c].point.x = scale * diagram->shape[i].path[j + 1];
                    fb_path[fb_path_c].point.y = scale * diagram->shape[i].path[j + 2];
                    fb_path_c++;
                    j += 3;
                    break;

                case svgtiny_PATH_CLOSE:	
                    fb_path[fb_path_c].operation = NFSB_PLOT_PATHOP_LINE;
                    fb_path[fb_path_c].point.x = fb_path[0].point.x;
                    fb_path[fb_path_c].point.y = fb_path[0].point.y;
                    fb_path_c++;
                    j += 1;
                    break;

                case svgtiny_PATH_LINE:
                    fb_path[fb_path_c].operation = NFSB_PLOT_PATHOP_LINE;
                    fb_path[fb_path_c].point.x = scale * diagram->shape[i].path[j + 1];
                    fb_path[fb_path_c].point.y = scale * diagram->shape[i].path[j + 2];
                    fb_path_c++;

                    j += 3;
                    break;

                case svgtiny_PATH_BEZIER:
                    fb_path[fb_path_c].operation = NFSB_PLOT_PATHOP_MOVE;
                    fb_path[fb_path_c].point.x = scale * diagram->shape[i].path[j + 1];
                    fb_path[fb_path_c].point.y = scale * diagram->shape[i].path[j + 2];
                    fb_path_c++;
                    fb_path[fb_path_c].operation = NFSB_PLOT_PATHOP_MOVE;
                    fb_path[fb_path_c].point.x = scale * diagram->shape[i].path[j + 3];
                    fb_path[fb_path_c].point.y = scale * diagram->shape[i].path[j + 4];
                    fb_path_c++;
                    fb_path[fb_path_c].operation = NFSB_PLOT_PATHOP_CUBIC;
                    fb_path[fb_path_c].point.x = scale * diagram->shape[i].path[j + 5];
                    fb_path[fb_path_c].point.y = scale * diagram->shape[i].path[j + 6];
                    fb_path_c++;

                    j += 7;
                    break;

                default:
                    printf("error ");
                    j += 1;
                }
            }

            nsfb_plot_path(nsfb, fb_path_c, fb_path, &pen);
        } else if (diagram->shape[i].text) {
            /* printf("text %g %g '%s' ",
               scale * diagram->shape[i].text_x,
               scale * diagram->shape[i].text_y,
               diagram->shape[i].text);*/
        }
    }

    svgtiny_free(diagram);

    nsfb_update(nsfb, &screen_box);
    
    while (event.type != NSFB_EVENT_CONTROL)
        nsfb_event(nsfb, &event, -1);

    return 0;
}

static int setup_fb(void)
{


    return 0;
}

/*

cc -g -std=c99 -D_BSD_SOURCE -I/home/vince/netsurf/libnsfb/include/ -I/home/vince/netsurf/libnsfb/src -I/usr/local/include -I/usr/include/libxml2 -Wall -Wextra -Wundef -Wpointer-arith -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Werror -pedantic -Wno-overlength-strings   -DNDEBUG -O2 -DBUILD_TARGET_Linux -DBUILD_HOST_Linux -o build-Linux-Linux-release-lib-static/test_svgtiny.o -c test/svgtiny.c

cc -o build-Linux-Linux-release-lib-static/test_svgtiny build-Linux-Linux-release-lib-static/test_svgtiny.o -Wl,--whole-archive -lnsfb -Wl,--no-whole-archive -lSDL -Lbuild-Linux-Linux-release-lib-static/ -lnsfb -lsvgtiny -lxml2

 */
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#384 Post by technosaurus »

I just posted a tiny (tiny != efficient) mp3 player at http://murga-linux.com/puppy/viewtopic.php?t=59417 ... still needs a lot of optimization, but a good starting point
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#385 Post by technosaurus »

here is a work in progress of the alternative to package management for binary and libraries (regular files are still a mystery ... possibly handle them using inotify and locks on null files)

first we need a downloader, we'll call it binget

Code: Select all

#!/bin/sh
REPO=ftp://example.com/rootdir
case "$1" in
*/lib/*)wget -q -O "$1" "$REPO$1";; #library
*)wget -q -O "/bin/$0" "$REPO/bin/$0";; #binary
esac
This doubles as the hardlink for any binaries we have in the repo (note the $0)
cd /bin
ln binget clang

Then we need something for libraries

Code: Select all

#define _GNU_SOURCE
#include <dlfcn.h> //dladdr
#include <string.h> //strcat

__attribute__((constructor))
void on_load(void) {
  char cmd[256] = "binget ";
  Dl_info dl_info;
  dladdr((void *)on_load, &dl_info);
  strncat(cmd,dl_info.dli_fname,255-strlen(cmd));
  system(cmd);
  dlopen(dl_info.dli_fname,RTLD_GLOBAL|RTLD_NOW);
}
compile with:
gcc -shared -Wl,-soname,libhelper.so.1 -o libhelper.so.1 libhelper.c
cd /lib
ln libhelper.so.1 libLLVM-3.4.so.1

this will load, run on_load (before any symbols get resolved), figure out how it was called (as /lib/libLLVM-3.4.so.1) via dladdr and replace itself with the one it was called as (using binget) then reload the replacement via dlopen and load all the symbols (via RTLD_GLOBAL|RTLD_NOW)
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#386 Post by technosaurus »

64 bit CPUs have been around for well over a decade now and it's tough to find a used PC that isn't 64 bit.

Puppy has long catered to these older systems, but added support for things like PAE for newer systems. One of the biggest reasons we still use x86 is the extra bloat added for x86_64 just for pointers and long. Since Linux3.4 and gcc 4.7 (and new versions of clang) there is a way to get the faster instructions and smaller function call overhead of x86_64 with 32 bit pointers and long called x32.

I think this is something we should consider. Any thoughts against it?
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

linuxcbon
Posts: 1312
Joined: Thu 09 Aug 2007, 22:54

#387 Post by linuxcbon »

technosaurus wrote:64 bit CPUs have been around for well over a decade now and it's tough to find a used PC that isn't 64 bit.
Puppy has long catered to these older systems, but added support for things like PAE for newer systems. One of the biggest reasons we still use x86 is the extra bloat added for x86_64 just for pointers and long. Since Linux3.4 and gcc 4.7 (and new versions of clang) there is a way to get the faster instructions and smaller function call overhead of x86_64 with 32 bit pointers and long called x32.
I think this is something we should consider. Any thoughts against it?
No. (this is my opinion following) Puppy was compiled for x86 to support old computers, that's all. Today, puppy cannot be x86_64 only, since those old 32 bit computers are still used and around (pentium, athlon, k5, k6, cyrix, via, etc).
As for "puppy in-house" I don't see any development anymore, it looks like a dead project, you should better use your energy improving the existing quirky april/appril. ;)

User avatar
Iguleder
Posts: 2026
Joined: Tue 11 Aug 2009, 09:36
Location: Israel, somewhere in the beautiful desert
Contact:

#388 Post by Iguleder »

I'm not convinced. x32 may improve performance only in some cases and creates compatibility issues (since you can't mix x32 binaries with x86_64 ones).
[url=http://dimakrasner.com/]My homepage[/url]
[url=https://github.com/dimkr]My GitHub profile[/url]

darry1966

#389 Post by darry1966 »

Qoute"As for "puppy in-house" I don't see any development anymore, it looks like a dead project, you should better use your energy improving the existing quirky april/appril."

Sigh yep. Though other distros like LinuxBBQ can do the same job with less ram.

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#390 Post by Ibidem »

technosaurus wrote:64 bit CPUs have been around for well over a decade now and it's tough to find a used PC that isn't 64 bit.

Puppy has long catered to these older systems, but added support for things like PAE for newer systems. One of the biggest reasons we still use x86 is the extra bloat added for x86_64 just for pointers and long. Since Linux3.4 and gcc 4.7 (and new versions of clang) there is a way to get the faster instructions and smaller function call overhead of x86_64 with 32 bit pointers and long called x32.

I think this is something we should consider. Any thoughts against it?
I've got a 2009-vintage Acer Aspire One netbook that's in great shape.
Has an Atom N270 processor, which was one of Intel's last semi-'mainstream' 32-bit singlecore processors.

The Quark (Intel's licenseable 'embedded' CPU) is rather specialty; I don't expect it to be a concern for most. Pretty much Galileo and Edison boards are the main use.
But IIRC, it's Pentium (not mmx) ISA, usually single-core, no speedstep, ~400 MHz.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#391 Post by technosaurus »

In my quest to minimalize jwm (replace, cairo, librsvg, libjpeg and libpng with stb_image and nanosvg), I ended up writing this minimal image viewer:

Note: nanosvg uses zlib license, the rest is public domain

Code: Select all

#include <xcb/xcb.h>
#include <xcb/xcb_image.h>
#define STBI_NO_HDR
#define STBI_NO_LINEAR
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define NANOSVG_IMPLEMENTATION
#include "nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvgrast.h"

int main(int argc, char **argv){
	xcb_connection_t *c = xcb_connect(0, 0);
	xcb_screen_t *s = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
	int w, h, n,
		depth = s->root_depth,
		win_class = XCB_WINDOW_CLASS_INPUT_OUTPUT,
		format = XCB_IMAGE_FORMAT_Z_PIXMAP;
	xcb_colormap_t colormap = s->default_colormap;
	xcb_drawable_t win = xcb_generate_id(c);
	xcb_gcontext_t gc = xcb_generate_id(c);
	xcb_pixmap_t pixmap = xcb_generate_id(c);
	xcb_generic_event_t *ev;
	xcb_image_t *image;
	NSVGimage *shapes = NULL;
	NSVGrasterizer *rast = NULL;
	char *data = NULL;
	unsigned *dp;
	size_t i, len;
	uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
		value_mask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS,
		values[] = { s->black_pixel, value_mask };

	if (argc<2) return -1;
	if ((data = stbi_load(argv[1], &w, &h, &n, 4)))
		;
	else if ((shapes = nsvgParseFromFile(argv[1], "px", 96.0f))) {
		w = (int)shapes->width;
		h = (int)shapes->height;
		rast = nsvgCreateRasterizer();
		data = malloc(w*h*4);
		nsvgRasterize(rast, shapes, 0,0,1, data, w, h, w*4);
	}else return -1;
	for(i=0,len=w*h,dp=(unsigned *)data;i<len;i++) //rgba to bgra
		dp[i]=dp[i]&0xff00ff00|((dp[i]>>16)&0xFF)|((dp[i]<<16)&0xFF0000);
	xcb_create_window(c,depth,win,s->root,0,0,w,h,1,win_class,s->root_visual,mask,values);
	xcb_create_pixmap(c,depth,pixmap,win,w,h);
	xcb_create_gc(c,gc,pixmap,0,NULL);
	image = xcb_image_create_native(c,w,h,format,depth,data,w*h*4,data);
	xcb_image_put(c, pixmap, gc, image, 0, 0, 0);
	xcb_image_destroy(image);
	xcb_map_window(c, win);
	xcb_flush(c);
	while ((ev = xcb_wait_for_event(c))) {
		switch (ev->response_type & ~0x80){
		case XCB_EXPOSE: {
			xcb_expose_event_t *x = (xcb_expose_event_t *)ev;
			xcb_copy_area(c,pixmap,win,gc,x->x,x->y,x->x,x->y,x->width,x->height);
			xcb_flush(c);
		}break;
		case XCB_BUTTON_PRESS: goto end;
		default: break;
		}
	}
end:
	xcb_free_pixmap(c, pixmap);
	xcb_disconnect(c);
	return 0;
}
90% of the code is just the verbosity of dealing with an xcb window.


An up to date gist to lighten jwm image loading is available at:
https://gist.github.com/technosaurus/36 ... f83d670546
Attachments
image.c.gz
replace jwm's image.c with this and compile with extra CFLAGS:
-DUSE_STB_IMAGE and -DUSE_NANOSVG -Wl,-lm
(with svg, png and jpeg disabled)
supports jpeg,png,gif,svg,tga,bmp and others
(4.41 KiB) Downloaded 291 times
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#392 Post by technosaurus »

I have posted my minimalistic libc implemenatation to github and named it Brad's Quixotic C
I wrote a little test program to test extremely low overhead threads and it only takes up 156 bytes of RAM on x86_64 (would probably be less on x86)
... something to think about for long running daemon processes.
It's not a full C implementation by any means, but let me know if there are any priority functions anyone would like to see implemented for their projects.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#393 Post by goingnuts »

Xlib version of technosaurus xcb based image-viewer two post back:

Code: Select all

/*Inspired by 
*	xputjpeg by Gleicon S. Moraes - gleicon@terra.com.br
		from: https://searchcode.com/codesearch/raw/107558322/
*	unamed example by technosaurus
		from http://murga-linux.com/puppy/viewtopic.php?t=89272&start=390&sid=1f696000b4032a89e59e66135ce527b8

fun with stb_image...
goingnuts July 2017
compile: gcc xputimage.c -o xputimage -L/usr/lib -L/usr/X11/lib -lX11 -lm
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
#include <math.h>

#ifndef sinf
float sinf (float x) { return (float) sin( (double)x ); }
#endif
#ifndef cosf
float cosf (float x) { return (float) cos( (double)x ); }
#endif
#ifndef tanf
float tanf  (float x){return (float) tan ( (double)x );}
#endif
#ifndef atan2f
float atan2f(float x, float y){return (float) atan2( (double)x, (double)y );}
#endif
#ifndef fmodf
float fmodf (float x, float y){return (float) fmod ( (double)x, (double)y );}
#endif
#ifndef acosf
float acosf (float x){return (float) acos( (double)x );}
#endif

#define STBI_NO_HDR
#define STBI_NO_LINEAR
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define NANOSVG_IMPLEMENTATION
#include "nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvgrast.h"

int main (int argc, char **argv) {

	int				i, len, w, h, n, bpl, depth, screen;
	Pixel			white, black;
	Window			Root, iconwin, win;
	XEvent 			x_event;
	XImage			*ximage;
	Display			*dpy;
	GC				gc;
	XGCValues		gcv;
	char			*data;
	unsigned 		*dp;
	NSVGimage *shapes = NULL;
	NSVGrasterizer *rast = NULL;
	
	if (argc < 2) {
		printf ("Use: %s path.to.image\n", argv[0]);
		exit(1);
	}
	
	if ((data = stbi_load(argv[1], &w, &h, &n, 4)))
		;
	else if ((shapes = nsvgParseFromFile(argv[1], "px", 96.0f))) {
		w = (int)shapes->width;
		h = (int)shapes->height;
		rast = nsvgCreateRasterizer();
		data = malloc(w*h*4);
		nsvgRasterize(rast, shapes, 0,0,1, data, w, h, w*4);
   } else {
   		printf("Unable to load image: %s\n", argv[0]);
		return -1;
	}
		
    for(i=0, len=w*h, dp=(unsigned *)data; i<len; i++) //rgba to bgra
      dp[i]=dp[i]&0xff00ff00|((dp[i]>>16)&0xFF)|((dp[i]<<16)&0xFF0000);
      
   	if (!(dpy = XOpenDisplay(NULL)))
		printf("can't open X display\n");
	
	screen = DefaultScreen(dpy);
	Root = RootWindow (dpy, screen);
	white = WhitePixel (dpy, screen);
	black = BlackPixel (dpy, screen);

	win = XCreateSimpleWindow (dpy, Root, 0, 0, w, h, 0, black, white);

	iconwin = XCreateSimpleWindow (dpy,	win, 0, 0, w, h, 0, black, white);

	XSelectInput(dpy, win, ExposureMask | KeyPressMask);
	XMapWindow (dpy, win);
	gc = XCreateGC (dpy, win, 0, &gcv);

	depth = DefaultDepth(dpy, screen);

	switch(depth) {
	
		case 24: 	
			bpl=4; break;
		case 16:
		case 15: 	
			bpl=2; break;
		default:
			bpl=1; break;
	}

	ximage = XCreateImage (dpy, 
        	CopyFromParent, depth, 
        	ZPixmap, 0, 
        	data, 
        	w, h, 
        	bpl*8, bpl * w);

	XFlush(dpy);

	while (1) {
		XNextEvent(dpy, &x_event);
			switch (x_event.type) {
				case Expose: 
					XPutImage (dpy, win, gc, ximage, 0,0,0,0, w, h);
 					XFlush (dpy);     
					break;
				case KeyPress:	goto end;
				default: break;	
			}
	}

end:
	free (data);
	close(ConnectionNumber(dpy));
	return 0;
}
All the #ifdef math stuff for compile with old uclibc.
One odd thing: If compiled with any CFLAGS like Os, O1 etc. results in svg not working. Static linked bin attached as fake .gz-file.
Attachments
xputimage.gz
remove .gz extension to get the static linked binary
(86.88 KiB) Downloaded 255 times
Last edited by goingnuts on Sun 02 Jul 2017, 20:44, edited 1 time in total.

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#394 Post by greengeek »

Tested ok on Slacko 5.6
Opens png and jpg fine, but did not work with a tif i made.

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#395 Post by goingnuts »

Thanks for testing! No tiff support but jpg, png, bmp, gif, SVG and others.
Might have a look at https://github.com/jkriege2/TinyTIFF some time...
Update 20170810: Just realized that my code only works at depth 24 - :(

User avatar
greengeek
Posts: 5789
Joined: Tue 20 Jul 2010, 09:34
Location: Republic of Novo Zelande

#396 Post by greengeek »

technosaurus wrote:In my quest to minimalize jwm (replace, cairo, librsvg, libjpeg and libpng with stb_image and nanosvg), I ended up writing this minimal image viewer:

Note: nanosvg uses zlib license, the rest is public domain

Code: Select all

#include <xcb/xcb.h>
#include <xcb/xcb_image.h>
#define STBI_NO_HDR
#define STBI_NO_LINEAR
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define NANOSVG_IMPLEMENTATION
#include "nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvgrast.h"

int main(int argc, char **argv){
	xcb_connection_t *c = xcb_connect(0, 0);
	xcb_screen_t *s = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
	int w, h, n,
		depth = s->root_depth,
		win_class = XCB_WINDOW_CLASS_INPUT_OUTPUT,
		format = XCB_IMAGE_FORMAT_Z_PIXMAP;
	xcb_colormap_t colormap = s->default_colormap;
	xcb_drawable_t win = xcb_generate_id(c);
	xcb_gcontext_t gc = xcb_generate_id(c);
	xcb_pixmap_t pixmap = xcb_generate_id(c);
	xcb_generic_event_t *ev;
	xcb_image_t *image;
	NSVGimage *shapes = NULL;
	NSVGrasterizer *rast = NULL;
	char *data = NULL;
	unsigned *dp;
	size_t i, len;
	uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
		value_mask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS,
		values[] = { s->black_pixel, value_mask };

	if (argc<2) return -1;
	if ((data = stbi_load(argv[1], &w, &h, &n, 4)))
		;
	else if ((shapes = nsvgParseFromFile(argv[1], "px", 96.0f))) {
		w = (int)shapes->width;
		h = (int)shapes->height;
		rast = nsvgCreateRasterizer();
		data = malloc(w*h*4);
		nsvgRasterize(rast, shapes, 0,0,1, data, w, h, w*4);
	}else return -1;
	for(i=0,len=w*h,dp=(unsigned *)data;i<len;i++) //rgba to bgra
		dp[i]=dp[i]&0xff00ff00|((dp[i]>>16)&0xFF)|((dp[i]<<16)&0xFF0000);
	xcb_create_window(c,depth,win,s->root,0,0,w,h,1,win_class,s->root_visual,mask,values);
	xcb_create_pixmap(c,depth,pixmap,win,w,h);
	xcb_create_gc(c,gc,pixmap,0,NULL);
	image = xcb_image_create_native(c,w,h,format,depth,data,w*h*4,data);
	xcb_image_put(c, pixmap, gc, image, 0, 0, 0);
	xcb_image_destroy(image);
	xcb_map_window(c, win);
	xcb_flush(c);
	while ((ev = xcb_wait_for_event(c))) {
		switch (ev->response_type & ~0x80){
		case XCB_EXPOSE: {
			xcb_expose_event_t *x = (xcb_expose_event_t *)ev;
			xcb_copy_area(c,pixmap,win,gc,x->x,x->y,x->x,x->y,x->width,x->height);
			xcb_flush(c);
		}break;
		case XCB_BUTTON_PRESS: goto end;
		default: break;
		}
	}
end:
	xcb_free_pixmap(c, pixmap);
	xcb_disconnect(c);
	return 0;
}
90% of the code is just the verbosity of dealing with an xcb window.


An up to date gist to lighten jwm image loading is available at:
https://gist.github.com/technosaurus/36 ... f83d670546
Hi Technosaurus, I am interested in this tiny image viewer (and it's relatives on previous page). How do I potentially use them? Is it "C" code? I tried to stick it in a bash script but of course I am well out of my depth.

I am wanting to display (in a minimal window) jpg files that are accumulated from my webcam based "security camera".

Any suggestions appreciated.

cheers!

EDIT : Do I need to do a "git pull" or something from "technosaurus/jwm-image-lite.c" you linked above - or is that just jwm related?

User avatar
sc0ttman
Posts: 2812
Joined: Wed 16 Sep 2009, 05:44
Location: UK

#397 Post by sc0ttman »

technosaurus wrote:64 bit CPUs have been around for well over a decade now and it's tough to find a used PC that isn't 64 bit.

Puppy has long catered to these older systems, but added support for things like PAE for newer systems. One of the biggest reasons we still use x86 is the extra bloat added for x86_64 just for pointers and long. Since Linux3.4 and gcc 4.7 (and new versions of clang) there is a way to get the faster instructions and smaller function call overhead of x86_64 with 32 bit pointers and long called x32.

I think this is something we should consider. Any thoughts against it?
I came up against an npm install error today that said ia32 not supported, only x32 ... Seems like its a good thing to have, known for its excellent performance :)
[b][url=https://bit.ly/2KjtxoD]Pkg[/url], [url=https://bit.ly/2U6dzxV]mdsh[/url], [url=https://bit.ly/2G49OE8]Woofy[/url], [url=http://goo.gl/bzBU1]Akita[/url], [url=http://goo.gl/SO5ug]VLC-GTK[/url], [url=https://tiny.cc/c2hnfz]Search[/url][/b]

Post Reply