Platform Image Utilities for J

Copyright (C) 2006. Oleg Kobchenko. All rights reserved.
http://olegykj.sourceforge.net/

Platform neutral image reading utility with implementations for Windows, Linux and Mac OS X. Supports BMP, GIF, JPEG, PNG, TIFF, Exif, ICO, WMF, and EMF formats.

Returns pixel matrix in ARGB (Alpha most significant) integer format. Good for glpixels.

Uses GDI+, gdk_pixbuf from GTK+, Core Graphics (Quartz).

Examples

These are listings and examples found in the user/platimg folder.

img.ijs

NB. img - read image files for specific platform
NB. 
NB. Uses GDI+ on Windows, gdk_pixbuf on Linux and Core Graphics on Mac
NB. 
NB. Oleg Kobchenko 08/04/2006

require ^:(UNAME-:'Win')    '~user/platimg/win.ijs'
require ^:(UNAME-:'Darwin') '~user/platimg/mac.ijs'
require ^:(UNAME-:'Linux')  '~user/platimg/linux.ijs'

readimg_z_=: readimg_pplatimg_
glimg_jgl2_=: ( ($[glpixels@(0 0,|.@$,,))@readimg@jpath ) : ($:@] [ glsel@[)

0 : 0     NB. Examples   (viewrgb incorrecly inverts RGB, glpixels is OK)
require 'viewmat'
viewrgb readimg jpath'~profile/jicon.gif'
viewrgb readimg jpath'~system/examples/data/jbox.bmp'
viewrgb readimg jpath'~system/extras/help/box.jpg'
viewrgb@readimg^:(UNAME-:'Win') jpath'~home/jr.ico'
viewrgb (0,:247 340)];.0 readimg jpath'~system/extras/help/jforc/jforcprogrammers_files/image001.png'
)

test.ijs

require 'gl2 ~user/platimg/img.ijs'
coinsert 'jgl2'

F=: 0 : 0
pc f;pn "Image Formats";
xywh 20 22 8 8;cc g1 isigraph;
xywh 5 48 36 10;cc s1 static ss_center;cn "jicon.gif";
xywh 52 20 16 16;cc g2 isigraph;
xywh 43 49 33 10;cc s2 static ss_center;cn "jr.ico";
xywh 9 80 64 64;cc g3 isigraph;
xywh 17 151 50 10;cc s3 static ss_center;cn "j.bmp";
xywh 86 27 100 100;cc g4 isigraph;
xywh 113 131 50 10;cc s4 static ss_center;cn "box.jpg";
pas 6 6;pcenter;
rem form end;
)

f_run=: 3 : 0
  wd F
  smoutput 'g1' glimg '~profile/jicon.gif'
  smoutput 'g2' glimg^:(UNAME-:'Win'"_) '~profile/jr.ico'
  smoutput 'g3' glimg '~system/examples/data/j.bmp'
  smoutput 'g4' glimg '~system/extras/help/box.jpg'
  wd 'pshow;'
)

f_close=: wd bind 'pclose'

f_run''

mac.ijs

NB. macimg - image files for Mac OS X
NB. 
NB. Uses Core Graphics from ApplicationServices framework
NB.    http://developer.apple.com/graphicsimaging/quartz/
NB. 
NB. Oleg Kobchenko 08/04/2006

require 'dll'

coclass 'pplatimg'

cfcd=: 1 : '(''/System/Library/Frameworks/CoreFoundation.framework/Versions/Current/CoreFoundation '',m)&cd'

CFStringCreateWithCString=:      'CFStringCreateWithCString        > i   i *c i    ' cfcd
CFURLCreateWithFileSystemPath=:  'CFURLCreateWithFileSystemPath    > i   i i i i   ' cfcd
CFRelease=:                      'CFRelease                        > i   i         ' cfcd

kCFStringEncodingUTF8=: 16b08000100
kCFURLPOSIXPathStyle=: 0

cfstr=: 3 : 'CFStringCreateWithCString 0;y;kCFStringEncodingUTF8'

ascd=: 1 : '(''/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices '',m)&cd'

CGImageSourceCreateWithURL=:      'CGImageSourceCreateWithURL       > i   i i       ' ascd
CGImageSourceCreateImageAtIndex=: 'CGImageSourceCreateImageAtIndex  > i   i i i     ' ascd
CGImageGetWidth=:                 'CGImageGetWidth                  > i   i         ' ascd
CGImageGetHeight=:                'CGImageGetHeight                 > i   i         ' ascd
CGImageRelease=:                  'CGImageRelease                   > i   i         ' ascd
CGColorSpaceCreateWithName=:      'CGColorSpaceCreateWithName       > i   i         ' ascd
CGColorSpaceRelease=:             'CGColorSpaceRelease              > i   i         ' ascd
CGBitmapContextCreate=:           'CGBitmapContextCreate            > i   *i i i   i i i i ' ascd
CGContextRelease=:                'CGContextRelease                 > i   i         ' ascd
CGContextDrawImage=:              'CGContextDrawImage               > i   i f f f f i ' ascd

kCGColorSpaceGenericRGB=: 'kCGColorSpaceGenericRGB'
kCGImageAlphaPremultipliedFirst=: 2

readimg=: 3 : 0
  s=. cfstr y
  CFRelease s [ url=. CFURLCreateWithFileSystemPath 0;s;kCFURLPOSIXPathStyle;0
  
  CFRelease url [ is=. CGImageSourceCreateWithURL url;0
  'image not found' assert is

  CFRelease is [ img=. CGImageSourceCreateImageAtIndex is;0;0
    
  w=. CGImageGetWidth img
  h=. CGImageGetHeight img
  bmp=. (h,w)$_1

  s=. cfstr kCGColorSpaceGenericRGB
  CFRelease s [ cs=. CGColorSpaceCreateWithName s
  
  ctx=. CGBitmapContextCreate bmp;w;h;8;(w*4);cs;kCGImageAlphaPremultipliedFirst
  CGColorSpaceRelease cs
  
  CGContextDrawImage ctx;0;0;w;h;img
  CGContextRelease ctx
  CGImageRelease img
  bmp
)

win.ijs

NB. winimg - image files for Windows
NB. 
NB. Uses GDI+
NB.    http://msdn.microsoft.com/library/en-us/gdicpp/GDIPlus/GDIPlus.asp
NB. 
NB. Oleg Kobchenko 08/04/2006

require 'dll'
coclass 'pplatimg'

s=. 'Ok GenericError InvalidParameter OutOfMemory ObjectBusy InsufficientBuffer '
s=. s,'NotImplemented Win32Error WrongState Aborted FileNotFound ValueOverflow '
s=. s,'AccessDenied UnknownImageFormat FontFamilyNotFound FontStyleNotFound '
s=. s,'NotTrueTypeFont UnsupportedGdiplusVersion GdiplusNotInitialized '
s=. ;:s,'PropertyNotFound PropertyNotSupported ProfileNotFound'

'`and or sh'=: (17 b.)`(23 b.)`(33 b.)
assi=: {::&s assert 0=]
cdi=: (&cd)(assi@)

PixelFormatGDI           =: 16b00020000 NB. Is a GDI-supported format
PixelFormatAlpha         =: 16b00040000 NB. Has an alpha component
PixelFormatCanonical     =: 16b00200000

PixelFormat32bppARGB     =: 10 or (8 sh 32) or PixelFormatAlpha or PixelFormatGDI or PixelFormatCanonical

GdiplusStartup           =: 'gdiplus GdiplusStartup           > i   *i *i i     ' cdi
GdiplusShutdown          =: 'gdiplus GdiplusShutdown          > i   i           ' cdi

GdipCreateBitmapFromFile =: 'gdiplus GdipCreateBitmapFromFile > i   *w *i       ' cdi
GdipDisposeImage         =: 'gdiplus GdipDisposeImage         > i   i           ' cdi

GdipBitmapLockBits       =: 'gdiplus GdipBitmapLockBits       > i   i i i i *i  ' cdi
GdipBitmapUnLockBits     =: 'gdiplus GdipBitmapUnlockBits     > i   i *i        ' cdi

ImageLockModeRead        =: 1

BitmapData =: 'WdthHghtStrdFrmtScanRsrv'
GdiplusStartupInput =: 1 0 0 0

readimg=: 3 : 0
  BMP=. TOK=. ,_1
  DATA=. i.4%~#BitmapData
  GdiplusStartup TOK;GdiplusStartupInput;0
  GdipCreateBitmapFromFile y;BMP
  GdipBitmapLockBits ({.BMP);0;ImageLockModeRead;PixelFormat32bppARGB;DATA
  'w h s f p r'=. DATA
  z=. (h,w)$memr p,0,(w*h),JINT
  GdipBitmapUnLockBits ({.BMP);DATA
  GdipDisposeImage {.BMP
  GdiplusShutdown {.TOK
  z
)

linux.ijs

NB. linimg - image files for Linux
NB. 
NB. Used The gdk-pixbuf Library
NB.     http://developer.gnome.org/doc/API/2.0/gdk-pix
NB.
NB. 08/08/2006 Oleg Kobchenko

require 'dll libpath'

coclass 'pplatimg'

LIBGDKX11=: ' ',~ find_dll 'gtk-x11-2.0'
gtkcd=: 1 : '(LIBGDKX11,m)&cd'
gtk_init_check=: 'gtk_init_check > i  *i i' gtkcd

LIBGTKPIX=: ' ',~ find_dll 'gdk_pixbuf-2.0'
gdkcd=: 1 : '(LIBGTKPIX,m)&cd'

gdk_pixbuf_new             =: 'gdk_pixbuf_new              > i  i i  i i i'gdkcd
gdk_pixbuf_unref           =: 'gdk_pixbuf_unref            > i  i'         gdkcd

gdk_pixbuf_new_from_file   =: 'gdk_pixbuf_new_from_file    > i  *c *i'     gdkcd
gdk_pixbuf_get_file_info   =: 'gdk_pixbuf_get_file_info    > i  *c *i *i'  gdkcd

gdk_pixbuf_get_width       =: 'gdk_pixbuf_get_width        > i  i'         gdkcd
gdk_pixbuf_get_height      =: 'gdk_pixbuf_get_height       > i  i'         gdkcd
gdk_pixbuf_get_n_channels  =: 'gdk_pixbuf_get_n_channels   > i  i'         gdkcd
gdk_pixbuf_get_bits_per_sample=:'gdk_pixbuf_get_bits_per_sample > i  i'    gdkcd
gdk_pixbuf_get_rowstride   =: 'gdk_pixbuf_get_rowstride    > i  i'         gdkcd
gdk_pixbuf_get_pixels      =: 'gdk_pixbuf_get_pixels       > i  i'         gdkcd
gdk_pixbuf_add_alpha       =: 'gdk_pixbuf_add_alpha        > i  i  i i i i'gdkcd

INIT=: 0
init=: 3 : 0
  if. -.INIT do. assert gtk_init_check (,0);0 end.
  INIT=: 1
)

rgba2bgra=: ,@(_4&(2 1 0 3&{\))&.(2&(3!:4))"1  NB. little-endian 32-bit color

NB. =========================================================

readimg=: 3 : 0
  init''
  assert raw=. gdk_pixbuf_new_from_file y;,0
  assert img=. gdk_pixbuf_add_alpha raw;0;0;0;0
  gdk_pixbuf_unref raw
  w=. gdk_pixbuf_get_width img
  h=. gdk_pixbuf_get_height img
  a=. gdk_pixbuf_get_pixels img
  z=. (h,w) $ memr a,0,(w*h),JINT
  gdk_pixbuf_unref img
  rgba2bgra z
)

infoimg=: 3 : 0
  init''
  w=. ,_1
  h=. ,_1
  assert i=. gdk_pixbuf_get_file_info y;w;h
  w,h
)

parimg=: 3 : 0
  init''
  assert b=. gdk_pixbuf_new_from_file y;,0
  z=.   gdk_pixbuf_get_width b
  z=. z,gdk_pixbuf_get_height b
  z=. z,gdk_pixbuf_get_n_channels b
  z=. z,gdk_pixbuf_get_bits_per_sample b
  z=. z,gdk_pixbuf_get_rowstride b
  gdk_pixbuf_unref b
  z
)


NB. =========================================================
0 : 0
coinsert 'pplatimg'
infoimg jpath'~profile/jicon.gif'
parimg jpath'~profile/jicon.gif'
readimg jpath'~profile/jicon.gif'
)