home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xicon05.zip / winwrite.c < prev    next >
C/C++ Source or Header  |  1993-05-06  |  6KB  |  200 lines

  1. /* This file is winwrite.c (part of XIcon)
  2.  *
  3.  * Copyright (C) 1993 by Norman Walsh
  4.  *
  5.  *   This program is free software; you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 2 of the License, or
  8.  *   (at your option) any later version.
  9.  *
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *   GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program; if not, write to the Free Software
  17.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  ************************************************************************/
  19.  
  20. #include <stdio.h>
  21. #include "icondata.h"
  22. #include "iconvars.h"
  23. #include "iconio.h"
  24. #include "windata.h"
  25. #include "winwrite.h"
  26.  
  27. win_rgb_info *convert_palette(rgb_info *p, int cnt)
  28. {
  29.   int count;
  30.   win_rgb_info *w = (win_rgb_info *) malloc(cnt * sizeof(win_rgb_info));
  31.  
  32.   for (count = 0; count < cnt; count++, p++)
  33.     {
  34.       w[count].red = p->red;
  35.       w[count].green = p->green;
  36.       w[count].blue = p->blue;
  37.       w[count].unused = 0;
  38.     }
  39.  
  40.   return w;
  41. }
  42.  
  43. int win_map_size(bitmap_info map)
  44. {
  45.   int bytewidth;
  46.  
  47.   bytewidth = ((map.width*map.bits_per_pixel) + 7) / 8;
  48.  
  49. /*
  50.   while (bytewidth % 4 != 0)
  51.     bytewidth++;
  52. */
  53.  
  54.   return bytewidth * map.height;
  55. }
  56.  
  57. void write_win_map (bitmap_info map)
  58. {
  59.   BYTE *rowptr, *ch;
  60.   int  padbytes, count;
  61.  
  62.   count = map.bytewidth;
  63.   padbytes = 0;
  64.  
  65. /*
  66.   while (count % 4 != 0)
  67.     {
  68.       count++;
  69.       padbytes++;
  70.     }
  71. */
  72.  
  73.   rowptr = map.map + map.size - map.bytewidth;
  74.   while (rowptr >= map.map)
  75.     {
  76.       for (count = 0, ch = rowptr; count < map.bytewidth; count++, ch++)
  77.     write_char(*ch);
  78.  
  79.       for (count = 0; count < padbytes; count++)
  80.     write_char(0);
  81.       
  82.       rowptr -= map.bytewidth;
  83.     }
  84. }
  85.  
  86. void write_win_direntry(WinIconDirEntry direntry)
  87. {
  88.   write_char(direntry.bWidth);
  89.   write_char(direntry.bHeight);
  90.   write_char(direntry.bColorCount);
  91.   write_char(direntry.bReserved);
  92.   write_shortint(direntry.wPlanes);
  93.   write_shortint(direntry.wBitCount);
  94.   write_int(direntry.dwBytesInRes);
  95.   write_int(direntry.dwImageOffset);
  96. }
  97.  
  98. void write_win_icon(WinIconBitInfoHdr icon)
  99. {
  100.   int color_count, count;
  101.   BYTE *ch;
  102.  
  103.   write_int(icon.biSize);
  104.   write_int(icon.biWidth);
  105.   write_int(icon.biHeight);
  106.   write_shortint(icon.biPlanes);
  107.   write_shortint(icon.biBitCount);
  108.   write_int(icon.biCompression);
  109.   write_int(icon.biSizeImage);
  110.   write_int(icon.biXPelsPerMeter);
  111.   write_int(icon.biYPelsPerMeter);
  112.   write_int(icon.biClrUsed);
  113.   write_int(icon.biClrImportant);
  114.  
  115.   color_count = 2 << (icon.biBitCount - 1);
  116.   ch = (char *) icon.p;
  117.   for (count = 0; count < (sizeof(win_rgb_info) * color_count); count++)
  118.     {
  119.       write_char(*ch);
  120.       ch++;
  121.     }
  122. }
  123.  
  124. void write_win_file()
  125. {
  126.   int *info_offsets;
  127.   int cur_offset;
  128.   WinIconDirEntry icon_entry;
  129.   WinIconBitInfoHdr icon;
  130.   int count;
  131.   BYTE *ch;
  132.  
  133.   fseek(output, 0, SEEK_SET);
  134.  
  135.   info_offsets = (int *) malloc (sizeof (int) * (generic_count+1));
  136.  
  137.   /* Figure out what the offsets will be for the headers ... */
  138.   cur_offset = 6 + (16 * generic_count);
  139.   for (count = 0; count < generic_count; count++)
  140.     {
  141.       info_offsets[count] = cur_offset;
  142.  
  143.       cur_offset += 40;                    /* sizeof constant parts */
  144.       cur_offset += sizeof(win_rgb_info)*generic[count].clr_map.num_colors;
  145.                                            /* sizeof color palette */
  146.       cur_offset += win_map_size(generic[count].clr_map);
  147.       cur_offset += win_map_size(generic[count].and_map);
  148.     }
  149.  
  150.   info_offsets[generic_count] = cur_offset;
  151.  
  152.   /* Write the header ... */
  153.   write_shortint(0);
  154.   write_shortint(1);
  155.   write_shortint(generic_count);
  156.  
  157.   /*  Write the dir entries to the file ... */
  158.   for (count = 0; count < generic_count; count++)
  159.     {
  160.       icon_entry.bWidth = generic[count].clr_map.width;
  161.       icon_entry.bHeight = generic[count].clr_map.height;
  162.       icon_entry.bColorCount = generic[count].clr_map.num_colors;
  163.       icon_entry.bReserved = 0;
  164.       icon_entry.wPlanes = 1;
  165.       icon_entry.wBitCount = generic[count].clr_map.bits_per_pixel;
  166.       icon_entry.dwBytesInRes = info_offsets[count+1] - info_offsets[count];
  167.       icon_entry.dwImageOffset = info_offsets[count];
  168.       write_win_direntry(icon_entry);
  169.     }
  170.  
  171.   /*  Write the headers to the file ... */
  172.   for (count = 0; count < generic_count; count++)
  173.     {
  174.       icon.biSize = 40; /* ? */
  175.       icon.biWidth = generic[count].clr_map.width;
  176.       icon.biHeight = generic[count].clr_map.height * 2;
  177.       icon.biPlanes = 1;
  178.       icon.biBitCount = generic[count].clr_map.bits_per_pixel;
  179.       icon.biCompression = 0;
  180.       icon.biSizeImage = win_map_size(generic[count].and_map)+
  181.                      win_map_size(generic[count].clr_map);
  182.       icon.biXPelsPerMeter = 0;
  183.       icon.biYPelsPerMeter = 0;
  184.       icon.biClrUsed = generic[count].clr_map.num_colors;
  185.  
  186.       if (generic[count].clr_map.num_colors == 2)
  187.     icon.biClrImportant = 2;
  188.       else
  189.     icon.biClrImportant = 0;
  190.  
  191.       icon.p = convert_palette(generic[count].clr_map.palette,
  192.                    generic[count].clr_map.num_colors);
  193.       write_win_icon(icon);
  194.  
  195.       write_win_map(generic[count].clr_map);
  196.       write_win_map(generic[count].and_map);
  197.     }
  198. }
  199.  
  200.