home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2001 May
/
VPR0105A.BIN
/
OLS
/
BR98211
/
br98211.lzh
/
PNGCDB.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
2000-04-25
|
9KB
|
375 lines
// JPEG Loader for Browser Return Ver2
// Copyright (C) AsakaSoft 2000
// this software uses pnglib and zlib.
//
#include <stdio.h>
#include <dos.h>
#include <setjmp.h>
#include <alloc.h>
#include "png.h"
#define PNG_BYTES_TO_CHECK 8
typedef unsigned int uint;
typedef unsigned char uchar;
uchar pbuf[4][640/8];
uchar nsw = 0;
void pinit ( void );
void pset ( uint x, uchar r, uchar g, uchar b, uchar dx, uchar dy );
void psetg ( uint x, uint gray, uchar dx, uchar dy );
void pwrite ( png_uint_32 w, FILE *cfp );
/*uchar pat[4][4] = {
1, 10, 3, 12,
14, 5, 16, 7,
4, 13, 2, 11,
17, 9, 15, 6 };
*/
uchar pat[4][4] = {
16, 7, 14, 5,
3, 12, 1, 10,
13, 4, 15, 6,
0, 8, 2, 11 };
union REGS inregs, outregs;
struct SREGS segregs;
uint ems_check ( void );
uint ems_getseg ( void );
uint ems_alloc ( uint &handle, uint pages );
uint ems_free ( uint handle );
uint ems_map ( uint handle, uint page );
main () {
png_structp png_ptr;
png_infop info_ptr;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
int interlace_loop = 1;
// uchar far *bufp[800];
uchar far *p;
uchar far *p2;
uchar huge *ph;
size_t rowsize;
FILE *fp;
FILE *cfp;
uchar buf[PNG_BYTES_TO_CHECK];
png_uint_32 i, j, x;
uchar iscolor;
uchar isems;
uint empages, emlines, emhandle, emseg;
/*
outportb ( 0x6a, 1 );
for ( i = 0 ; i < 8 ; i++ ) {
outportb ( 0xa8, i );
outportb ( 0xac, i*2 );
outportb ( 0xaa, i*2 );
outportb ( 0xae, i*2 );
outportb ( 0xa8, i + 8 );
outportb ( 0xac, i*2+1 );
outportb ( 0xaa, i*2+1 );
outportb ( 0xae, i*2+1 );
}
*/
// if ( **(_argv+2) == '/' ) nsw = 1;
fp = fopen ( *(_argv+1), "rb" );
if ( fp == NULL ) return 1;
cfp = fopen ( *(_argv+2), "wb" );
if ( cfp == NULL ) {
fclose ( fp );
return 1;
}
// PNGファイルか検査
if ( fread ( buf, 1, PNG_BYTES_TO_CHECK, fp ) != PNG_BYTES_TO_CHECK ) {
fclose ( fp );
fclose ( cfp );
remove ( *(_argv+2) );
return 1;
}
if ( png_sig_cmp ( buf, 0, PNG_BYTES_TO_CHECK ) != 0 ) {
fclose ( fp );
fclose ( cfp );
remove ( *(_argv+2) );
return 1;
}
printf ( "PNG Loader for AsakaSoft Browser Returns Ver2\n%s\nNow Loading %s\n", png_get_copyright(NULL), *(_argv+1) );
png_ptr = png_create_read_struct ( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if ( png_ptr == NULL ) {
fclose ( fp );
fclose ( cfp );
remove ( *(_argv+2) );
return 1;
}
info_ptr = png_create_info_struct ( png_ptr );
if ( info_ptr == NULL ) {
png_destroy_read_struct ( &png_ptr, (png_infopp)NULL, (png_infopp)NULL );
fclose ( fp );
fclose ( cfp );
remove ( *(_argv+2) );
return 1;
}
if ( setjmp ( png_ptr->jmpbuf ) ) {
png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
fclose ( fp );
fclose ( cfp );
remove ( *(_argv+2) );
return 1;
}
png_init_io ( png_ptr, fp );
png_set_sig_bytes ( png_ptr, PNG_BYTES_TO_CHECK );
png_read_info ( png_ptr, info_ptr );
png_get_IHDR ( png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL );
// 読み込み方の設定
// if ( color_type & PNG_COLOR_MASK_ALPHA ) png_set_strip_alpha ( png_ptr ); // αチャンネルは無視 colortypeは0,2,3のみと考えられる
// if ( bit_depth > 8 ) png_set_strip_16 ( png_ptr ); // 8bitに落とす
if ( color_type & PNG_COLOR_MASK_COLOR ) {
// // モノクロに落とす
// png_set_rgb_to_gray ( png_ptr, 1, NULL, NULL );
iscolor = 1;
} else iscolor = 0;
if ( ( bit_depth < 8 ) || ( color_type & PNG_COLOR_MASK_PALETTE ) ) png_set_expand ( png_ptr ); // 8bitに伸張する ただしαチャンネルが付くことも
png_set_strip_16 ( png_ptr ); // 8bitに落とす
png_set_strip_alpha ( png_ptr ); // αチャンネルを落とす
// 読み込む
// interlace_handlingはread_update_infoの前に
if ( interlace_type == 0 ) {
interlace_loop = 1;
} else {
interlace_loop = png_set_interlace_handling ( png_ptr );
}
png_read_update_info ( png_ptr, info_ptr );
printf ( "X%lu Y%lu Bit%d Type%d", width, height, bit_depth, color_type );
rowsize = png_get_rowbytes ( png_ptr, info_ptr );
printf ( " %dLoops %luByte/Line %luByte\n", interlace_loop, (unsigned long)rowsize, (unsigned long)rowsize*height );
/* for ( i = 0 ; i < height ; i++ ) {
bufp[i] = ( uchar far * ) farmalloc ( (unsigned long)rowsize );
if ( bufp[i] == NULL ) {
printf ( "Not enough memory\n" );
png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
fclose ( fp );
fclose ( cfp );
remove ( *(_argv+2) );
return 1;
}
}
*/
isems = 0;
if ( ems_check() == 0 ) {
// 使用ページ数計算
emlines = 16384 / rowsize;
if ( emlines > 0 ) {
empages = height / emlines;
emseg = ems_getseg ();
if ( emseg != 0 ) {
if ( ems_alloc ( emhandle, empages ) == 0 ) {
isems = 1;
printf ( "EMS %uPages\n", empages );
}
}
}
}
if ( isems == 0 ) {
printf ( "Not enough EMS\n" );
// メインメモリ使用の場合
p = ( uchar far * ) farmalloc ( (unsigned long)rowsize * height );
if ( p == NULL ) {
printf ( "Not enough main memory\n" );
png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
fclose ( fp );
fclose ( cfp );
remove ( *(_argv+2) );
return 1;
}
}
fwrite ( (void *)&width, 4, 1, cfp );
fwrite ( (void *)&height, 4, 1, cfp );
fputc ( 1, cfp );
for ( j = 0 ; j < interlace_loop ; j++ ) {
if ( isems == 0 ) ph = p;
for ( i = 0 ; i < height ; i++ ) {
// png_read_rows ( png_ptr, &bufp[i], NULL, 1 );
if ( isems ) {
ems_map ( emhandle, i / emlines );
p2 = ( uchar far * ) MK_FP ( emseg, ( i % emlines ) * rowsize );
} else {
p2 = ( uchar far *) ph;
}
png_read_rows ( png_ptr, &p2, NULL, 1 );
if ( j == interlace_loop - 1 ) {
pinit ();
for ( x = 0 ; x < width ; x++ ) {
// psetg ( x, bufp[i][x] );
if ( iscolor ) {
pset ( x, p2[x*3], p2[x*3+1], p2[x*3+2], x&3, i&3 );
} else {
psetg ( x, p2[x], x&3, i&3 );
}
}
pwrite ( width, cfp );
}
//printf ( "Pass%lu/%u Buf%Fp Scan%lu/%lu \r", j+1, interlace_loop, p2, i, height );
printf ( "Pass%lu/%u Scan%lu/%lu \r", j+1, interlace_loop, i, height );
if ( isems == 0 ) ph += rowsize;
}
}
/*
png_read_image ( png_ptr, bufp );
for ( i = 0 ; i < height ; i++ ) {
pinit ();
for ( x = 0 ; x < width ; x++ ) {
psetg ( x, bufp[i][x] );
}
pwrite ( i );
//printf ( "Pass%lu Scan%lu Buf%Fp\r", j+1, i, p );
}
*/
png_read_end ( png_ptr, info_ptr );
png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
printf ( "Pass and Scan Complete. \n" );
// for ( i = 0 ; i < height ; i++ ) farfree ( bufp[i] );
if ( isems ) {
ems_free ( emhandle );
} else {
farfree ( p );
}
fclose ( fp );
fclose ( cfp );
return 0;
}
void pinit ( void ) {
memset ( pbuf, 0, 640/8*4 );
}
void pset ( uint x, uchar r, uchar g, uchar b, uchar dx, uchar dy ) {
uchar s;
s = ( (uint)b*28 + (uint)r*77 + (uint)g*151 ) / 256;
psetg ( x, s, dx, dy );
}
void psetg ( uint x, uint gray, uchar dx, uchar dy ) {
uchar or[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
uchar bi, b2;
if ( x >= 640 ) return;
// gray = (uint)gray * 15 / 255;
/* b2 = gray % 17;
gray /= 17;
if ( b2 >= pat[dx][dy] ) gray++;
*/
gray = ( gray + pat[dx][dy] ) / 17;
if ( nsw ) gray = 15 - gray;
bi = x >> 3;
b2 = x & 7;
if ( gray & 1 ) pbuf[0][bi] |= or[b2];
if ( gray & 2 ) pbuf[1][bi] |= or[b2];
if ( gray & 4 ) pbuf[2][bi] |= or[b2];
if ( gray & 8 ) pbuf[3][bi] |= or[b2];
}
/*void pwrite ( uint y ) {
uint gseg[4] = { 0xe000, 0xa800, 0xb000, 0xb800 };
uint i, j;
if ( y >= 400 ) return;
for ( i = 0 ; i < 4; i++ ) {
_fmemcpy ( MK_FP ( gseg[i], y * 80 ), pbuf[i], 80 );
}
}
*/
void pwrite ( png_uint_32 w, FILE *cfp ) {
png_uint_32 x;
uint i;
x = ( w + 7 ) / 8;
if ( x > 80 ) x = 80;
for ( i = 0 ; i < 4; i++ ) {
fwrite ( pbuf[i], x, 1, cfp );
}
}
uint ems_check ( void ) {
uchar id[] = "EMMXXXX0";
uchar far *p;
uchar f;
uint i;
inregs.x.ax = 0x3567;
segread ( &segregs );
int86x ( 0x21, &inregs, &outregs, &segregs );
p = ( uchar far * ) MK_FP ( segregs.es, 0x0a );
f = 0;
for ( i = 0 ; i < 8 ; i++ ) if ( *(p+i) != id[i] ) f = 1;
return ( f );
}
uint ems_getseg ( void ) {
uint ph[8][2], i;
inregs.x.ax = 0x5800;
segread ( &segregs );
segregs.es = FP_SEG ( ( void far * ) ph );
inregs.x.di = FP_OFF ( ( void far * ) ph );
for ( i = 0 ; i < 8 ; i++ ) {
ph[i][0] = 0;
ph[i][1] = 1;
}
int86x ( 0x67, &inregs, &outregs, &segregs );
if ( outregs.h.ah != 0 ) return ( 0 );
for ( i = 0 ; i < 8 ; i++ ) {
if ( ph[i][1] == 0 ) return ( ph[i][0] );
}
return ( 0 );
}
uint ems_alloc ( uint &handle, uint pages ) {
inregs.h.ah = 0x43;
inregs.x.bx = pages;
int86 ( 0x67, &inregs, &outregs );
handle = outregs.x.dx;
return ( outregs.h.ah );
}
uint ems_free ( uint handle ) {
inregs.h.ah = 0x45;
inregs.x.dx = handle;
int86 ( 0x67, &inregs, &outregs );
return ( outregs.h.ah );
}
uint ems_map ( uint handle, uint page ) {
inregs.x.ax = 0x4400;
inregs.x.bx = page;
inregs.x.dx = handle;
int86 ( 0x67, &inregs, &outregs );
return ( outregs.h.ah );
}