Discussion:
JPEG options
(too old to reply)
muta...@gmail.com
2021-05-14 01:35:17 UTC
Permalink
I'd like to display a fred.jpg

On Windows I would like to have a 32-bit executable
that is run from the command-line like this:

showjpeg fred.jpg

I don't really care what happens then, so long as I
see a picture.

Now I'd like to run "showjpeg" (exact same executable)
under HX on Freedos.

One day I would like the executable to run on PDOS/386
too, which provides unrestricted access to the SVGA
buffer using "video_buffer" below (a flat, 32-bit pointer -
I'm only interested in flat 32-bit addressing).

Where do I stand?

HX provides a stack of graphics capabilities but I
don't know which, if any, to choose.

I've never done graphics programming before, except
for the below test program.

Ideally I'd like public domain code to interpret the
JPEG, but for now I'll accept any freeware license.

Thanks. Paul.




/*********************************************************************/
/* */
/* This Program Written By Paul Edwards. */
/* Released to the public domain. */
/* */
/*********************************************************************/
/*********************************************************************/
/* */
/* Manipulate the video card */
/* */
/*********************************************************************/

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

#include <pos.h>
#include <bos.h>

typedef struct {
unsigned short seg;
unsigned short off;
} FARP;

#define FARP2ADDR(x) ((void *)(((unsigned long)x.seg << 4) + x.off))

typedef unsigned long U32;

typedef struct {
char sig[4];
unsigned short VESAver;
FARP OEMname;
U32 cap;
FARP modeptr;
unsigned short mem;
unsigned short OEMver;
FARP vendor_name;
FARP product_name;
FARP revision;
unsigned short AFver;
FARP acc_modes;
char res1[216];
char res2[256];
} VESAinfo;

typedef struct {
unsigned short mode_attributes;
unsigned char wina_attributes;
unsigned char winb_attributes;
unsigned short win_granularity;
unsigned short win_size;
unsigned short wina_startseg;
unsigned short winb_startseg;
FARP position_func;
unsigned short bytes_scan;
unsigned short width;
unsigned short height;
unsigned char width_cell;
unsigned char height_cell;
unsigned char memory_planes;
unsigned char bits_pixel;
unsigned char banks;
unsigned char memory_model;
unsigned char size_bank;
unsigned char image_pages;
unsigned char reserved1;
unsigned char red_mask;
unsigned char red_pos;
unsigned char green_mask;
unsigned char green_pos;
unsigned char blue_mask;
unsigned char blue_pos;
unsigned char res_mask;
unsigned char res_pos;
unsigned char color_info;
U32 video_buffer;
FARP offscreen; /* is this a far pointer? */
unsigned short size_offscreen;
unsigned short bytes_scan_linear;
unsigned char banked_num_images;
unsigned char linear_num_images;
unsigned char direct_red_mask;
unsigned char red_mask_lsb;
unsigned char direct_green_mask;
unsigned char green_mask_lsb;
unsigned char direct_blue_mask;
unsigned char blue_mask_lsb;
unsigned char direct_res_mask;
unsigned char res_mask_lsb;
U32 pixel_clock;
unsigned char reserved2[190];
} VESAMinfo;

typedef struct {
char reserved[60];
} VESACRTC;

int main(int argc, char **argv)
{
VESAinfo *vi;
VESAMinfo *mi;
char *vendor_name;
unsigned short *modes;
int x = 0;
int y;
unsigned char *vidbuf;
unsigned char *palet;
unsigned int oldmode;
int scancode;
int ascii;

vi = PosAllocMem(sizeof *vi, POS_LOC20);
printf("vi is %p\n", vi);
mi = PosAllocMem(sizeof *mi, POS_LOC20);
printf("mi is %p\n", mi);
memcpy(vi->sig, "VBE2", 4);
BosVBEGetInfo(vi);
printf("buf starts %.4s\n", vi);
vendor_name = FARP2ADDR(vi->vendor_name);
printf("vendor_name is %s\n", vendor_name);
#if 0
/* these mode numbers seem to be unreliable */
modes = FARP2ADDR(vi->modeptr);
while (*modes != 0xffff)
{
if (*modes & 0x4000)
{
printf("mode is %x\n", *modes);
BosVBEGetModeInfo(*modes, mi);
printf("width is %d, height is %d %lx %x\n",
mi->width, mi->height, (long)mi->video_buffer,
mi->wina_startseg);
/* if (mi->width == 1920) break; */
/* if (mi->width == 1024) break; */
if ((*modes & 0x1ff) == 0x105) break;
x++;
/* if (x == 5) break; */
}
modes++;
}
#endif
BosVBEGetMode(&oldmode);
/* 0x105 is 1024 * 768 * 256, but not guaranteed */
BosVBEGetModeInfo(0x4105, mi); /* note sure if "4" required */
printf("width is %d, height is %d %lx %x\n",
mi->width, mi->height, (long)mi->video_buffer,
mi->wina_startseg);
vidbuf = (unsigned char *)mi->video_buffer;
/* Palette stuff. */
palet = PosAllocMem(12, POS_LOC20);
BosVBESetMode(0x4105, mi); /* not sure if "4" required,
and mi is not correct mapping */
BosVBEPaletteOps(1 /* get */, 1, 0x80, palet); /* doesn't work on my Bochs*/
printf("red: %x green: %x blue: %x aligment: %x\n",palet[0],palet[1],
palet[2],palet[3]);
palet[0] = 0xff; palet[1] = 0; palet[2] = 0; palet[3] = 0;
palet[4] = 0; palet[5] = 0xff; palet[6] = 0; palet[7] = 0;
palet[8] = 0; palet[9] = 0; palet[10] = 0xff; palet[11] = 0;
BosVBEPaletteOps(0 /* set */, 3, 0x80, palet); /* doesn't work on my Bochs*/

for (y = 0; y < 200; y++)
{
for (x = 0; x < 400; x++)
{
vidbuf[1024 * 300 + 500 + 1024 * y + x] = 0x80;
}
}
for (y = 0; y < 100; y++)
{
for (x = 0; x < 100; x++)
{
vidbuf[1024 * 300 + 500 + 50 + 1024 * 50 + 1024 * y + x] = 0x60;
}
}
/* Palette test. */
for (y = 0; y < 100; y++)
{
for (x = 0; x < 100; x++)
{
vidbuf[1024 * 300 + 1024 * y + x] = 0x82;
}
}
for (y = 0; y < 100; y++)
{
for (x = 0; x < 100; x++)
{
vidbuf[1024 * 300 + 100 + 1024 * y + x] = 0x81;
}
}
for (y = 0; y < 100; y++)
{
for (x = 0; x < 100; x++)
{
vidbuf[1024 * 300 + 200 + 1024 * y + x] = 0x80;
}
}
BosReadKeyboardCharacter(&scancode, &ascii);
BosVBESetMode(oldmode, mi); /* mi is not correct mapping */
return (0);
}
Herbert Kleebauer
2021-05-14 15:09:38 UTC
Permalink
Post by ***@gmail.com
I'd like to display a fred.jpg
On Windows I would like to have a 32-bit executable
showjpeg fred.jpg
Take a look at http://ikomi.de/pub/jpeg/pfp.zip

This is a very simple jpeg decoder and the OS part is
separated from the jpeg part, so it should be easy to
adopt it to different OS. The first version was a DOS
version (but graphics card specific) but then I replaced
the OS part by a Windows version. It was for Windows 98
but the program still works in Windows 10.
muta...@gmail.com
2021-05-14 21:07:39 UTC
Permalink
Post by Herbert Kleebauer
Take a look at http://ikomi.de/pub/jpeg/pfp.zip
Thanks!

I didn't see a copyright notice anywhere, nor a
public domain notice. Would you be able to
clarify that please?

Here are my initial attempts to compile:

C:\devel\pfp\SOURCE>gcc pfp.c
In file included from pfp.c:47:0:
win.c: In function ‘WinMain’:
win.c:118:8: warning: passing argument 4 of ‘CreateDIBSection’ from incompatible pointer type [enabled by default]
CreateDIBSection(globalhdc,&bmpinfo,DIB_RGB_COLORS,&bgr,NULL,0))
^
In file included from /usr/include/w32api/windows.h:71:0,
from win.c:10,
from pfp.c:47:
/usr/include/w32api/wingdi.h:3231:28: note: expected ‘void **’ but argument is of type ‘unsigned char **’
WINGDIAPI HBITMAP WINAPI CreateDIBSection(HDC hdc,CONST BITMAPINFO *lpbmi,UINT usage,VOID **ppvBits,HANDLE hSection,DWORD offset);
^
In file included from pfp.c:47:0:
win.c:117:17: warning: assignment from incompatible pointer type [enabled by default]
if (!(bmphandle=
^
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x1ac): undefined reference to `***@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x200): undefined reference to `***@24'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x234): undefined reference to `***@8'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x253): undefined reference to `***@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x372): undefined reference to `***@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x384): undefined reference to `***@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x396): undefined reference to `***@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x7aa): undefined reference to `***@8'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x7dd): undefined reference to `***@20'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x86a): undefined reference to `***@36'
/usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: /cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o: bad reloc address 0x0 in section `.data'
/usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: final link failed: Invalid operation
collect2: error: ld returned 1 exit status



C:\devel\pfp\SOURCE>wcl386 -q -I\watcom\h\win pfp.c
win.c(76): Error! E1009: Expecting ',' or ';' but found 'WinMain'
win.c(125): Warning! W112: Pointer truncated
win.c(125): Note! N2003: source conversion type is 'char __far *'
win.c(125): Note! N2004: target conversion type is 'char *'
win.c(316): Error! E1011: Symbol 'LPDLGTEMPLATE' has not been declared
win.c(316): Error! E1079: Expression must be integral
PFP.C(342): Warning! W107: Missing return value for function 'decode'
win.c(118): Warning! W131: No prototype found for function 'CreateDIBSection'
Error: Compiler returned a bad status compiling "PFP.C"



I'll investigate that later.

BFN. Paul.
Herbert Kleebauer
2021-05-14 22:52:46 UTC
Permalink
Post by ***@gmail.com
Post by Herbert Kleebauer
Take a look at http://ikomi.de/pub/jpeg/pfp.zip
I didn't see a copyright notice anywhere, nor a
public domain notice. Would you be able to
clarify that please?
Just a few lines of trivial code doesn't deserve a
copyright notice. You can do what ever you want to
do with it.
Post by ***@gmail.com
C:\devel\pfp\SOURCE>gcc pfp.c
win.c:118:8: warning: passing argument 4 of ‘CreateDIBSection’ from incompatible pointer type [enabled by default]
CreateDIBSection(globalhdc,&bmpinfo,DIB_RGB_COLORS,&bgr,NULL,0))
I used gcc for the DOS version and Microsoft C for the
Windows version. But that was 20 years ago, so I don't
remember any details about the program. And it was my
first and last Window GUI program.
muta...@gmail.com
2021-05-15 03:56:35 UTC
Permalink
Post by Herbert Kleebauer
Post by ***@gmail.com
Post by Herbert Kleebauer
Take a look at http://ikomi.de/pub/jpeg/pfp.zip
I didn't see a copyright notice anywhere, nor a
public domain notice. Would you be able to
clarify that please?
Just a few lines of trivial code doesn't deserve a
copyright notice.
The three operations:

1. Interpreting a JPEG file format.
2. Finding the correct Windows API to call.
3. Putting the appropriate colors in place

are not trivial to me, and I am grateful that you
have provided code to do this.
Post by Herbert Kleebauer
You can do what ever you want to do with it.
Thanks! What I'd like to do with it is to republish it
as public domain code. Are you willing to release
your code into the public domain without
conditions/caveats?
Post by Herbert Kleebauer
Post by ***@gmail.com
C:\devel\pfp\SOURCE>gcc pfp.c
win.c:118:8: warning: passing argument 4 of ‘CreateDIBSection’ from incompatible pointer type [enabled by default]
CreateDIBSection(globalhdc,&bmpinfo,DIB_RGB_COLORS,&bgr,NULL,0))
I used gcc for the DOS version and Microsoft C for the
Windows version. But that was 20 years ago, so I don't
remember any details about the program. And it was my
first and last Window GUI program.
That was the breakthrough I needed - Microsoft C. I have
that installed, so ran nmake, and got a clean build from
the makefile that previously didn't work for me.

That alerted me to the missing libraries, and I was able
to get gcc to build.

And I had another attempt with Watcom C, and that also
worked after I used the proper include directory - nt instead
of win.

C:\devel\pfp\SOURCE>type compile.bat
rem gcc -o pfp.exe pfp.c -lws2_32 -lmswsock -ladvapi32 -luser32 -lgdi32 -lcomdlg32 -lwinspool
wcl386 -I\watcom\h -I\watcom\h\nt pfp.c ws2_32.lib mswsock.lib advapi32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib

All 3 executables worked fine on Windows 10. I am
particularly happy that it occupied the full screen,
rather than being a window.

However, gcc didn't work on HX under Freedos under Bochs
because I don't have Cygwin available, and the wcl386 version
caused a hang.

But I think the principles are now in place, and I have something
to go to Japheth (or someone else) with for an HX enhancement
(or bug fix), and something for PDOS/386 to work towards.

BFN. Paul.
muta...@gmail.com
2021-05-15 12:25:54 UTC
Permalink
Post by ***@gmail.com
because I don't have Cygwin available, and the wcl386 version
caused a hang.
Correction. The wcl386 version under HX under
Freedos just didn't display anything. Pressing
"x" returned me to the command prompt.

BFN. Paul.
Herbert Kleebauer
2021-05-15 15:43:26 UTC
Permalink
Post by ***@gmail.com
1. Interpreting a JPEG file format.
2. Finding the correct Windows API to call.
3. Putting the appropriate colors in place
are not trivial to me, and I am grateful that you
have provided code to do this.
You are right, these three steps are not trivial. You have
to read a lot of documentation and the main purpose of the
code was, to make sure, that I did understand the documentation
correctly. But the code itself is just a trivial implementation
of the specification.
Post by ***@gmail.com
Post by Herbert Kleebauer
You can do what ever you want to do with it.
Thanks! What I'd like to do with it is to republish it
as public domain code. Are you willing to release
your code into the public domain without
conditions/caveats?
Please remove my email address from the source code, then
you can do what ever you want to do with it. But be aware,
it's just a quick a dirty hack, so maybe you have to rewrite
most of the code to get a version which is worth to be
made public available.
Post by ***@gmail.com
All 3 executables worked fine on Windows 10. I am
particularly happy that it occupied the full screen,
rather than being a window.
As far as I remember, in the debug version (pfpdebug.c)
some loops are unrolled, so the decoding is faster. But
just for understanding the jpeg decoding, the slower
version (pfp.c) is more appropriate. But be sure to switch
debugging of in pfpdebug.c when building a final version,
because otherwise the password for the encrypted multi-jpeg
file could be found in the debug file.
muta...@gmail.com
2021-05-15 22:01:34 UTC
Permalink
Post by Herbert Kleebauer
Post by ***@gmail.com
Thanks! What I'd like to do with it is to republish it
as public domain code. Are you willing to release
your code into the public domain without
conditions/caveats?
Please remove my email address from the source code, then
you can do what ever you want to do with it.
Ok, I will take the above as consent to release the
code (minus your email address) to the public
domain, so I will indeed republish it with an
explicit PD notice, without your email address,
and with the addition of my compile.bat that
compiles for gcc on Windows and Watcom.
Post by Herbert Kleebauer
But be aware,
it's just a quick a dirty hack, so maybe you have to rewrite
most of the code to get a version which is worth to be
made public available.
In my eyes, it is a reference implementation. And now
the public, perhaps for the first time in human history,
owns a JPEG decoder and displayer. There was a time
when JPEG was patented, but now we've come as far
as humanly possible away from that. Well, there's still
more platforms to cover.

Thankyou so much! It means a lot to me. :-)

BFN. Paul.
Herbert Kleebauer
2021-05-16 06:25:16 UTC
Permalink
Post by ***@gmail.com
In my eyes, it is a reference implementation. And now
the public, perhaps for the first time in human history,
owns a JPEG decoder and displayer. There was a time
when JPEG was patented, but now we've come as far
as humanly possible away from that. Well, there's still
more platforms to cover.
There was a free reference implementation of the full
jepeg standard from the beginning. If you just want a
working software use this:

https://jpegclub.org/reference/libjpeg-license/

But if you want to read and understand the jpeg
specification, then maybe my trivial code (which
only supports part of the specification) is a better
start for your own experiments.
muta...@gmail.com
2021-05-16 09:09:37 UTC
Permalink
Post by Herbert Kleebauer
Post by ***@gmail.com
In my eyes, it is a reference implementation. And now
the public, perhaps for the first time in human history,
owns a JPEG decoder and displayer. There was a time
when JPEG was patented, but now we've come as far
as humanly possible away from that. Well, there's still
more platforms to cover.
There was a free reference implementation of the full
jepeg standard from the beginning.
Yes, and it is copyrighted. That was my point. I'm trying
to do some basic computer functions with public domain
software. I'm a long way from achieving that goal. But
you just got me a bit further along the road.

BFN. Paul.

Continue reading on narkive:
Loading...