473,770 Members | 1,901 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

working with bitmaps in C

Hello,
Sorry if this is not "exactly" a C topic but I thought this would be
the best place to start. I need some guidance on working with bitmap
images in ANSI C. I need to "read" in a bitmap image, then break it up
into pieces (say 32x32) then take those pieces and "save" them,
granted they do not need to be a readable image, then perform some
other operations on the pieces, and then combine the manipulated
pieces back into one image.

Any suggestions on any part of this would be great! I have found the
"EasyBMP" package from http://easybmp.sourceforge.net but apperas this
is not going to work for what I need.

Thanks!
Dec 23 '07 #1
10 5231
St************* *****@gmail.com said:
Hello,
Sorry if this is not "exactly" a C topic but I thought this would be
the best place to start. I need some guidance on working with bitmap
images in ANSI C.
The first thing you need to know is this: YES, it is possible, in ANSI C.
I need to "read" in a bitmap image, then break it up
into pieces (say 32x32) then take those pieces and "save" them,
granted they do not need to be a readable image, then perform some
other operations on the pieces, and then combine the manipulated
pieces back into one image.
This sounds pretty simple. I would recommend the following procedure:

1) decide on a way of representing an image in memory, that has nothing
whatsoever to do with .bmp format; I use a dynamically allocated array of
unsigned long int *, each of which points to the first element in a
dynamically allocated array of unsigned long int. In other words, I have
one unsigned long int per pixel, with the low 24 bits used for
representing the three colour channels, 8 bits each.

2) now write a bitmap loader, a function that can create an appropriately
sized in-memory representation of a bitmap file. Don't hard-code the image
size for your current task! It might sound like it'll make things simpler,
but actually it'll make them harder. That's because your task actually
involves several different sizes already (original, 32x32, 32xrightmargin,
bottommarginx32 , and rightmarginxbot tommargin).

3) now write a bitmap saver, a function that can create a bitmap file on
disk from an in-memory representation.

4) now write as many graphics functions as you like. On the way, write a
blitter (for copying an image region from an arbitrary part of one image
to an arbitrary part of another).

5) your task itself is now very, very simple - glue together some of the
above, and you're done.

(Although I have never written the program you need, I guess it would take
me about three or four minutes including testing - but only because I've
done all of the above work already.)

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Dec 23 '07 #2

<St************ ******@gmail.co mwrote in message
Sorry if this is not "exactly" a C topic but I thought this would be
the best place to start. I need some guidance on working with bitmap
images in ANSI C. I need to "read" in a bitmap image, then break it up
into pieces (say 32x32) then take those pieces and "save" them,
granted they do not need to be a readable image, then perform some
other operations on the pieces, and then combine the manipulated
pieces back into one image.

Any suggestions on any part of this would be great! I have found the
"EasyBMP" package from http://easybmp.sourceforge.net but apperas this
is not going to work for what I need.

Thanks!
A bit long, but then pixels are getting cheaper these days
(for regs who don't want to read this, it is just an ANSI-standard bitmap
loader /saver).
This is incorporated in my book Basic Algorithms, so any bug reports
particularly welcome.

/*************** *************** *************** ************
* bmp.c - Microsoft bitmap loading functions. *
*************** *************** *************** ************/
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
int width;
int height;
int bits;
int upside_down; /* set for a bottom-up bitmap */
int core; /* set if bitmap is old version */
int palsize; /* number of palette entries */
int compression; /* type of compression in use */
} BMPHEADER;

int bmpgetinfo(char *fname, int *width, int *height);
unsigned char *loadbmp(char *fname, int *width, int *height);
unsigned char *loadbmp8bit(ch ar *fname, int *width, int *height, unsigned
char *pal);
unsigned char *loadbmp4bit(ch ar *fname, int *width, int *height, unsigned
char *pal);

static void loadpalette(FIL E *fp, unsigned char *pal, int entries);
static void loadpalettecore (FILE *fp, unsigned char *pal, int entries);
static void savepalette(FIL E *fp, unsigned char *pal, int entries);
static int loadheader(FILE *fp, BMPHEADER *hdr);
static void saveheader(FILE *fp, int width, int height, int bits);
static void loadraster8(FIL E *fp, unsigned char *data, int width, int
height);
static void loadraster4(FIL E *fp, unsigned char *data, int width, int
height);
static void loadraster1(FIL E *fp, unsigned char *data, int width, int
height);
static long getfilesize(int width, int height, int bits);
static void swap(void *x, void *y, int len);
static void fput32le(long x, FILE *fp);
static void fput16le(int x, FILE *fp);
static long fget32le(FILE *fp);
static int fget16le(FILE *fp);
/*************** *************** *************** ***********
* bmpgetinfo() - get information about a BMP file. *
* Params: fname - name of the .bmp file. *
* width - return pointer for image width. *
* height - return pointer for image height. *
* Returns: bitmap type. *
* 0 - not a valid bitmap. *
* 1 - monochrome paletted (2 entries). *
* 4 - 4-bit paletted. *
* 8 - 8 bit paletted. *
* 16 - 16 bit rgb. *
* 24 - 24 bit rgb. *
* 32 - 24 bit rgb with 1 byte wasted. *
*************** *************** *************** ***********/
int bmpgetinfo(char *fname, int *width, int *height)
{
FILE *fp;
BMPHEADER bmphdr;
fp = fopen(fname, "rb");
if(!fp)
return 0;
if(loadheader(f p, &bmphdr) == -1)
{
fclose(fp);
return 0;
}
fclose(fp);
if(width)
*width = bmphdr.width;
if(height)
*height = bmphdr.height;
return bmphdr.bits;
}

/*************** *************** *************** ***************
* loadbmp() - load any bitmap *
* Params: fname - pointer to file path *
* width - return pointer for image width *
* height - return pointer for image height *
* Returns: malloced pointer to image, 0 on fail *
*************** *************** *************** ***************/
unsigned char *loadbmp(char *fname, int *width, int *height)
{
FILE *fp;
BMPHEADER bmpheader;
unsigned char *answer;
unsigned char *raster;
unsigned char pal[256 * 3];
int index;
int col;
int target;
int i;
int ii;
fp = fopen(fname, "rb");
if(!fp)
return 0;

if(loadheader(f p, &bmpheader) == -1)
{
fclose(fp);
return 0;
}
if(bmpheader.bi ts == 0 || bmpheader.compr ession != 0)
{
fclose(fp);
return 0;
}

answer = malloc(bmpheade r.width * bmpheader.heigh t * 3);
if(!answer)
{
fclose(fp);
return 0;
}

if(bmpheader.bi ts < 16)
{
raster = malloc(bmpheade r.width * bmpheader.heigh t);
if(!raster)
{
free(answer);
return 0;
}
}

switch(bmpheade r.bits)
{
case 1:
if(bmpheader.co re)
loadpalettecore (fp, pal, 2);
else
loadpalette(fp, pal, bmpheader.palsi ze);

loadraster1(fp, raster, bmpheader.width , bmpheader.heigh t);
break;
case 4:
if(bmpheader.co re)
loadpalettecore (fp, pal, 256);
else
loadpalette(fp, pal, bmpheader.palsi ze);

loadraster4(fp, raster, bmpheader.width , bmpheader.heigh t);
break;

case 8:
if(bmpheader.co re)
loadpalettecore (fp, pal, 256);
else
loadpalette(fp, pal, bmpheader.palsi ze);

loadraster8(fp, raster, bmpheader.width , bmpheader.heigh t);
break;

case 16:
for(i=0;i<bmphe ader.height;i++ )
{
for(ii=0;ii<bmp header.width;ii ++)
{
target = (i * bmpheader.width * 3) + ii * 3;
col = fget16le(fp);
answer[target] = (col & 0x001F) << 3;
answer[target+1] = (col & 0x03E0) >2;
answer[target+2] = (col & 0x7A00) >7;
}
while(ii < (bmpheader.widt h + 1)/2 * 4)
{
fgetc(fp);
ii++;
}
}
break;

case 24:
for(i=0;i<bmphe ader.height;i++ )
{
for(ii=0;ii<bmp header.width;ii ++)
{
target = (i * bmpheader.width * 3) + ii * 3;
answer[target] = fgetc(fp);
answer[target+1] = fgetc(fp);
answer[target+2] = fgetc(fp);
}
while(ii < (bmpheader.widt h + 3)/4 * 4)
{
fgetc(fp);
ii++;
}
}
break;

case 32:
for(i=0;i<bmphe ader.height;i++ )
for(ii=0;ii<bmp header.width;ii ++)
{
target = (i * bmpheader.width * 3) + ii * 3;
answer[target] = fgetc(fp);
answer[target+1] = fgetc(fp);
answer[target+2] = fgetc(fp);
fgetc(fp);
}
break;
}

if(bmpheader.bi ts < 16)
{
for(i=0;i<bmphe ader.height;i++ )
for(ii=0;ii<bmp header.width;ii ++)
{
target = (i * bmpheader.width * 3) + ii * 3;
index = raster[i * bmpheader.width + ii] * 3;
answer[target] = pal[ index ];
answer[target+1] = pal[ index + 1 ];
answer[target+2] = pal[ index + 2 ];
}

free(raster);
}

if(bmpheader.up side_down)
{
for(i=0;i<bmphe ader.height/2;i++)
swap( answer + i * bmpheader.width * 3,
answer + (bmpheader.heig ht - i - 1) * bmpheader.width * 3,
bmpheader.width * 3);
}

if(ferror(fp))
{
free(answer);
answer = 0;
}

*width = bmpheader.width ;
*height = bmpheader.heigh t;

fclose(fp);

return answer;
}

/*************** *************** *************** ***************
* loadbmp8bit() - load an 8-bit bitmap. *
* Params: fname - pointer to file path. *
* width - return pointer for image width. *
* height - return pointer for image height. *
* pal - return pointer to 256 rgb palette entries. *
* Returns: malloced pointer to image data, 0 on fail. *
*************** *************** *************** ***************/
unsigned char *loadbmp8bit(ch ar *fname, int *width, int *height, unsigned
char *pal)
{
BMPHEADER bmphdr;
FILE *fp;
unsigned char *answer;
int i;

fp = fopen(fname, "rb");
if(!fp)
return 0;

if(loadheader(f p, &bmphdr) == -1)
{
fclose(fp);
return 0;
}
if(bmphdr.bits != 8)
{
fclose(fp);
return 0;
}
if(bmphdr.compr ession != 0)
{
fclose(fp);
return 0;
}
if(bmphdr.core)
loadpalettecore (fp, pal, 256);
else
loadpalette(fp, pal, bmphdr.palsize) ;
answer = (unsigned char *) malloc(bmphdr.w idth * bmphdr.height);
if(!answer)
{
fclose(fp);
return 0;
}

loadraster8(fp, answer, bmphdr.width, bmphdr.height);
if(bmphdr.upsid e_down)
{
for(i=0;i<bmphd r.height/2;i++)
swap(answer + i * bmphdr.width,
answer + (bmphdr.height - i - 1) * bmphdr.width,
bmphdr.width);
}

if(ferror(fp))
{
free(answer);
answer = 0;
}

fclose(fp);
*width = bmphdr.width;
*height = bmphdr.height;

return answer;
}

/*************** *************** *************** ***************
* loadbmp4bit() - load a 4-bit bitmap from disk. *
* Params: fname - pointer to the file path. *
* width - return pointer for image width. *
* height - return pointer for image height. *
* pal - return pointer for 16 rgb palette entries. *
* Returns: malloced pointer to 4-bit image data. *
*************** *************** *************** ***************/
unsigned char *loadbmp4bit(ch ar *fname, int *width, int *height, unsigned
char *pal)
{
BMPHEADER bmphdr;
FILE *fp;
unsigned char *answer;
int i;

fp = fopen(fname, "rb");
if(!fp)
return 0;

if(loadheader(f p, &bmphdr) == -1)
{
fclose(fp);
return 0;
}
if(bmphdr.bits != 4)
{
fclose(fp);
return 0;
}
if(bmphdr.compr ession != 0)
{
fclose(fp);
return 0;
}

if(bmphdr.core)
loadpalettecore (fp, pal, 16);
else
loadpalette(fp, pal, bmphdr.palsize) ;
answer = (unsigned char *) malloc(bmphdr.w idth * bmphdr.height);
if(!answer)
{
fclose(fp);
return 0;
}
loadraster4(fp, answer, bmphdr.width, bmphdr.height);

if(bmphdr.upsid e_down)
{
for(i=0;i<bmphd r.height/2;i++)
{
swap(answer + i * bmphdr.width,
answer + (bmphdr.height - i - 1) * bmphdr.width,
bmphdr.width);
}
}

if(ferror(fp))
{
free(answer);
answer = 0;
}

fclose(fp);
*width = bmphdr.width;
*height = bmphdr.height;
return answer;
}

/*************** *************** *************** **************
* save a24-bit bmp file. *
* Params: fname - name of file to save. *
* rgb - raster data in rgb format *
* width - image width *
* height - image height *
* Returns: 0 on success, -1 on fail *
*************** *************** *************** **************/
int savebmp(char *fname, unsigned char *rgb, int width, int height)
{
FILE *fp;
int i;
int ii;

fp = fopen(fname, "wb");
if(!fp)
return -1;

saveheader(fp, width, height, 24);
for(i=0;i<heigh t;i++)
{
for(ii=0;ii<wid th;ii++)
{
fputc(rgb[2], fp);
fputc(rgb[1], fp);
fputc(rgb[0], fp);
rgb += 3;
}
if(( width * 3) % 4)
{
for(ii=0;ii< 4 - ( (width * 3) % 4); ii++)
{
fputc(0, fp);
}
}
}

if(ferror(fp))
{
fclose(fp);
return -1;
}

return fclose(fp);
}

/*************** *************** *************** *************
* save an 8-bit palettised bitmap . *
* Params: fname - the name of the file. *
* data - the raster data *
* width - image width *
* height - image height *
* pal - palette (RGB format) *
* Returns: 0 on success, -1 on failure *
*************** *************** *************** *************/
int savebmp8bit(cha r *fname, unsigned char *data, int width, int height,
unsigned char *pal)
{
FILE *fp;
int i;
int ii;

fp = fopen(fname, "wb");
if(!fp)
return -1;

saveheader(fp, width, height, 8);
savepalette(fp, pal, 256);

for(i=0;i<heigh t;i++)
for(ii=0;ii< (width + 3)/4;ii++)
{
fputc(data[i*width + ii * 4], fp);
if(ii * 4 + 1 < width)
fputc(data[i*width + ii * 4 + 1], fp);
else
fputc(0, fp);
if(ii * 4 + 2 < width)
fputc(data[i*width + ii * 4 + 2], fp);
else
fputc(0, fp);
if(ii * 4 + 3 < width)
fputc(data[i*width + ii * 4 + 3], fp);
else
fputc(0, fp);
}

if(ferror(fp))
{
fclose(fp);
return -1;
}

return fclose(fp);
}

/*************** *************** *************** **********
* save a 4-bit palettised bitmap. *
* Params: fname - the name of the file. *
* data - raster data *
* width - image width *
* height - image height *
* pal - the palette (RGB format) *
* Returns: 0 on success, -1 on failure *
*************** *************** *************** **********/
int savebmp4bit(cha r *fname, unsigned char *data, int width, int height,
unsigned char *pal)
{
FILE *fp;
int i;
int ii;
int pix;

fp = fopen(fname, "wb");
if(!fp)
return -1;

saveheader(fp, width, height, 4);
savepalette(fp, pal, 16);

for(i=0;i<heigh t;i++)
for(ii=0;ii< (width + 7)/8;ii++)
{
pix = data[i * width + ii * 8] << 4;
if(ii * 8 + 1 < width)
pix |= data[i * width + ii * 8 + 1];
fputc(pix, fp);

pix = 0;
if(ii * 8 + 2 < width)
pix = data[ i * width + ii * 8 + 2] << 4;
if(ii * 8 + 3 < width)
pix |= data[ i * width + ii * 8 + 3];
fputc(pix, fp);

pix = 0;
if(ii * 8 + 4 < width)
pix = data[ i * width + ii * 8 + 4] << 4;
if(ii * 8 + 5 < width)
pix |= data[i * width + ii * 8 + 5];
fputc(pix, fp);

pix = 0;
if(ii * 8 + 6 < width)
pix = data[ i * width + ii * 8 + 6] << 4;
if(ii * 8 + 7 < width)
pix |= data[i * width + ii * 8 + 7];
fputc(pix, fp);
}

if(ferror(fp))
{
fclose(fp);
return -1;
}

return fclose(fp);
}

/*************** *************** *************** *************** ***
* save a 2-bit palettised bitmap. *
* Params: fname - name of file to write. *
* data - raster data, one byte per pixel. *
* width - image width. *
* height - image height. *
* pal - the palette (0 = black/white) *
* Returns: 0 on success, -1 on fail. *
*************** *************** *************** *************** ***/
int savebmp2bit(cha r *fname, unsigned char *data, int width, int height,
unsigned char *pal)
{
FILE *fp;
unsigned char defpal[6] = {0, 0, 0, 255, 255, 255 };
int i;
int ii;
int iii;
int pix;

fp = fopen(fname, "wb");
if(!fp)
return -1;

saveheader(fp, width, height, 1);
if(pal)
savepalette(fp, pal, 2);
else
savepalette(fp, defpal, 2);

for(i=0;i<heigh t;i++)
for(ii=0;ii<wid th;ii+=32)
{
pix = 0;
for(iii=0;iii<8 ;iii++)
if(ii + iii < width)
pix |= data[i * width + ii + iii] ? (1 << (7-iii) ) : 0;
fputc(pix, fp);

pix = 0;
for(iii=0;iii<8 ;iii++)
if(ii + iii + 8 < width)
pix |= data[i * width + ii + iii + 8] ? (1 << (7 - iii)) : 0;
fputc(pix, fp);

pix = 0;
for(iii=0;iii<8 ;iii++)
if(ii + iii + 16 < width)
pix |= data[i * width + ii + iii + 16] ? (1 << (7 - iii)) : 0;
fputc(pix, fp);

pix = 0;
for(iii=0;iii<8 ;iii++)
if(ii + iii + 24 < width)
pix |= data[i * width + ii + iii + 24] ? (1 << (7 - iii)) : 0;

fputc(pix, fp);
}

if(ferror(fp))
{
fclose(fp);
return -1;
}

return fclose(fp);
}

/*************** *************** *************** *************** **
* loadpalette() - load palette for a new format BMP. *
* Params: fp - pointer to an open file. *
* pal - return pointer for palette entries. *
* entries - number of entries in palette. *
*************** *************** *************** *************** **/
static void loadpalette(FIL E *fp, unsigned char *pal, int entries)
{
int i;
for(i=0;i<entri es;i++)
{
pal[2] = fgetc(fp);
pal[1] = fgetc(fp);
pal[0] = fgetc(fp);
fgetc(fp);
pal += 3;
}
}

/*************** *************** *************** *********
* loadpalettecore () - load a palette for a core BMP *
* Params: fp - pointer to an open file. *
* pal - return pointer for palette entries. *
* entries - number of entries to read. *
*************** *************** *************** *********/
static void loadpalettecore (FILE *fp, unsigned char *pal, int entries)
{
int i;
for(i=0;i<entri es;i++)
{
pal[2] = fgetc(fp);
pal[1] = fgetc(fp);
pal[0] = fgetc(fp);
pal += 3;
}
}

/*************** *************** *************** *************** *
* saves a palette *
* Params: fp - pointer to an open file *
* pal - the palette *
* entries - number of palette entries. *
*************** *************** *************** *************** */
static void savepalette(FIL E *fp, unsigned char *pal, int entries)
{
int i;

for(i=0;i<entri es;i++)
{
fputc(pal[2], fp);
fputc(pal[1], fp);
fputc(pal[0], fp);
fputc(0, fp);
pal += 3;
}
}

/*
typedef struct tagBITMAPFILEHE ADER { // bmfh
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADE R;

typedef struct tagBITMAPINFOHE ADER{ // bmih
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter ;
LONG biYPelsPerMeter ;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADE R;

*/

/*************** *************** *************** *********
* loadheader() - load the bitmap header information. *
* Params: fp - pinter to an opened file. *
* hdr - return pointer for header information.*
* Returns: 0 on success, -1 on fail. *
*************** *************** *************** *********/
static int loadheader(FILE *fp, BMPHEADER *hdr)
{
int size;
int hdrsize;
int id;
int i;

id = fget16le(fp);
/* is it genuinely a BMP ? */
if(id != 0x4D42)
return -1;
/* skip rubbish */
fget32le(fp);
fget16le(fp);
fget16le(fp);
/* offset to bitmap bits */
size = fget32le(fp);
hdrsize = fget32le(fp);
if(hdrsize == 40)
{
hdr->width = fget32le(fp);
hdr->height = fget32le(fp);
fget16le(fp);
hdr->bits = fget16le(fp);
hdr->compression = fget32le(fp);
/* skip rubbish */
for(i=0;i<12;i+ +)
fgetc(fp);
hdr->palsize = fget32le(fp);
if(hdr->palsize == 0 && hdr->bits < 16)
hdr->palsize = 1 << hdr->bits;
fget32le(fp);
if(hdr->height < 0)
{
hdr->upside_down = 0;
hdr->height = -hdr->height;
}
else
hdr->upside_down = 1;
hdr->core = 0;
}
else if(hdrsize == 12)
{
hdr->width = fget16le(fp);
hdr->height = fget16le(fp);
fget16le(fp);
hdr->bits = fget16le(fp);
hdr->compression = 0;
hdr->upside_down = 1;
hdr->core = 1;
hdr->palsize = 1 << hdr->bits;
}
else
return 0;
if(ferror(fp))
return -1;
return 0;
}

/*************** *************** *************** *************** ****
* write a bitmap header. *
* Params: fp - pointer to an open file. *
* width - bitmap width *
* height - bitmap height *
* bit - bit depth (1, 4, 8, 16, 24, 32) *
*************** *************** *************** *************** ****/
static void saveheader(FILE *fp, int width, int height, int bits)
{
long sz;
long offset;

/* the file header */
/* "BM" */
fputc(0x42, fp);
fputc(0x4D, fp);

/* file size */
sz = getfilesize(wid th, height, bits) + 40 + 14;
fput32le(sz, fp);

/* reserved */
fput16le(0, fp);
fput16le(0, fp);
/* offset of raster data from header */
if(bits < 16)
offset = 40 + 14 + 4 * (1 << bits);
else
offset = 40 + 14;
fput32le(offset , fp);

/* the infoheader */

/* size of structure */
fput32le(40, fp);
fput32le(width, fp);
/* height negative because top-down */
fput32le(-height, fp);
/* bit planes */
fput16le(1, fp);
fput16le(bits, fp);
/* compression */
fput32le(0, fp);
/* size of image (can be zero) */
fput32le(0, fp);
/* pels per metre */
fput32le(600000 , fp);
fput32le(600000 , fp);
/* colours used */
fput32le(0, fp);
/* colours important */
fput32le(0, fp);
}

/*************** *************** *************** *************** *********
* load 8-bit raster data *
* Params: fp - pointer to an open file. *
* data - return pointer for data (one byte per pixel) *
* width - image width *
* height - image height *
*************** *************** *************** *************** *********/
static void loadraster8(FIL E *fp, unsigned char *data, int width, int
height)
{
int linewidth;
int i;
int ii;

linewidth = (width + 3)/4 * 4;

for(i=0;i<heigh t;i++)
{
for(ii=0;ii<wid th;ii++)
*data++ = fgetc(fp);
while(ii < linewidth)
{
fgetc(fp);
ii++;
}
}
}

/*************** *************** *************** *************** **********
* load 4-bit raster data *
* Params: fp - pointer to an open file. *
* data - return pointer for data (one byte per pixel) *
* width - image width *
* height - iamge height *
*************** *************** *************** *************** **********/
static void loadraster4(FIL E *fp, unsigned char *data, int width, int
height)
{
int linewidth;
int i;
int ii;
int pix;

linewidth = (((width + 1)/2) + 3)/4 * 4;

for(i=0;i<heigh t;i++)
{
for(ii=0;ii<lin ewidth;ii++)
{
pix = fgetc(fp);
if(ii * 2 < width)
*data++ = pix >4;
if(ii * 2 + 1 < width)
*data++ = pix & 0x0F;
}
}
}

/*************** *************** *************** *************** *******
* load 1 bit raster data *
* Params: fp - pointer to an open file. *
* data - return pointer for data (one byte per pixel) *
* width - image width. *
* height - image height. *
*************** *************** *************** *************** *******/
static void loadraster1(FIL E *fp, unsigned char *data, int width, int
height)
{
int linewidth;
int i;
int ii;
int iii;
int pix;

linewidth = ((width + 7)/8 + 3)/4 * 4;

for(i=0;i<heigh t;i++)
{
for(ii=0;ii<lin ewidth;ii++)
{
pix = fgetc(fp);
if(ii * 8 < width)
{
for(iii=0;iii<8 ;iii++)
if(ii * 8 + iii < width)
*data++ = (pix & (1 << (7 - iii))) ? 1 : 0;
}
}
}

}

/*************** *************** *************** ********
* get the size of the file to be written. *
* Params: width - image width *
* height - image height *
* bits - image type *
* Returns: size of image data (excluding headers) *
*************** *************** *************** ********/
static long getfilesize(int width, int height, int bits)
{
long answer = 0;
switch(bits)
{
case 1:
answer = (width + 7)/8;
answer = (answer + 3)/4 * 4;
answer *= height;
answer += 2 * 4;
break;
case 4:
answer = 16 * 4 + (width + 1)/2;
answer = (answer + 3)/4 * 4;
answer *= height;
answer += 16 * 4;
break;
case 8:
answer = (width + 3)/4 * 4;
answer *= height;
answer += 256 * 4;
break;
case 16:
answer = (width * 2 + 3)/4 * 4;
answer *= height;
break;
case 24:
answer = (width * 3 + 3)/4 * 4;
answer *= height;
break;
case 32:
answer = width * height * 4;
break;
default:
return 0;
}

return answer;
}

/*************** *************** *************** *************** ***
* swap an area of memory *
* Params: x - pointer to first buffer *
* y - pointer to second buffer *
* len - length of memory to swap *
*************** *************** *************** *************** ***/
static void swap(void *x, void *y, int len)
{
unsigned char *ptr1 = x;
unsigned char *ptr2 = y;
unsigned char temp;
int i;

for(i=0;i<len;i ++)
{
temp = ptr1[i];
ptr1[i] = ptr2[i];
ptr2[i] = temp;
}
}

/*************** *************** *************** *************** ***
* write a 32-bit little-endian number to a file. *
* Params: x - the number to write *
* fp - pointer to an open file. *
*************** *************** *************** *************** ***/
static void fput32le(long x, FILE *fp)
{
fputc(x & 0xFF, fp);
fputc( (x >8) & 0xFF, fp);
fputc( (x >16) & 0xFF, fp);
fputc( (x >24) & 0xFF, fp);
}

/*************** *************** *************** *************** ***
* write a 16-bit little-endian number to a file. *
* Params: x - the nmuber to write *
* fp - pointer to an open file *
*************** *************** *************** *************** ***/
static void fput16le(int x, FILE *fp)
{
fputc(x & 0xFF, fp);
fputc( (x >8) & 0xFF, fp);
}

/*************** *************** *************** *************** ***
* fget32le() - read a 32 bit little-endian number from a file. *
* Params: fp - pointer to an open file. *
* Returns: value read as a signed integer. *
*************** *************** *************** *************** ***/
static long fget32le(FILE *fp)
{
long answer;
answer = fgetc(fp);
answer |= (fgetc(fp) << 8);
answer |= (fgetc(fp) << 16);
answer |= (fgetc(fp) << 24);
/* check for negative */
if(answer & 0x80000000)
answer |= ((-1) << 31);
return answer;
}

/*************** *************** *************** *************** ***
* fget16le() - read a 16 bit little-endian number from a file. *
* Params: fp - pointer to an open file. *
* Returns: value read as a signed integer. *
*************** *************** *************** *************** ***/
static int fget16le(FILE *fp)
{
int answer;
answer = fgetc(fp);
answer |= (fgetc(fp) << 8);
/* check for negative */
if(answer & 0x8000)
answer |= ((-1) << 16);
return answer;
}
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Dec 23 '07 #3

<St************ ******@gmail.co mwrote in message
news:0d******** *************** ***********@q77 g2000hsh.google groups.com...
Hello,
Sorry if this is not "exactly" a C topic but I thought this would be
the best place to start. I need some guidance on working with bitmap
images in ANSI C. I need to "read" in a bitmap image, then break it up
into pieces (say 32x32) then take those pieces and "save" them,
granted they do not need to be a readable image, then perform some
other operations on the pieces, and then combine the manipulated
pieces back into one image.

Any suggestions on any part of this would be great! I have found the
"EasyBMP" package from http://easybmp.sourceforge.net but apperas this
is not going to work for what I need.

Thanks!
Here is some dodgy code I found
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned char CHAR;
// Bitmap file header
typedef struct tagBITMAPINFOHE ADER
{
WORD bfType; //specifies the file type
DWORD bfSize; //specifies the size in bytes of the bitmap file
WORD bfReserved1; //reserved; must be 0
WORD bfReserved2; //reserved; must be 0
DWORD bOffBits; //species the offset in bytes from the bitmapfileheade r to
the bitmap bits
DWORD biSize; //specifies the number of bytes required by the struct
DWORD biWidth; //specifies width in pixels
DWORD biHeight; //species height in pixels
WORD biPlanes; //specifies the number of color planes, must be 1
WORD biBitCount; //specifies the number of bit per pixel
DWORD biCompression;//spcifies the type of compression
DWORD biSizeImage; //size of image in bytes
DWORD biXPelsPerMeter ; //number of pixels per meter in x axis
DWORD biYPelsPerMeter ; //number of pixels per meter in y axis
DWORD biClrUsed; //number of colors used by th ebitmap
DWORD biClrImportant; //number of colors that are important
} BITMAPINFOHEADE R;

// Saves picture data to a bitmap file
unsigned char *SaveBitmapFile (char *filename, BITMAPINFOHEADE R
*bitmapInfoHead er, unsigned char *bitmapImage)
{
FILE *filePtr;
unsigned int imageIdx=0;
CHAR tempRGB;

//open file in write mode
filePtr = fopen(filename, "wb");
if (filePtr == NULL)
return NULL;

//save the bitmap file header
fwrite(&(bitmap InfoHeader->bfType),
sizeof(bitmapIn foHeader->bfType),1,file Ptr);
fwrite(&(bitmap InfoHeader->bfSize),
sizeof(bitmapIn foHeader->bfSize),1,file Ptr);
fwrite(&(bitmap InfoHeader->bfReserved1) ,
sizeof(bitmapIn foHeader->bfReserved1),1 ,filePtr);
fwrite(&(bitmap InfoHeader->bfReserved2) ,
sizeof(bitmapIn foHeader->bfReserved2),1 ,filePtr);
fwrite(&(bitmap InfoHeader->bOffBits),
sizeof(bitmapIn foHeader->bOffBits),1,fi lePtr);

//write info header
fwrite(&(bitmap InfoHeader->biSize),
sizeof(bitmapIn foHeader->biSize),1,file Ptr);
fwrite(&(bitmap InfoHeader->biWidth),
sizeof(bitmapIn foHeader->biWidth),1,fil ePtr);
fwrite(&(bitmap InfoHeader->biHeight),
sizeof(bitmapIn foHeader->biHeight),1,fi lePtr);
fwrite(&(bitmap InfoHeader->biPlanes),
sizeof(bitmapIn foHeader->biPlanes),1,fi lePtr);
fwrite(&(bitmap InfoHeader->biBitCount),
sizeof(bitmapIn foHeader->biBitCount),1, filePtr);
fwrite(&(bitmap InfoHeader->biCompression) ,
sizeof(bitmapIn foHeader->biCompression) ,1,filePtr);
fwrite(&(bitmap InfoHeader->biSizeImage) ,
sizeof(bitmapIn foHeader->biSizeImage),1 ,filePtr);
fwrite(&(bitmap InfoHeader->biXPelsPerMete r),
sizeof(bitmapIn foHeader->biXPelsPerMete r),1,filePtr);
fwrite(&(bitmap InfoHeader->biYPelsPerMete r),
sizeof(bitmapIn foHeader->biYPelsPerMete r),1,filePtr);
fwrite(&(bitmap InfoHeader->biClrUsed),
sizeof(bitmapIn foHeader->biClrUsed),1,f ilePtr);
fwrite(&(bitmap InfoHeader->biClrImportant ),
sizeof(bitmapIn foHeader->biClrImportant ),1,filePtr);

//swap the r and b values to get RGB (bitmap is BGR)
for (imageIdx = 0;imageIdx < bitmapInfoHeade r->biSizeImage;im ageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}

//write bitmap image values
fwrite(bitmapIm age,sizeof(CHAR ),bitmapInfoHea der->biSizeImage,fi lePtr);

//swap the r and b values to get RGB (bitmap is BGR)
for (imageIdx = 0;imageIdx < bitmapInfoHeade r->biSizeImage;im ageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
fclose(filePtr) ;

return 0;
}

// Loads picture data from a bitmap file
unsigned char *LoadBitmapFile (char *filename, BITMAPINFOHEADE R
*bitmapInfoHead er)
{
FILE *filePtr; //our file pointer
CHAR *bitmapImage; //store image data
unsigned int imageIdx=0; //image index counter
CHAR tempRGB; //our swap variable

//open filename in read binary mode
filePtr = fopen(filename, "rb");
if (filePtr == NULL)
return NULL;

//read the bitmap file header
//fread(&bitmapFi leHeader, sizeof(BITMAPFI LEHEADER),1,fil ePtr);
fread(&bitmapIn foHeader->bfType,
sizeof(bitmapIn foHeader->bfType),1,file Ptr);
fread(&bitmapIn foHeader->bfSize,
sizeof(bitmapIn foHeader->bfSize),1,file Ptr);
fread(&bitmapIn foHeader->bfReserved1,
sizeof(bitmapIn foHeader->bfReserved1),1 ,filePtr);
fread(&bitmapIn foHeader->bfReserved2,
sizeof(bitmapIn foHeader->bfReserved2),1 ,filePtr);
fread(&bitmapIn foHeader->bOffBits,
sizeof(bitmapIn foHeader->bOffBits),1,fi lePtr);

//read the bitmap info header
//fread(bitmapInf oHeader, sizeof(BITMAPIN FOHEADER),1,fil ePtr);
fread(&bitmapIn foHeader->biSize,
sizeof(bitmapIn foHeader->biSize),1,file Ptr);
fread(&bitmapIn foHeader->biWidth,
sizeof(bitmapIn foHeader->biWidth),1,fil ePtr);
fread(&bitmapIn foHeader->biHeight,
sizeof(bitmapIn foHeader->biHeight),1,fi lePtr);
fread(&bitmapIn foHeader->biPlanes,
sizeof(bitmapIn foHeader->biPlanes),1,fi lePtr);
fread(&bitmapIn foHeader->biBitCount,
sizeof(bitmapIn foHeader->biBitCount),1, filePtr);
fread(&bitmapIn foHeader->biCompressio n,
sizeof(bitmapIn foHeader->biCompression) ,1,filePtr);
fread(&bitmapIn foHeader->biSizeImage,
sizeof(bitmapIn foHeader->biSizeImage),1 ,filePtr);
fread(&bitmapIn foHeader->biXPelsPerMete r,
sizeof(bitmapIn foHeader->biXPelsPerMete r),1,filePtr);
fread(&bitmapIn foHeader->biYPelsPerMete r,
sizeof(bitmapIn foHeader->biYPelsPerMete r),1,filePtr);
fread(&bitmapIn foHeader->biClrUsed,
sizeof(bitmapIn foHeader->biClrUsed),1,f ilePtr);
fread(&bitmapIn foHeader->biClrImportant ,
sizeof(bitmapIn foHeader->biClrImportant ),1,filePtr);

//verify that this is a bmp file by check bitmap id
if (bitmapInfoHead er->bfType !=0x4D42)
{
fclose(filePtr) ;
return NULL;
}

//move file point to the begging of bitmap data
fseek(filePtr, bitmapInfoHeade r->bOffBits, SEEK_SET);

//allocate enough memory for the bitmap image data
bitmapImage = (CHAR*)malloc(b itmapInfoHeader->biSizeImage) ;

//verify memory allocation
if (!bitmapImage)
{
free(bitmapImag e);
fclose(filePtr) ;
return NULL;
}

//read in the bitmap image data
fread(bitmapIma ge,sizeof(CHAR) ,bitmapInfoHead er->biSizeImage,fi lePtr);

//make sure bitmap image data was read
if (bitmapImage == NULL)
{
fclose(filePtr) ;
return NULL;
}

//swap the r and b values to get RGB (bitmap is BGR)
for (imageIdx = 0;imageIdx < bitmapInfoHeade r->biSizeImage;im ageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}

//close file and return bitmap iamge data
fclose(filePtr) ;
return bitmapImage;
}

Dec 23 '07 #4

"Malcolm McLean" <re*******@btin ternet.comwrote in message
news:Qv******** *************** *******@bt.com. ..
>
<St************ ******@gmail.co mwrote in message
....
>the best place to start. I need some guidance on working with bitmap
images in ANSI C. I need to "read" in a bitmap image, then break it up
into pieces (say 32x32) then take those pieces and "save" them,
....
A bit long, but then pixels are getting cheaper these days
(for regs who don't want to read this, it is just an ANSI-standard bitmap
loader /saver).
This is incorporated in my book Basic Algorithms, so any bug reports
particularly welcome.
* loadbmp() - load any bitmap *
....
unsigned char *loadbmp(char *fname, int *width, int *height)
....
answer = malloc(bmpheade r.width * bmpheader.heigh t * 3);
Don't know if this is actually wrong, but: assumes here 24 bits per pixel?
Even though it loads any size? So smaller pixel bitmaps are expanded to 24?
That's why this function doesn't return the pixel size?

Also this allows an odd number of bytes per row although I seem to remember
BMP was padded to 4n bytes per row, so the code presumably compresses the
image by eliminating the padding?

In other words, this function loads any BMP file and returns a pointer to a
string of 3-byte/24-bit pixels in a 'raw' format different from that stored
in the file?

Bart

Dec 23 '07 #5
"Bart C" <bc@freeuk.comw rote in message
"Malcolm McLean" <re*******@btin ternet.comwrote in message
news:Qv******** *************** *******@bt.com. ..
>>
<St*********** *******@gmail.c omwrote in message
...
>>the best place to start. I need some guidance on working with bitmap
images in ANSI C. I need to "read" in a bitmap image, then break it up
into pieces (say 32x32) then take those pieces and "save" them,
...
>A bit long, but then pixels are getting cheaper these days
(for regs who don't want to read this, it is just an ANSI-standard bitmap
loader /saver).
This is incorporated in my book Basic Algorithms, so any bug reports
particularly welcome.
>* loadbmp() - load any bitmap *
...
>unsigned char *loadbmp(char *fname, int *width, int *height)
...
> answer = malloc(bmpheade r.width * bmpheader.heigh t * 3);

Don't know if this is actually wrong, but: assumes here 24 bits per pixel?
Even though it loads any size? So smaller pixel bitmaps are expanded to
24? That's why this function doesn't return the pixel size?
That's right. If you want the palette and index values for some reason call
getbitmapinfo() to ensure the file is of the right type, then call
loadbmp8bit / 4 bit.
>
Also this allows an odd number of bytes per row although I seem to
remember BMP was padded to 4n bytes per row, so the code presumably
compresses the image by eliminating the padding?

In other words, this function loads any BMP file and returns a pointer to
a string of 3-byte/24-bit pixels in a 'raw' format different from that
stored in the file?
Yes. The padding is now a quirk of the file format. Originally the idea was
that a slow PC could save a few cycles by loading the image directly into
memory, and then from memory straight to VDU memory. Nowadays that is
unlikely to matter, and probably slows it down as much as it speeds it up.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Dec 24 '07 #6

"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
Malcolm McLean wrote, On 27/12/07 17:16:
Actually, the best thing is normally to start off by checking the length
is within a valid range, then check the data is valid, then check that you
hit a valid tag in the place expected. If any of those things fail you
report the file as being corrupt or a format you can't handle.
The object of the exercise is to read the data, not to check the file for
adherence to the format.
>
>That's a good point. It should be returning -1 instead of zero on an
unrecognised header size, at least. Probably we should try to read it as
a 40. However to do a really good job we've got to skip to the raster
bits, which means a total rewrite and lots of complications.

Don't advertise your code as being reliable then, advertise it as
supporting some but not all BMP files.
The question is what to do with as yet unspecified versions. Presumably MS
will extend the header field, maybe add new chunks. The question is whether
the raster data will still be readable without the new information, and it
is impossible for MS to guarantee that, because they won't change the format
for fun, but because some need arises.
I should be able to read every current format, barring bugs, but some are
obsolete.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Dec 27 '07 #7
Malcolm McLean wrote, On 27/12/07 23:38:
>
"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
>Malcolm McLean wrote, On 27/12/07 17:16:
Actually, the best thing is normally to start off by checking the
length is within a valid range, then check the data is valid, then
check that you hit a valid tag in the place expected. If any of those
things fail you report the file as being corrupt or a format you can't
handle.
The object of the exercise is to read the data, not to check the file
for adherence to the format.
OK, so I know not to rely on any code you write for reading files. This
is because you can only reliably read data if you validate that it is in
the format that it is meant to be in. Also you were the person who
raised the problem of corrupted files, I just advised you on what works
better in real situations where you do have data corruption to deal with.
>>That's a good point. It should be returning -1 instead of zero on an
unrecognise d header size, at least. Probably we should try to read it
as a 40. However to do a really good job we've got to skip to the
raster bits, which means a total rewrite and lots of complications.

Don't advertise your code as being reliable then, advertise it as
supporting some but not all BMP files.
The question is what to do with as yet unspecified versions. Presumably
MS will extend the header field, maybe add new chunks. The question is
whether the raster data will still be readable without the new
information, and it is impossible for MS to guarantee that, because they
won't change the format for fun, but because some need arises.
I should be able to read every current format, barring bugs, but some
are obsolete.
You are saying this having just had OS/2 BMPs reported as a possible
problem (in text you snipped) and having admitted to not even testing on
all the formats that MS support. Ernie raised forward compatibility as
an additional problem.
--
Flash Gordon
Dec 28 '07 #8
Flash Gordon wrote:
Malcolm McLean wrote, On 27/12/07 17:16:
>"Ernie Wright" <er****@comcast .netwrote
>>>
The specification claims that 4-bit old-style BMP has a 16-color
palette. It's been so long since I've encountered one of these
that I wouldn't know where to look for one now. Unless you know of
users that actually have to deal with these (they haven't been
written by Microsoft code since Windows 2.x), I'd be tempted to
strip all of that cruft out of your loader.

The version of Paint in Windows Vista claims to be able to save a 16
colour bitmap. I've no idea if the format is the same, but I see no
reason why it would not be.
It's not. Old-style BMP, what Malcolm's code calls "core" BMP, is an
obsolete form of BMP with a different header. This older form was used
by Windows 1.x and 2.x and OS/2 1.x.

- Ernie http://home.comcast.net/~erniew
Dec 28 '07 #9
Malcolm McLean wrote:
The object of the exercise is to read the data, not to check the file
for adherence to the format.
You have to verify that you're reading a format you understand! If at
any point the file deviates from what you expect, the only *safe* thing
to conclude is that it's not in a format you can handle.
The question is what to do with as yet unspecified versions. Presumably
MS will extend the header field, maybe add new chunks.
They already have. A long time ago, in fact. Google BITMAPV4HEADER
and BITMAPV5HEADER.

It's unlikely you'll see these in files, since they're primarily meant
to enhance aspects of the internal representation of bitmaps in Windows.

But the point is, the right thing to do with variants you don't know
about, which by definition includes future versions, is recognize that
you don't know what they contain, and fail gracefully.

- Ernie http://home.comcast.net/~erniew
Dec 28 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
2222
by: Brad Smalling | last post by:
Does anyone know if there is a reason to prefer bitmaps over icons (or vice-versa) when populating image lists? I've always favored icons because of their built-in transparency (although I've never use the invert "color"). But I've noticed that Microsoft seems to favor bitmaps in many of their sample applications. Is there a reason? For instance, do icons clutter the icon cache or require more system resources whereas bitmaps do not? ...
13
2540
by: Jeff Melvaine | last post by:
I note that I can write expressions like "1 << 100" and the result is stored as a long integer, which means it is stored as an integer of arbitrary length. I may need to use a large number of these, and am interested to know whether the storage efficiency of long integers is in danger of breaking my code if I use too many. Would I do better to write a class that defines bitwise operations on arrays of integers, each integer being assumed...
1
2384
by: Mark Evans | last post by:
I have a dialog box and on it I want to display a bitmap, which will change at various times during the program. My problem is that the bitmaps will not be the same each time. I want the user to put their own bitmaps into a directory and the application will pick them off and display them as required. The bitmaps will always be called the same thing, ie 1.bmp, 2.bmp, 3.bmp - but they will be different pictures. I am new to visual...
4
1675
by: Nathan | last post by:
Hello, I'm needing some advice: I have an app for which I've built a timer out of multiple bitmaps--a clock with a moving hands. I've saved each hand position (1 second, 2 seconds, etc.) as a separate bitmap, and I make the clock "tic" down by changing the image of a picture box. The problem, of course, is that the application uses tons of memory, because each of the bitmaps is preloaded into an array. Is there an easier way to do...
1
2239
by: John | last post by:
I have 76 bitmaps (640 x 480) and need to combine them together to form a big one (about 3840 x 2880). Those 76 bitmaps overlap each other with a small portion. Is there any way to do it? Thanks.
1
2582
by: Peter Stojkovic | last post by:
What is the correct way to move BITMAPS and drawings inside a windows-forms from one project to another project. The problem is the following row: Dim resources As System.Resources.ResourceManager = New System.Resources.ResourceManager(GetType(frm_ageing_state1)) Where are the bitmaps located ?
2
2076
by: Mike | last post by:
Hello everybody. I am drawing a country map that consists of 149 municipality bitmaps, each around 25 Kb. I draw it onto the in-memory bitmap, then draw it on the picture box. I use C++, but anyways if I were using the C# the question would be the same. And here is the problem: it takes 700 ms to draw it, and anything above 300 ms is noticable by the human eye. So, is there any technique that I could use to actually keep the bitmaps in...
1
8346
by: =?Utf-8?B?Sm9obg==?= | last post by:
Hi, I need to combine several bitmaps together to form a single bitmap. Can anyone show me some similar sample code? Thanks. AJ
1
2731
by: nkumarin001 | last post by:
Hi, Can anyone help me in this matter:- When i was studying locally managed tablespaces i came across bitmaps that are used in locally managed tablespaces it stated that:- "Locally managed tablespaces use bitmaps stored within the header of the datafiles comprising a tablespace to track the space utilization of the tablespaces." AND When i was studying some other topics i came across...
0
10259
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10038
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9906
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8933
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6710
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5482
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4007
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3609
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2849
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.