source: soft/giet_vm/applications/rosenfeld/src/bmpNR.c @ 778

Last change on this file since 778 was 772, checked in by meunier, 9 years ago
  • Ajout de l'application rosenfeld
  • Changement du nom du flag O_CREATE en O_CREAT
File size: 12.3 KB
Line 
1/* --------------- */
2/* --- bmpNR.c --- */
3/* --------------- */
4
5// Copyright (c) 2013-2014 Lionel Lacassagne, All Rights Reserved
6// Laboratoire de Recherche en Informatique
7// Universite Paris-Sud / CNRS
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12
13
14/* -- image -- */
15#ifdef CLI
16#include "nrc_os_config.h"
17#include "nrtype.h"
18#include "nrdef.h"
19#include "nrmacro.h"
20#include "nralloc.h"
21#endif
22
23#include "palette.h"
24
25/* -- local -- */
26
27#include "bmpNR.h"
28
29#define BM 0x4d42
30#define BI_RGB 0L
31
32PRIVATE void ReadBMProw  (int fd, long width, uint8 * row);
33PRIVATE void WriteBMProw (uint8 * row, long width, int fd);
34//PRIVATE void SetupPalette (RGBQUAD Palette[]);
35
36#if (!defined(WIN32) && !defined(_WINDOWS_) && !defined(_WINGDI_))
37//#pragma message("bmpio.h no WINDOWS echo")
38PRIVATE void Palette_RGBQuad2RGBQUAD(RGBQuad * src, RGBQUAD dst[]);
39#endif
40
41/* ------------------------------------- */
42uint8 *ui8ArrayAppend(uint8 *ptr, uint8 x)
43    /* ------------------------------------- */
44{
45    *ptr++ = x;
46    return ptr;
47}
48/* ---------------------------------------- */
49uint8 *ui16ArrayAppend(uint8 *ptr, uint16 x)
50    /* ---------------------------------------- */
51{
52    uint8 x0, x1;
53
54    x0 = x & 0xFF; x = x >> 8;
55    x1 = x & 0xFF; x = x >> 8;
56
57    *ptr++ = x0;
58    *ptr++ = x1;
59
60    return ptr;
61}
62/* -------------------------------------- */
63uint8 *ui32ArrayAppend(uint8 *ptr, uint32 x)
64    /* -------------------------------------- */
65{
66    uint8 x0, x1, x2, x3;
67
68    x0 = x & 0xFF; x = x >> 8;
69    x1 = x & 0xFF; x = x >> 8;
70    x2 = x & 0xFF; x = x >> 8;
71    x3 = x & 0xFF; x = x >> 8;
72
73    *ptr++ = x0;
74    *ptr++ = x1;
75    *ptr++ = x2;
76    *ptr++ = x3;
77
78    return ptr;
79}
80// Seul moyen de cache dans la librairie ces putains de types windoze
81
82// --------------------------------------------------------
83PRIVATE void ReadBMProw(int fd, long width, uint8 *row)
84    // --------------------------------------------------------
85{
86    // Le fichier est ouvert (en lecture) et ne sera pas ferme a la fin
87    read(fd, row, sizeof(uint8) * width);
88}
89// ---------------------------------------------------------
90PRIVATE void WriteBMProw(uint8 *row, long width, int fd)
91    // ---------------------------------------------------------
92{
93    // Le fichier est deja ouvert et ne sera pas ferme a la fin
94    write(fd, row, sizeof(uint8) * width);
95}
96#if (!defined(WIN32) && !defined(_WINDOWS_) && !defined(_WINGDI_))
97//#pragma message("bmpio.h no WINDOWS echo")
98/* ----------------------------------------------------------- */
99PRIVATE void Palette_RGBQuad2RGBQUAD(RGBQuad *src, RGBQUAD dst[])
100    /* ----------------------------------------------------------- */
101{
102    int i;
103    for (i = 0; i < 256; i++) {
104        dst[i].rgbBlue     = (byte) src[i].blue;
105        dst[i].rgbGreen    = (byte) src[i].green;
106        dst[i].rgbRed      = (byte) src[i].red;
107        dst[i].rgbReserved = (byte) 0;
108    }
109}
110#endif
111
112#if (!defined(WIN32) && !defined(_WINDOWS_) && !defined(_WINGDI_))
113//#pragma message("bmpio.h no WINDOWS echo")
114/* --------------------------------------------------------------------------- */
115IMAGE_EXPORT(int) SaveBMP0_ui8matrix(uint8 **m, int width, int height, RGBQuad *palette_RGBQuad, char *filename)
116    /* --------------------------------------------------------------------------- */
117    /* sauvegarde 'image' au format bmp dans le fichier 'filename' */
118{
119    int rc = 0;
120
121    int v_offset = 0; // no more implemented image->v_offset;
122    int h_offset = 0; // no more implemented image->h_offset;
123    int vmax = height - v_offset;
124    //int hmax = width - h_offset;
125    int height_utile = height - 2*v_offset;
126    int width_utile = width - 2*h_offset;
127    int taille_utile  = height_utile * width_utile;
128
129    //int size;
130    int padding_len;
131
132    BITMAPFILEHEADER Bitmap_File_Header;
133    /*BITMAPINFO;      Bitmap_Info; */
134
135    BITMAPINFOHEADER Bitmap_Info_Header;
136    /*RGBQUAD          RGB_Quad; */
137
138    RGBQUAD palette_RGBQUAD[256]; /* Windows */
139
140    uint8 Padding[3];
141
142    uint8 **data = m;
143    int fd;
144    int  i;
145
146    Padding[0] = 0;
147    Padding[1] = 0;
148    Padding[2] = 0;
149
150    /* --- Header --- */
151    Bitmap_File_Header.bfType      = (WORD) BM;   /* BM                            */
152    Bitmap_File_Header.bfSize      = (DWORD) sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQuad)+taille_utile;    /* taille avec header et palette */
153    Bitmap_File_Header.bfReserved1 = (WORD) 0; /* 0                             */
154    Bitmap_File_Header.bfReserved2 = (WORD) 0; /* 0                             */
155    Bitmap_File_Header.bfOffBits   = (DWORD) sizeof(BITMAPFILEHEADER) +
156        (DWORD) sizeof(BITMAPINFOHEADER) +
157        (DWORD) sizeof(RGBQUAD)*256;   /* */
158
159
160    Bitmap_Info_Header.biSize          = (DWORD) sizeof(BITMAPINFOHEADER);
161    Bitmap_Info_Header.biWidth         = (LONG)  width_utile;  // width sans padding
162    Bitmap_Info_Header.biHeight        = (LONG)  height_utile; // height sans padding
163    Bitmap_Info_Header.biPlanes        = (WORD)  1;            // 1
164    Bitmap_Info_Header.biBitCount      = (WORD)  8;            // 8 en 256 colors
165    Bitmap_Info_Header.biCompression   = (DWORD) BI_RGB;       // BI_RGB
166    Bitmap_Info_Header.biSizeImage     = (DWORD) 0;            // 0 si BI_RGB
167    Bitmap_Info_Header.biXPelsPerMeter = (LONG)  0;            // ???
168    Bitmap_Info_Header.biYPelsPerMeter = (LONG)  0;            // ???
169    Bitmap_Info_Header.biClrUsed       = (DWORD) 256;          // 256
170    Bitmap_Info_Header.biClrImportant  = (DWORD) 0;            // 0
171
172
173    printf("   SaveBMP %s ", filename);
174    printf("[%dx%d] - [%dx%d] = [%dx%d]\n",height,width, v_offset, h_offset, height_utile, width_utile);
175    fd = open(filename, O_CREAT | O_TRUNC);
176    if (fd < 0) {
177        printf("*** Erreur : Ouverture du fichier impossible dans SaveBMP");
178    }
179
180    /* enregistrement de l'image au format bmp */
181    write(fd, &Bitmap_File_Header, sizeof(BITMAPFILEHEADER));
182    /*if(size != sizeof(BITMAPFILEHEADER)) {
183      printf("Bitmap File Header : octets ecrits %d attendus %d\n", size, sizeof(BITMAPFILEHEADER));
184      Error("Erreur d'ecriture du Bitmap File Header");
185      }*/
186    write(fd, &Bitmap_Info_Header, sizeof(BITMAPINFOHEADER));
187    /*if(size != sizeof(BITMAPINFOHEADER) ){
188      printf("Bitmap Info Header : octets ecrits %d attendus %d\n", size, sizeof(BITMAPINFOHEADER));
189      Error("Erreur d'ecriture du Bitmap Info Header");
190      }*/
191
192    Palette_RGBQuad2RGBQUAD(palette_RGBQuad, palette_RGBQUAD);
193    write(fd, palette_RGBQUAD, sizeof(RGBQUAD) * 256);
194    /*if(size != 256*sizeof(RGBQUAD)) {
195      printf("Palette : octets ecrits %d attendus %d\n", size, 256*sizeof(RGBQUAD));
196      Error("Erreur d'ecriture de la palette");
197      }*/
198
199    //for(i=v_offset; i<vmax; i++)/
200
201    /* en 2x car le compilo est trop con ... */
202    padding_len = width_utile % 4;
203    padding_len = (4 - padding_len) % 4;
204
205    for (i = vmax - 1; i >= v_offset; i--) {
206        WriteBMProw(data[i] + h_offset, width_utile, fd);
207        write(fd, Padding, sizeof(byte) * padding_len);
208    }
209    close(fd);
210    return rc;
211
212}
213#endif
214// ------------------------------------------------------------------------------------------------------------
215IMAGE_EXPORT(int) SaveBMP2_ui8matrix(uint8 **m, int width, int height, RGBQuad *palette_RGBQuad, char *filename)
216    // ------------------------------------------------------------------------------------------------------------
217    // sauvegarde 'image' au format bmp dans le fichier 'filename'
218{
219    int taille_utile  = height * width;
220
221    //int size;
222    int padding_len;
223
224    BitmapFileHeader Bitmap_File_Header;
225
226    BitmapInfoHeader Bitmap_Info_Header;
227
228    //RGBQuad palette_RGBQuad[256]; /* Windows */
229
230    byte Padding[3];
231    uint8 rawBFH[14], *ptrBFH; // raw Bitmap File Header
232    uint8 rawBIH[40], *ptrBIH; // raw Bitmap Info Header
233
234    int fd;
235    int  i;
236
237    //#pragma message("BMP warnin' data structure aligment must be 2")
238    //#pragma message("  sizeof( BitmapFileHeader) must = 14, not 16")
239
240    //DEBUG(printf("BMP0 : %d %d\n", sizeof( BITMAPFILEHEADER), sizeof( BITMAPINFOHEADER)));
241    //DEBUG(printf("BMP0_: %d %d\n", sizeof(_BITMAPFILEHEADER), sizeof(_BITMAPINFOHEADER)));
242    //DEBUG(printf("BMP  : %d %d\n", sizeof( BitmapFileHeader), sizeof( BitmapInfoHeader)));
243    if (sizeof(BitmapFileHeader) != 14) {
244        printf("*** Error SaveMBP: sizeof(BitmapFileHeader) = %d should be 14...\n", sizeof(BitmapFileHeader));
245    }
246
247    Padding[0] = 0;
248    Padding[1] = 0;
249    Padding[2] = 0;
250
251    // --- Header ---
252    Bitmap_File_Header.bfType      = (uint16) BM;   //
253    Bitmap_File_Header.bfSize      = (uint32) sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + 256 * sizeof(RGBQuad) + taille_utile;    /* taille avec header et palette */
254    Bitmap_File_Header.bfReserved1 = (uint16) 0; /* 0                             */
255    Bitmap_File_Header.bfReserved2 = (uint16) 0; /* 0                             */
256    Bitmap_File_Header.bfOffBits   = (uint32) sizeof(BitmapFileHeader) + (uint32) sizeof(BitmapInfoHeader) + (uint32) sizeof(RGBQuad) * 256;   /* */
257
258
259    Bitmap_Info_Header.biSize          = (uint32) sizeof(BitmapInfoHeader);
260    Bitmap_Info_Header.biWidth         = (uint32)  width;  // width sans padding
261    Bitmap_Info_Header.biHeight        = (uint32)  height; // height sans padding
262    Bitmap_Info_Header.biPlanes        = (uint16)  1;      // 1
263    Bitmap_Info_Header.biBitCount      = (uint16)  8;      // 8 en 256 colors
264    Bitmap_Info_Header.biCompression   = (uint32) BI_RGB;  // BI_RGB
265    Bitmap_Info_Header.biSizeImage     = (uint32) 0;       // 0 si BI_RGB
266    Bitmap_Info_Header.biXPelsPerMeter = (uint32)  0;      // ???
267    Bitmap_Info_Header.biYPelsPerMeter = (uint32)  0;      // ???
268    Bitmap_Info_Header.biClrUsed       = (uint32) 256;     // 256
269    Bitmap_Info_Header.biClrImportant  = (uint32) 0;       // 0
270
271    ptrBFH = rawBFH;
272    ptrBFH = ui16ArrayAppend(ptrBFH, Bitmap_File_Header.bfType);
273    ptrBFH = ui32ArrayAppend(ptrBFH, Bitmap_File_Header.bfSize);
274    ptrBFH = ui16ArrayAppend(ptrBFH, Bitmap_File_Header.bfReserved1);
275    ptrBFH = ui16ArrayAppend(ptrBFH, Bitmap_File_Header.bfReserved2);
276    ptrBFH = ui32ArrayAppend(ptrBFH, Bitmap_File_Header.bfOffBits);
277
278    ptrBIH = rawBIH;
279    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biSize);
280    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biWidth);
281    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biHeight);
282    ptrBIH = ui16ArrayAppend(ptrBIH, Bitmap_Info_Header.biPlanes);
283    ptrBIH = ui16ArrayAppend(ptrBIH, Bitmap_Info_Header.biBitCount);
284    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biCompression);
285    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biSizeImage);
286    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biXPelsPerMeter);
287    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biYPelsPerMeter);
288    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biClrUsed);
289    ptrBIH = ui32ArrayAppend(ptrBIH, Bitmap_Info_Header.biClrImportant);
290
291    //printf("   SaveBMP %s %dx%d\n", filename, width, height);
292
293    fd = open(filename, O_CREAT | O_TRUNC);
294    if (fd < 0) {
295        printf("*** Erreur : ouverture du fichier '%s' impossible dans SaveBMP", filename);
296    }
297
298    // enregistrement de l'image au format bmp
299    //size = fwrite(&Bitmap_File_Header, sizeof(BitmapFileHeader), 1, file);
300    write(fd, rawBFH, 14);
301    //if(size != sizeof(BITMAPFILEHEADER)) {
302    //  printf("Bitmap File Header : octets ecrits %d attendus %d\n", size, sizeof(BITMAPFILEHEADER));
303    //  Error("Erreur d'ecriture du Bitmap File Header");
304    //}
305
306    //size = fwrite(&Bitmap_Info_Header, sizeof(BitmapInfoHeader), 1, file);
307    write(fd, rawBIH, 40);
308
309    //if(size != sizeof(BITMAPINFOHEADER) ){
310    //  printf("Bitmap Info Header : octets ecrits %d attendus %d\n", size, sizeof(BITMAPINFOHEADER));
311    //  Error("Erreur d'ecriture du Bitmap Info Header");
312    //}
313
314    write(fd, palette_RGBQuad, sizeof(RGBQuad) * 256);
315    //if(size != 256*sizeof(RGBQUAD)) {
316    //  printf("Palette : octets ecrits %d attendus %d\n", size, 256*sizeof(RGBQUAD));
317    //  Error("Erreur d'ecriture de la palette");
318    //}
319
320
321    // en 2x car le compilo est trop con ...
322    padding_len = width % 4;
323    padding_len = (4 - padding_len) % 4;
324
325    for (i = height - 1; i >= 0; i--) {
326        //WriteBMProw(data[i]+h_offset, width_utile, fichier);
327        WriteBMProw(m[i] + 0, width, fd);
328        write(fd, Padding, sizeof(uint8) * padding_len);
329    }
330    close(fd);
331    return 0;
332}
333
Note: See TracBrowser for help on using the repository browser.