Puppy In-House Development
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
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
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].
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
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].
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
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].
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
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
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
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)
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
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);
}
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].
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
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?
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].
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).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?
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.
I've got a 2009-vintage Acer Aspire One netbook that's in great shape.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?
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.
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
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 domain90% 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
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;
}
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 296 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].
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
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.
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].
Xlib version of technosaurus xcb based image-viewer two post back:
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.
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;
}
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 261 times
Last edited by goingnuts on Sun 02 Jul 2017, 20:44, edited 1 time in total.
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 -
Might have a look at https://github.com/jkriege2/TinyTIFF some time...
Update 20170810: Just realized that my code only works at depth 24 -
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.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 domain90% of the code is just the verbosity of dealing with an xcb window.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; }
An up to date gist to lighten jwm image loading is available at:
https://gist.github.com/technosaurus/36 ... f83d670546
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?
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 performancetechnosaurus 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?
[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]