home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / games / wcoltris / source / image / image.c next >
C/C++ Source or Header  |  1994-12-31  |  9KB  |  447 lines

  1. #include <tos.h>
  2. #include <stdlib.h>
  3.  
  4. #include <image.h>
  5.  
  6. /*
  7.     int load_ximg(char *name,MFDB *mfdb,IMG_COLOR **coltab)
  8.     int load_img(char *name,MFDB *mfdb)
  9.  
  10. lade gem-image datei
  11.  
  12. rückgabewerte
  13.     0  -> ok
  14.     <0 -> os-error
  15.     >0 -> 3: format falsch
  16.        -> 2: speicher reicht nicht
  17.        -> 1: allg error
  18.  
  19. coltab wird auf 0l gesetzt wenn keine XIMG datei geladen wird
  20. speicher für bilddaten und farbtabelle wird mit malloc alloziert
  21. */
  22.  
  23. #define BUF_SIZE        2048
  24.  
  25. static int f_id;
  26. static char *w_buf;
  27. static int z,z1;
  28. static long l;
  29.  
  30. static int init_get_byte(long len)
  31. {
  32.     l=len;
  33.     z=0;
  34.     w_buf=malloc(BUF_SIZE);
  35.     if ( !w_buf )
  36.         return IMG_MEMORY;
  37.     return IMG_OK;
  38. }
  39.  
  40. static int get_byte(char *byte)
  41. {
  42. long len;
  43. long ret;
  44.     if ( z==0 ) {
  45.         if ( l<BUF_SIZE ) {
  46.             len=l;
  47.         }
  48.         else {
  49.             len=BUF_SIZE;
  50.             l-=BUF_SIZE;
  51.         }
  52.         if ( (ret=Fread(f_id,len,w_buf))!=len ) {
  53.             if ( ret<0 )
  54.                 return (int)ret;
  55.             else
  56.                 return IMG_ERROR;
  57.         }
  58.         z=(int)len;
  59.         z1=0;
  60.     }
  61.     *byte=w_buf[z1];
  62.     z1++;
  63.     z--;
  64.     return IMG_OK;
  65. }
  66.  
  67. static int get_block(char *buf,int len)
  68. {
  69. int ret;
  70.  
  71.     for ( ; len>0; len-- )
  72.         if ( (ret=get_byte(buf++))!=IMG_OK )
  73.             return ret;
  74.     return IMG_OK;
  75. }
  76.  
  77. static int do_ld_img(char *buffer,char *line_buf,IMG_HEADER *head)
  78. {                /* return: <0 -> os-error, IMG_FORMAT falsches datenformat, IMG_ERROR tosfehler, 0 ok */
  79. char *line,*h,*h1;
  80. char byte,l_cnt,b_cnt;
  81. char muster[16];
  82. int lline_len,line_len;
  83. long pl_len;
  84. int planes,lines,bytes,i;
  85.  
  86.     line_len=head->pix_num/8;
  87.     if ( head->pix_num%8 )
  88.         line_len++;
  89.     lline_len=line_len*head->plane_num;
  90.     pl_len=(long)line_len*head->scan_num;
  91.     if ( line_len&1 )
  92.         pl_len+=head->scan_num;
  93.  
  94.     line=buffer;
  95.     h=line_buf;
  96.     bytes=lines=0;
  97.     l_cnt=1;        /* anzahl von zeilenwiederholungen */
  98.  
  99.     while (1) {
  100.         if ( bytes>=lline_len ) {    /* ganze zeile eingelesen */
  101.             for ( ; l_cnt>0; l_cnt-- ) {
  102.                 h1=line_buf;
  103.                 for ( planes=0; planes<head->plane_num; planes++ ) {
  104.                     for ( i=0,h=line+planes*pl_len; i<line_len; i++ )
  105.                         *h++=*h1++;
  106.                     if ( line_len&1 )
  107.                         *h++=0;
  108.                 }
  109.                 lines++;
  110.                 line+=line_len;
  111.                 if ( line_len&1 )
  112.                     line++;
  113.             }
  114.             if ( lines>=head->scan_num )
  115.                 return IMG_OK;
  116.             l_cnt=1;
  117.             h=line_buf;
  118.             bytes=0;
  119.         }
  120.  
  121.         if ( get_byte(&byte)!=IMG_OK )
  122.             return IMG_ERROR;
  123.         if ( byte==0 ) {
  124.             if ( get_byte(&byte)!=IMG_OK )
  125.                 return IMG_ERROR;
  126.             if ( byte==0 ) {
  127.                 if ( get_byte(&byte)!=IMG_OK )
  128.                     return IMG_ERROR;
  129.                 if ( byte!=0xFF )
  130.                     return IMG_FORMAT;
  131.                 if ( get_byte(&l_cnt)!=IMG_OK )
  132.                     return IMG_ERROR;
  133.             }
  134.             else {
  135.                 for ( i=0; i<head->pat_len; i++ )
  136.                     if ( get_byte(muster+i)!=IMG_OK )
  137.                         return IMG_ERROR;
  138.                 for ( ; byte>0; byte-- ) {
  139.                     for ( i=0; i<head->pat_len; i++ ) {
  140.                         *h++=muster[i];
  141.                         bytes++;
  142.                         if ( bytes>lline_len )
  143.                             return IMG_FORMAT;
  144.                     }
  145.                 }
  146.             }
  147.         }
  148.         else if ( byte==0x80 ) {
  149.             if ( get_byte(&b_cnt)!=IMG_OK )
  150.                 return IMG_ERROR;
  151.             for ( ; b_cnt>0; b_cnt-- ) {
  152.                 if ( get_byte(h++)!=IMG_OK )
  153.                     return IMG_ERROR;
  154.                 bytes++;
  155.                 if ( bytes>lline_len )
  156.                     return IMG_FORMAT;
  157.             }
  158.         }
  159.         else {
  160.           int set=0;
  161.             if ( byte&0x80 ) {
  162.                 byte&=0x7F;
  163.                 set=0xFF;
  164.             }
  165.             for ( ; byte>0; byte-- ) {
  166.                 *h++=set;
  167.                 bytes++;
  168.                 if ( bytes>lline_len )
  169.                     return IMG_FORMAT;
  170.             }
  171.         }
  172.     }
  173. }
  174.  
  175. static IMG_ERR do_load_ximg(IMG_HEADER *head,char *name,MFDB *picture,IMG_COLOR **coltab)
  176. {
  177. long len,llen;
  178. int line_len;
  179. IMG_ERR ret;
  180. char *line_buf;
  181. char byte;
  182.  
  183.     picture->fd_addr=0l;
  184.  
  185.     f_id=Fopen(name,0);
  186.     if ( f_id<0 )
  187.         return f_id;
  188.  
  189.     if ( (len=Fseek(0,f_id,2))<0 ) {
  190.         Fclose(f_id);
  191.         return (int)len;
  192.     }
  193.     if ( Fseek(0,f_id,0)!=0l ) {
  194.         Fclose(f_id);
  195.         return IMG_ERROR;
  196.     }
  197.  
  198.     if ( init_get_byte(len)!=IMG_OK )
  199.         return IMG_MEMORY;
  200.  
  201.     /*
  202.             lese header
  203.     */
  204.     if ( (ret=get_block((char*)head,(int)sizeof(IMG_HEADER)))!=IMG_OK ) {
  205.         Fclose(f_id);
  206.         return ret;
  207.     }
  208.  
  209.     head->head_len*=2;    /* head_len in bytes, nicht words */
  210.     len-=head->head_len;
  211.     head->head_len-=(int)sizeof(IMG_HEADER);
  212.  
  213.     *coltab=0l;
  214.     if ( head->head_len>sizeof(IMG_HEADER) ) {        /* zus. header überlesen */
  215.       struct {                                    /* ximg-header lesen */
  216.         long id;
  217.         int col_flag;
  218.       } ximg;
  219.       int col_len;
  220.  
  221.         if ( head->head_len>sizeof(ximg) ) {
  222.             if ( get_block((char*)&ximg,(int)sizeof(ximg))!=IMG_OK ) {
  223.                 Fclose(f_id);
  224.                 return IMG_ERROR;
  225.             }
  226.             head->head_len-=(int)sizeof(ximg);
  227.             if ( ximg.id=='XIMG' && ximg.col_flag==0 ) {
  228.                 col_len=(int)sizeof(IMG_COLOR)*1<<head->plane_num;
  229.                 *coltab=malloc(col_len);
  230.                 if ( *coltab==0l ) {
  231.                     Fclose(f_id);
  232.                     return IMG_MEMORY;
  233.                 }
  234.                 if ( col_len<=head->head_len ) {
  235.                     if ( get_block((char*)*coltab,col_len)!=IMG_OK ) {
  236.                         Fclose(f_id);
  237.                         return IMG_ERROR;
  238.                     }
  239.                     head->head_len-=(int)col_len;
  240.                 }
  241.                 else {
  242.                     free(*coltab);
  243.                 }
  244.             }
  245.         }
  246.     }
  247.  
  248.     if ( head->head_len>0 ) {
  249.         while ( head->head_len-- ) {
  250.             if ( (ret=get_byte(&byte))!=IMG_OK ) {
  251.                 Fclose(f_id);
  252.                 return ret;
  253.             }
  254.         }
  255.     }
  256.     else if ( head->head_len<0 ) {
  257.         Fclose(f_id);
  258.         return IMG_FORMAT;
  259.     }
  260.  
  261.     if ( head->plane_num>8 || head->pat_len>8 ) {
  262.         Fclose(f_id);
  263.         return IMG_FORMAT;
  264.     }
  265.  
  266.     picture->fd_h=head->scan_num;
  267.     picture->fd_nplanes=head->plane_num;
  268.     picture->fd_stand=1;
  269.  
  270.     line_len=head->pix_num/8;
  271.     if ( head->pix_num%8 )
  272.         line_len++;
  273.     picture->fd_wdwidth=line_len/2;
  274.     if ( line_len&1 )
  275.         picture->fd_wdwidth++;
  276.     
  277.     picture->fd_w=head->pix_num;
  278.  
  279.     len=(long)picture->fd_wdwidth*2*(long)head->scan_num*(long)head->plane_num;
  280.  
  281.     picture->fd_addr=malloc(len);
  282.     if ( picture->fd_addr==0l ) {
  283.         Fclose(f_id);
  284.         return IMG_MEMORY;
  285.     }
  286.  
  287.     llen=(long)head->pix_num*head->plane_num/8;
  288.     line_buf=malloc(llen);
  289.     if ( !line_buf ) {
  290.         Fclose(f_id);
  291.         return IMG_MEMORY;
  292.     }
  293.  
  294.     ret=do_ld_img(picture->fd_addr,line_buf,head);
  295.  
  296.     Fclose(f_id);
  297.     free(line_buf);
  298.     free(w_buf);
  299.  
  300.     return ret;
  301. }
  302.  
  303.  
  304. static IMG_ERR do_load_img(IMG_HEADER *head,char *name,MFDB *picture)
  305. {
  306. long len,llen;
  307. int line_len;
  308. IMG_ERR ret;
  309. char *line_buf;
  310. char byte;
  311.  
  312.     picture->fd_addr=0l;
  313.  
  314.     f_id=Fopen(name,0);
  315.     if ( f_id<0 )
  316.         return f_id;
  317.  
  318.     if ( (len=Fseek(0,f_id,2))<0 ) {
  319.         Fclose(f_id);
  320.         return (int)len;
  321.     }
  322.     if ( Fseek(0,f_id,0)!=0l ) {
  323.         Fclose(f_id);
  324.         return IMG_ERROR;
  325.     }
  326.  
  327.     if ( init_get_byte(len)!=IMG_OK )
  328.         return IMG_MEMORY;
  329.  
  330.     /*
  331.             lese header
  332.     */
  333.     if ( (ret=get_block((char*)head,(int)sizeof(IMG_HEADER)))!=IMG_OK ) {
  334.         Fclose(f_id);
  335.         return ret;
  336.     }
  337.  
  338.     head->head_len*=2;    /* head_len in bytes, nicht words */
  339.     len-=head->head_len;
  340.     head->head_len-=(int)sizeof(IMG_HEADER);
  341.  
  342.     if ( head->head_len>0 ) {
  343.         while ( head->head_len-- ) {
  344.             if ( (ret=get_byte(&byte))!=IMG_OK ) {
  345.                 Fclose(f_id);
  346.                 return ret;
  347.             }
  348.         }
  349.     }
  350.     else if ( head->head_len<0 ) {
  351.         Fclose(f_id);
  352.         return IMG_FORMAT;
  353.     }
  354.  
  355.     if ( head->plane_num>8 || head->pat_len>8 ) {
  356.         Fclose(f_id);
  357.         return IMG_FORMAT;
  358.     }
  359.  
  360.     picture->fd_h=head->scan_num;
  361.     picture->fd_nplanes=head->plane_num;
  362.     picture->fd_stand=1;
  363.  
  364.     line_len=head->pix_num/8;
  365.     if ( head->pix_num%8 )
  366.         line_len++;
  367.     picture->fd_wdwidth=line_len/2;
  368.     if ( line_len&1 )
  369.         picture->fd_wdwidth++;
  370.     
  371.     picture->fd_w=head->pix_num;
  372.  
  373.     len=(long)picture->fd_wdwidth*2*(long)head->scan_num*(long)head->plane_num;
  374.  
  375.     picture->fd_addr=malloc(len);
  376.     if ( picture->fd_addr==0l ) {
  377.         Fclose(f_id);
  378.         return IMG_MEMORY;
  379.     }
  380.  
  381.     llen=(long)head->pix_num*head->plane_num/8;
  382.     line_buf=malloc(llen);
  383.     if ( !line_buf ) {
  384.         Fclose(f_id);
  385.         return IMG_MEMORY;
  386.     }
  387.  
  388.     ret=do_ld_img(picture->fd_addr,line_buf,head);
  389.  
  390.     Fclose(f_id);
  391.     free(line_buf);
  392.     free(w_buf);
  393.  
  394.     return ret;
  395. }
  396.  
  397.  
  398. IMG_ERR xload_ximg(IMG_HEADER *head,char *name,MFDB *picture,IMG_COLOR **coltab)
  399. {
  400. IMG_ERR ret;
  401.  
  402.     ret=do_load_ximg(head,name,picture,coltab);
  403.     if ( ret!=IMG_OK ) {
  404.         if ( picture->fd_addr ) {
  405.             free(picture->fd_addr);
  406.             picture->fd_addr=0l;
  407.         }
  408.         if ( *coltab ) {
  409.             free(*coltab);
  410.             *coltab=0l;
  411.         }
  412.         if ( w_buf )
  413.             free(w_buf);
  414.     }
  415.     return ret;
  416. }
  417.  
  418. IMG_ERR xload_img(IMG_HEADER *head,char *name,MFDB *picture)
  419. {
  420. IMG_ERR ret;
  421.  
  422.     ret=do_load_img(head,name,picture);
  423.     if ( ret!=IMG_OK ) {
  424.         if ( picture->fd_addr ) {
  425.             free(picture->fd_addr);
  426.             picture->fd_addr=0l;
  427.         }
  428.         if ( w_buf )
  429.             free(w_buf);
  430.     }
  431.     return ret;
  432. }
  433.  
  434. IMG_ERR load_ximg(char *name,MFDB *picture,IMG_COLOR **coltab)
  435. {
  436. IMG_HEADER head;
  437.  
  438.     return xload_ximg(&head,name,picture,coltab);
  439. }
  440.  
  441. IMG_ERR load_img(char *name,MFDB *picture)
  442. {
  443. IMG_HEADER head;
  444.  
  445.     return xload_img(&head,name,picture);
  446. }
  447.