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

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