home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2001 May / VPR0105A.BIN / OLS / BR98211 / br98211.lzh / PNGCDB.CPP < prev    next >
C/C++ Source or Header  |  2000-04-25  |  9KB  |  375 lines

  1. // JPEG Loader for Browser Return Ver2
  2. // Copyright (C) AsakaSoft 2000
  3. // this software uses pnglib and zlib.
  4. //
  5.  
  6. #include <stdio.h>
  7. #include <dos.h>
  8. #include <setjmp.h>
  9. #include <alloc.h>
  10. #include "png.h"
  11.  
  12. #define PNG_BYTES_TO_CHECK 8
  13.  
  14. typedef unsigned int uint;
  15. typedef unsigned char uchar;
  16.  
  17. uchar pbuf[4][640/8];
  18. uchar nsw = 0;
  19. void pinit ( void );
  20. void pset ( uint x, uchar r, uchar g, uchar b, uchar dx, uchar dy );
  21. void psetg ( uint x, uint gray, uchar dx, uchar dy );
  22. void pwrite ( png_uint_32 w, FILE *cfp );
  23.  
  24. /*uchar pat[4][4] = {
  25.  1, 10,  3, 12,
  26. 14,  5, 16,  7,
  27.  4, 13,  2, 11,
  28. 17,  9, 15,  6 };
  29. */
  30. uchar pat[4][4] = {
  31. 16,  7, 14,  5,
  32.  3, 12,  1, 10,
  33. 13,  4, 15,  6,
  34.  0,  8,  2, 11 };
  35.  
  36. union REGS inregs, outregs;
  37. struct SREGS segregs;
  38.  
  39. uint ems_check ( void );
  40. uint ems_getseg ( void );
  41. uint ems_alloc ( uint &handle, uint pages );
  42. uint ems_free ( uint handle );
  43. uint ems_map ( uint handle, uint page );
  44.  
  45. main () {
  46.     png_structp png_ptr;
  47.     png_infop info_ptr;
  48.     png_uint_32 width, height;
  49.     int bit_depth, color_type, interlace_type;
  50.     int interlace_loop = 1;
  51. //    uchar far *bufp[800];
  52.     uchar far *p;
  53.     uchar far *p2;
  54.     uchar huge *ph;
  55.     size_t rowsize;
  56.  
  57.     FILE *fp;
  58.     FILE *cfp;
  59.     uchar buf[PNG_BYTES_TO_CHECK];
  60.     png_uint_32 i, j, x;
  61.     uchar iscolor;
  62.  
  63.     uchar isems;
  64.     uint empages, emlines, emhandle, emseg;
  65. /*
  66.     outportb ( 0x6a, 1 );
  67.     for ( i = 0 ; i < 8 ; i++ ) {
  68.         outportb ( 0xa8, i );
  69.         outportb ( 0xac, i*2 );
  70.         outportb ( 0xaa, i*2 );
  71.         outportb ( 0xae, i*2 );
  72.         outportb ( 0xa8, i + 8 );
  73.         outportb ( 0xac, i*2+1 );
  74.         outportb ( 0xaa, i*2+1 );
  75.         outportb ( 0xae, i*2+1 );
  76.     }
  77. */
  78. //    if ( **(_argv+2) == '/' ) nsw = 1;
  79.     fp = fopen ( *(_argv+1), "rb" );
  80.     if ( fp == NULL ) return 1;
  81.     cfp = fopen ( *(_argv+2), "wb" );
  82.     if ( cfp == NULL ) {
  83.         fclose ( fp );
  84.         return 1;
  85.     }
  86.  
  87.     // PNGファイルか検査
  88.     if ( fread ( buf, 1, PNG_BYTES_TO_CHECK, fp ) != PNG_BYTES_TO_CHECK ) {
  89.         fclose ( fp );
  90.         fclose ( cfp );
  91.         remove ( *(_argv+2) );
  92.         return 1;
  93.     }
  94.     if ( png_sig_cmp ( buf, 0, PNG_BYTES_TO_CHECK ) != 0 ) {
  95.         fclose ( fp );
  96.         fclose ( cfp );
  97.         remove ( *(_argv+2) );
  98.         return 1;
  99.     }
  100.  
  101. printf ( "PNG Loader for AsakaSoft Browser Returns Ver2\n%s\nNow Loading %s\n", png_get_copyright(NULL), *(_argv+1) );
  102.  
  103.     png_ptr = png_create_read_struct ( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
  104.     if ( png_ptr == NULL ) {
  105.         fclose ( fp );
  106.         fclose ( cfp );
  107.         remove ( *(_argv+2) );
  108.         return 1;
  109.     }
  110.  
  111.     info_ptr = png_create_info_struct ( png_ptr );
  112.     if ( info_ptr == NULL ) {
  113.         png_destroy_read_struct ( &png_ptr, (png_infopp)NULL, (png_infopp)NULL );
  114.         fclose ( fp );
  115.         fclose ( cfp );
  116.         remove ( *(_argv+2) );
  117.         return 1;
  118.     }
  119.  
  120.     if ( setjmp ( png_ptr->jmpbuf ) ) {
  121.         png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
  122.         fclose ( fp );
  123.         fclose ( cfp );
  124.         remove ( *(_argv+2) );
  125.         return 1;
  126.     }
  127.  
  128.     png_init_io ( png_ptr, fp );
  129.  
  130.     png_set_sig_bytes ( png_ptr, PNG_BYTES_TO_CHECK );
  131.  
  132.     png_read_info ( png_ptr, info_ptr );
  133.  
  134.     png_get_IHDR ( png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL );
  135.  
  136.     // 読み込み方の設定
  137. //    if ( color_type & PNG_COLOR_MASK_ALPHA ) png_set_strip_alpha ( png_ptr ); // αチャンネルは無視 colortypeは0,2,3のみと考えられる
  138. //    if ( bit_depth > 8 ) png_set_strip_16 ( png_ptr ); // 8bitに落とす
  139.     if ( color_type & PNG_COLOR_MASK_COLOR ) {
  140. //        // モノクロに落とす
  141. //        png_set_rgb_to_gray ( png_ptr, 1, NULL, NULL );
  142.         iscolor = 1;
  143.     } else iscolor = 0;
  144.     if ( ( bit_depth < 8 ) || ( color_type & PNG_COLOR_MASK_PALETTE ) ) png_set_expand ( png_ptr ); // 8bitに伸張する ただしαチャンネルが付くことも
  145.     png_set_strip_16 ( png_ptr ); // 8bitに落とす
  146.     png_set_strip_alpha ( png_ptr ); // αチャンネルを落とす
  147.  
  148.     // 読み込む
  149.     // interlace_handlingはread_update_infoの前に
  150.     if ( interlace_type == 0 ) {
  151.         interlace_loop = 1;
  152.     } else {
  153.         interlace_loop = png_set_interlace_handling ( png_ptr );
  154.     }
  155.  
  156.     png_read_update_info ( png_ptr, info_ptr );
  157. printf ( "X%lu Y%lu Bit%d Type%d", width, height, bit_depth, color_type );
  158.  
  159.     rowsize = png_get_rowbytes ( png_ptr, info_ptr );
  160. printf ( " %dLoops %luByte/Line %luByte\n", interlace_loop, (unsigned long)rowsize, (unsigned long)rowsize*height );
  161.  
  162. /*    for ( i = 0 ; i < height ; i++ ) {
  163.         bufp[i] = ( uchar far * ) farmalloc ( (unsigned long)rowsize );
  164.         if ( bufp[i] == NULL ) {
  165.             printf ( "Not enough memory\n" );
  166.             png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
  167.             fclose ( fp );
  168.             fclose ( cfp );
  169.             remove ( *(_argv+2) );
  170.             return 1;
  171.         }
  172.     }
  173. */
  174.     isems = 0;
  175.     if ( ems_check() == 0 ) {
  176.         // 使用ページ数計算
  177.         emlines = 16384 / rowsize;
  178.         if ( emlines > 0 ) {
  179.             empages = height / emlines;
  180.             emseg = ems_getseg ();
  181.             if ( emseg != 0 ) {
  182.                 if ( ems_alloc ( emhandle, empages ) == 0 ) {
  183.                     isems = 1;
  184.                     printf ( "EMS %uPages\n", empages );
  185.                 }
  186.             }
  187.         }
  188.     }
  189.     if ( isems == 0 ) {
  190.         printf ( "Not enough EMS\n" );
  191.         // メインメモリ使用の場合
  192.         p = ( uchar far * ) farmalloc ( (unsigned long)rowsize * height );
  193.         if ( p == NULL ) {
  194.             printf ( "Not enough main memory\n" );
  195.             png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
  196.             fclose ( fp );
  197.             fclose ( cfp );
  198.             remove ( *(_argv+2) );
  199.             return 1;
  200.         }
  201.     }
  202.  
  203.     fwrite ( (void *)&width, 4, 1, cfp );
  204.     fwrite ( (void *)&height, 4, 1, cfp );
  205.     fputc ( 1, cfp );
  206.     for ( j = 0 ; j < interlace_loop ; j++ ) {
  207.         if ( isems == 0 ) ph = p;
  208.         for ( i = 0 ; i < height ; i++ ) {
  209. //            png_read_rows ( png_ptr, &bufp[i], NULL, 1 );
  210.             if ( isems ) {
  211.                 ems_map ( emhandle, i / emlines );
  212.                 p2 = ( uchar far * ) MK_FP ( emseg, ( i % emlines ) * rowsize );
  213.             } else {
  214.                 p2 = ( uchar far *) ph;
  215.             }
  216.             png_read_rows ( png_ptr, &p2, NULL, 1 );
  217.             if ( j == interlace_loop - 1 ) {
  218.                 pinit ();
  219.                 for ( x = 0 ; x < width ; x++ ) {
  220. //                    psetg ( x, bufp[i][x] );
  221.                     if ( iscolor ) {
  222.                         pset ( x, p2[x*3], p2[x*3+1], p2[x*3+2], x&3, i&3 );
  223.                     } else {
  224.                         psetg ( x, p2[x], x&3, i&3 );
  225.                     }
  226.                 }
  227.                 pwrite ( width, cfp );
  228.             }
  229. //printf ( "Pass%lu/%u Buf%Fp Scan%lu/%lu    \r", j+1, interlace_loop, p2, i, height );
  230. printf ( "Pass%lu/%u Scan%lu/%lu    \r", j+1, interlace_loop, i, height );
  231.             if ( isems == 0 ) ph += rowsize;
  232.         }
  233.     }
  234.  
  235. /*
  236.     png_read_image ( png_ptr, bufp );
  237.         for ( i = 0 ; i < height ; i++ ) {
  238.             pinit ();
  239.             for ( x = 0 ; x < width ; x++ ) {
  240.                 psetg ( x, bufp[i][x] );
  241.             }
  242.             pwrite ( i );
  243. //printf ( "Pass%lu Scan%lu Buf%Fp\r", j+1, i, p );
  244.         }
  245. */
  246.     png_read_end ( png_ptr, info_ptr );
  247.     png_destroy_read_struct ( &png_ptr, &info_ptr, (png_infopp)NULL );
  248. printf ( "Pass and Scan Complete.                    \n" );
  249.  
  250. //    for ( i = 0 ; i < height ; i++ ) farfree ( bufp[i] );
  251.     if ( isems ) {
  252.         ems_free ( emhandle );
  253.     } else {
  254.         farfree ( p );
  255.     }
  256.     fclose ( fp );
  257.     fclose ( cfp );
  258.     return 0;
  259. }
  260.  
  261. void pinit ( void ) {
  262.     memset ( pbuf, 0, 640/8*4 );
  263. }
  264.  
  265. void pset ( uint x, uchar r, uchar g, uchar b, uchar dx, uchar dy ) {
  266.     uchar s;
  267.  
  268.     s = ( (uint)b*28 + (uint)r*77 + (uint)g*151 ) / 256;
  269.     psetg ( x, s, dx, dy );
  270. }
  271.  
  272. void psetg ( uint x, uint gray, uchar dx, uchar dy ) {
  273.     uchar or[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  274.     uchar bi, b2;
  275.  
  276.     if ( x >= 640 ) return;
  277. //    gray = (uint)gray * 15 / 255;
  278. /*    b2 = gray % 17;
  279.     gray /= 17;
  280.     if ( b2 >= pat[dx][dy] ) gray++;
  281. */
  282.     gray = ( gray + pat[dx][dy] ) / 17;
  283.  
  284.     if ( nsw ) gray = 15 - gray;
  285.  
  286.     bi = x >> 3;
  287.     b2 = x & 7;
  288.  
  289.     if ( gray & 1 ) pbuf[0][bi] |= or[b2];
  290.     if ( gray & 2 ) pbuf[1][bi] |= or[b2];
  291.     if ( gray & 4 ) pbuf[2][bi] |= or[b2];
  292.     if ( gray & 8 ) pbuf[3][bi] |= or[b2];
  293. }
  294.  
  295. /*void pwrite ( uint y ) {
  296.     uint gseg[4] = { 0xe000, 0xa800, 0xb000, 0xb800 };
  297.     uint i, j;
  298.     if ( y >= 400 ) return;
  299.     for ( i = 0 ; i < 4; i++ ) {
  300.         _fmemcpy ( MK_FP ( gseg[i], y * 80 ), pbuf[i], 80 );
  301.     }
  302. }
  303. */
  304.  
  305. void pwrite ( png_uint_32 w, FILE *cfp ) {
  306.     png_uint_32 x;
  307.     uint i;
  308.  
  309.     x = ( w + 7 ) / 8;
  310.     if ( x > 80 ) x = 80;
  311.     for ( i = 0 ; i < 4; i++ ) {
  312.         fwrite ( pbuf[i], x, 1, cfp );
  313.     }
  314.  
  315. }
  316.  
  317.  
  318. uint ems_check ( void ) {
  319.     uchar id[] = "EMMXXXX0";
  320.     uchar far *p;
  321.     uchar f;
  322.     uint i;
  323.  
  324.     inregs.x.ax = 0x3567;
  325.     segread ( &segregs );
  326.     int86x ( 0x21, &inregs, &outregs, &segregs );
  327.     p = ( uchar far * ) MK_FP ( segregs.es, 0x0a );
  328.     f = 0;
  329.     for ( i = 0 ; i < 8 ; i++ ) if ( *(p+i) != id[i] ) f = 1;
  330.     return ( f );
  331. }
  332.  
  333. uint ems_getseg ( void ) {
  334.     uint ph[8][2], i;
  335.  
  336.     inregs.x.ax = 0x5800;
  337.     segread ( &segregs );
  338.     segregs.es = FP_SEG ( ( void far * ) ph );
  339.     inregs.x.di = FP_OFF ( ( void far * ) ph );
  340.     for ( i = 0 ; i < 8 ; i++ ) {
  341.         ph[i][0] = 0;
  342.         ph[i][1] = 1;
  343.     }
  344.     int86x ( 0x67, &inregs, &outregs, &segregs );
  345.     if ( outregs.h.ah != 0 ) return ( 0 );
  346.     for ( i = 0 ; i < 8 ; i++ ) {
  347.         if ( ph[i][1] == 0 ) return ( ph[i][0] );
  348.     }
  349.     return ( 0 );
  350. }
  351.  
  352. uint ems_alloc ( uint &handle, uint pages ) {
  353.     inregs.h.ah = 0x43;
  354.     inregs.x.bx = pages;
  355.     int86 ( 0x67, &inregs, &outregs );
  356.     handle = outregs.x.dx;
  357.     return ( outregs.h.ah );
  358. }
  359.  
  360. uint ems_free ( uint handle ) {
  361.     inregs.h.ah = 0x45;
  362.     inregs.x.dx = handle;
  363.     int86 ( 0x67, &inregs, &outregs );
  364.     return ( outregs.h.ah );
  365. }
  366.  
  367. uint ems_map ( uint handle, uint page ) {
  368.     inregs.x.ax = 0x4400;
  369.     inregs.x.bx = page;
  370.     inregs.x.dx = handle;
  371.     int86 ( 0x67, &inregs, &outregs );
  372.     return ( outregs.h.ah );
  373. }
  374.  
  375.