[ create a new paste ] login | about

Link: http://codepad.org/t5uaBaLd    [ raw code | output | fork ]

C, pasted on Jul 15:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct {
  unsigned char bfType1;
  unsigned char bfType2;
  unsigned long bfSize;
  unsigned short bfReserved1;
  unsigned short bfReserved2;
  unsigned long bfOffBits;
} BitmapFileHeader;

int bmHeaderCheck(FILE *fp, BitmapFileHeader *bh) {
  assert(sizeof(unsigned short) == 2);
  assert(sizeof(unsigned long) == 4);
  if (fread(&(bh->bfType1), sizeof(unsigned char), 1, fp) != 1)
    goto error_NotRead;
  if (fread(&(bh->bfType2), sizeof(unsigned char), 1, fp) != 1)
    goto error_NotRead;
  if (fread(&(bh->bfSize), sizeof(unsigned long), 1, fp) != 1)
    goto error_NotRead;
  if (fread(&(bh->bfReserved1), sizeof(unsigned short), 1, fp) != 1)
    goto error_NotRead;
  if (fread(&(bh->bfReserved2), sizeof(unsigned short), 1, fp) != 1)
    goto error_NotRead;
  if (fread(&(bh->bfOffBits), sizeof(unsigned long), 1, fp) != 1)
    goto error_NotRead;
  if (bh->bfType1 != 'B' || bh->bfType2 != 'M')
    goto error_NotBitmap;
  if (bh->bfReserved1 != 0 || bh->bfReserved2 != 0)
    goto error_NotBitmap;
  printf("bfType1: %c\n", bh->bfType1);
  printf("bfType2: %c\n", bh->bfType2);
  printf("bfSize: %lu\n", bh->bfSize);
  printf("bfReserved1: %u\n", bh->bfReserved1);
  printf("bfReserved2: %u\n", bh->bfReserved2);
  printf("bfOffBits: %lu\n", bh->bfOffBits);
  putchar('\n');
  return 1;

error_NotBitmap:
  fprintf(stderr, "cannot find bmp header\n");
  return 0;
error_NotRead:
  fprintf(stderr, "cannot read bmp header\n");
  return 0;
}

typedef struct {
  unsigned long biSize;
  long biWidth;
  long biHeight;
  unsigned short biPlanes;
  unsigned short biBitCount;
  unsigned long biCompression;
  unsigned long biSizeImage;
  long biXPixPerMeter;
  long biYPixPerMeter;
  unsigned long biClrUsed;
  unsigned long biClrImpotant;
} BitmapInfoHeader;

int bmInfoHeaderCheck(FILE *fp, BitmapInfoHeader *bi)
{
  assert(sizeof(unsigned short) == 2);
  assert(sizeof(unsigned long) == 4);
  assert(sizeof(long) == 4);
  if (fread(&(bi->biSize), sizeof(unsigned long), 1, fp) != 1)
    goto error_NotRead;
  if (bi->biSize == 12) {
    bi->biWidth = 0;
    if (fread(&(bi->biWidth), sizeof(short), 1, fp) != 1)
      goto error_NotRead;
    bi->biHeight = 0;
    if (fread(&(bi->biHeight), sizeof(short), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biPlanes), sizeof(unsigned short), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biBitCount), sizeof(unsigned short), 1, fp) != 1)
      goto error_NotRead;
    if (bi->biWidth > 32768)
      bi->biWidth = -bi->biWidth;
    if (bi->biHeight > 32768)
      bi->biWidth = -bi->biHeight;
  } else if (bi->biSize == 40) {
    if (fread(&(bi->biWidth), sizeof(long), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biHeight), sizeof(long), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biPlanes), sizeof(unsigned short), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biBitCount), sizeof(unsigned short), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biCompression), sizeof(unsigned long), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biSizeImage), sizeof(unsigned long), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biXPixPerMeter), sizeof(long), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biYPixPerMeter), sizeof(long), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biClrUsed), sizeof(unsigned long), 1, fp) != 1)
      goto error_NotRead;
    if (fread(&(bi->biClrImpotant), sizeof(unsigned long), 1, fp) != 1)
      goto error_NotRead;
  } else
    goto error_NotSupported1;
  printf("biSize: %lu\n", bi->biSize);
  printf("biWidth: %ld\n", bi->biWidth);
  printf("biHeight: %ld\n", bi->biHeight);
  printf("biPlanes: %u\n", bi->biPlanes);
  printf("biBitcount: %u\n", bi->biBitCount);
  if (bi->biSize == 40) {
    printf("biCompression: %lu\n", bi->biCompression);
    printf("biSizeImage: %lu\n", bi->biSizeImage);
    printf("biXPixPerMeter %ld\n", bi->biXPixPerMeter);
    printf("biYPixPerMeter %ld\n", bi->biYPixPerMeter);
    printf("biClrUsed: %lu\n", bi->biClrUsed);
    printf("biClrImporant: %lu\n", bi->biClrImpotant);
  }
  putchar('\n');
  if (bi->biSize != 40)
    goto error_NotSupported1;
  if (bi->biPlanes != 1)
    goto error_NotSupported2;
  if (bi->biBitCount != 24)
    goto error_NotSupported3;
  if (bi->biCompression != 0)
    goto error_NotSupported4;
  return 1;

error_NotSupported1:
  fprintf(stderr, "info header size: this format is not supported\n");
  return 0;
error_NotSupported2:
  fprintf(stderr, "biPlanes: this format is not supported\n");
  return 0;
error_NotSupported3:
  fprintf(stderr, "biBitCount: this format is not supported\n");
  return 0;
error_NotSupported4:
  fprintf(stderr, "biCompression: this format is not supported\n");
  return 0;
error_NotRead:
  fprintf(stderr, "cannot read bmp info header\n");
  return 0;
}

int isFtellGood(FILE *fp, unsigned long pos) {
  return (unsigned long)ftell(fp) == pos;
}

long iabs(long n) {
  return (n > 0) ? n : -n;
}

void task_read(FILE *fp, BitmapFileHeader *bheader, BitmapInfoHeader *binfo,
          char **dataR, char **dataG, char **dataB)
{
  long x, y;
  unsigned char dummy;
  int c;
  if (!isFtellGood(fp, bheader->bfOffBits)) {
    fprintf(stderr, "Header or Image Data is corrupted.\n");
    return;
  }
  *dataR = malloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight));
  *dataG = malloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight));
  *dataB = malloc(sizeof(char) * iabs(binfo->biWidth) * iabs(binfo->biHeight));  
  if (*dataR == NULL || *dataG == NULL || *dataB == NULL) {
    fprintf(stderr, "cannot alloc. enough memory.\n");
    return;
  }
  for (y = 0; y < iabs(binfo->biHeight); y++) {
    c = 0;
    for (x = 0; x < iabs(binfo->biWidth); x++) {
      fread((*dataB + y * iabs(binfo->biWidth) + x), 1, 1, fp);
      fread((*dataG + y * iabs(binfo->biWidth) + x), 1, 1, fp);
      fread((*dataR + y * iabs(binfo->biWidth) + x), 1, 1, fp);
      c += 3;
    }
    while (c % 4 != 0) {
      fread(&dummy, 1, 1, fp);
      c++;
    }
  }
  return;
}

void task_write_header(FILE *fp, BitmapFileHeader *bh) {
  assert(sizeof(unsigned short) == 2);
  assert(sizeof(unsigned long) == 4);
  fwrite(&(bh->bfType1), sizeof(unsigned char), 1, fp);
  fwrite(&(bh->bfType2), sizeof(unsigned char), 1, fp);
  fwrite(&(bh->bfSize), sizeof(unsigned long), 1, fp);
  fwrite(&(bh->bfReserved1), sizeof(unsigned short), 1, fp);
  fwrite(&(bh->bfReserved2), sizeof(unsigned short), 1, fp);
  fwrite(&(bh->bfOffBits), sizeof(unsigned long), 1, fp);
}

void task_write_info(FILE *fp, BitmapInfoHeader *bi) {
  assert(sizeof(unsigned short) == 2);
  assert(sizeof(unsigned long) == 4);
  assert(sizeof(long) == 4);
  fwrite(&(bi->biSize), sizeof(unsigned long), 1, fp);
  fwrite(&(bi->biWidth), sizeof(long), 1, fp);
  fwrite(&(bi->biHeight), sizeof(long), 1, fp);
  fwrite(&(bi->biPlanes), sizeof(unsigned short), 1, fp);
  fwrite(&(bi->biBitCount), sizeof(unsigned short), 1, fp);
  fwrite(&(bi->biCompression), sizeof(unsigned long), 1, fp);
  fwrite(&(bi->biSizeImage), sizeof(unsigned long), 1, fp);
  fwrite(&(bi->biXPixPerMeter), sizeof(long), 1, fp);
  fwrite(&(bi->biYPixPerMeter), sizeof(long), 1, fp);
  fwrite(&(bi->biClrUsed), sizeof(unsigned long), 1, fp);
  fwrite(&(bi->biClrImpotant), sizeof(unsigned long), 1, fp);
}

void task_write(int pos, FILE *fp, BitmapFileHeader *bh, BitmapInfoHeader *bi, char *data)
{
  int x, y, c;
  unsigned char dummy = '\0';
  task_write_header(fp, bh);
  task_write_info(fp, bi);
  for (y = 0; y < iabs(bi->biHeight); y++) {
    c = 0;
    for (x = 0; x < iabs(bi->biWidth); x++) {
      if (pos == 2)
        fwrite(&data[y * iabs(bi->biWidth) + x], 1, 1, fp);
      else
        fwrite(&dummy, 1, 1, fp);
      if (pos == 1)
        fwrite(&data[y * iabs(bi->biWidth) + x], 1, 1, fp);
      else
        fwrite(&dummy, 1, 1, fp);
      if (pos == 0)
        fwrite(&data[y * iabs(bi->biWidth) + x], 1, 1, fp);
      else
        fwrite(&dummy, 1, 1, fp);
      c += 3;
    }
    while (c % 4 != 0) {
      fwrite(&dummy, 1, 1, fp);
      c++;
    }
  }
}

int main(int argc, char *argv[]) {
  FILE *fp;
  BitmapFileHeader bheader;
  BitmapInfoHeader binfo;
  char *dataR, *dataG, *dataB;

  if ((fp = fopen(argv[1], "rb")) == NULL) {
    fprintf(stderr, "cannot open the file \"%s\".\n", argv[1]);
    return -1;
  }
  if(!bmHeaderCheck(fp, &bheader)) {
    fprintf(stderr, "the file \"%s\" might be a bitmap file.\n", argv[1]);
    return -1;
  }
  if (!bmInfoHeaderCheck(fp, &binfo)) {
    fprintf(stderr, "the file \"%s\" might not be a bitmap file.\n", argv[1]);
    return -1;
  }
  dataR = dataG = dataB = NULL;
  task_read(fp, &bheader, &binfo, &dataR, &dataG, &dataB);
  fclose(fp);
  bheader.bfSize = iabs(binfo.biWidth) * iabs(binfo.biHeight) * 3 + binfo.biSize + 14;

  if ((fp = fopen("r.bmp", "wb")) == NULL) {
    fprintf(stderr, "cannot open the file 'r.bmp'.\n");
  }
  task_write(0, fp, &bheader, &binfo, dataR);
  fclose(fp);
  fprintf(stderr, "output red data.\n");

  if ((fp = fopen("g.bmp", "wb")) == NULL) {
    fprintf(stderr, "cannot open the file 'g.bmp'.\n");
  }
  task_write(1, fp, &bheader, &binfo, dataG);
  fclose(fp);
  fprintf(stderr, "output green data.\n");

  if ((fp = fopen("b.bmp", "wb")) == NULL) {
    fprintf(stderr, "cannot open the file 'b.bmp'.\n");
  }
  task_write(2, fp, &bheader, &binfo, dataB);
  fclose(fp);
  fprintf(stderr, "output blue data.\n");

  if (dataR != NULL)
    free(dataR);
  if (dataG != NULL)
    free(dataG);
  if (dataB != NULL)
    free(dataB);

  return 0;
}
/* end */


Output:
1
2
3
cannot open the file "(null)".

Exited: ExitFailure 255


Create a new paste based on this one


Comments: