Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

JPEG options

54 views
Skip to first unread message

muta...@gmail.com

unread,
May 13, 2021, 9:35:18 PM5/13/21
to
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

unread,
May 14, 2021, 11:09:43 AM5/14/21
to
On 14.05.2021 03:35, muta...@gmail.com wrote:

> 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

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

unread,
May 14, 2021, 5:07:40 PM5/14/21
to
On Saturday, May 15, 2021 at 1:09:43 AM UTC+10, Herbert Kleebauer wrote:

> 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 `_imp__CreateCompatibleDC@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x200): undefined reference to `_imp__CreateDIBSection@24'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x234): undefined reference to `_imp__SelectObject@8'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x253): undefined reference to `_imp__CreateSolidBrush@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x372): undefined reference to `_imp__DeleteObject@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x384): undefined reference to `_imp__DeleteObject@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x396): undefined reference to `_imp__DeleteDC@4'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x7aa): undefined reference to `_imp__SelectObject@8'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x7dd): undefined reference to `_imp__Rectangle@20'
/cygdrive/c/Users/kerra/AppData/Local/Temp/ccjnkamg.o:pfp.c:(.text+0x86a): undefined reference to `_imp__BitBlt@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

unread,
May 14, 2021, 6:52:51 PM5/14/21
to
On 14.05.2021 23:07, muta...@gmail.com wrote:

>> 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.

>
> 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))

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

unread,
May 14, 2021, 11:56:37 PM5/14/21
to
On Saturday, May 15, 2021 at 8:52:51 AM UTC+10, Herbert Kleebauer wrote:

> >> 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.

> 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?

> > 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))

> 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

unread,
May 15, 2021, 8:25:55 AM5/15/21
to
On Saturday, May 15, 2021 at 1:56:37 PM UTC+10, muta...@gmail.com wrote:

> 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

unread,
May 15, 2021, 11:43:29 AM5/15/21
to
On 15.05.2021 05:56, muta...@gmail.com wrote:

> 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.

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.


>> 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.


> 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

unread,
May 15, 2021, 6:01:35 PM5/15/21
to
On Sunday, May 16, 2021 at 1:43:29 AM UTC+10, Herbert Kleebauer wrote:

> > 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.

> 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

unread,
May 16, 2021, 2:25:19 AM5/16/21
to
On 16.05.2021 00:01, muta...@gmail.com wrote:

> 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

unread,
May 16, 2021, 5:09:38 AM5/16/21
to
On Sunday, May 16, 2021 at 4:25:19 PM UTC+10, Herbert Kleebauer wrote:

> > 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.
0 new messages