OpenCores
URL https://opencores.org/ocsvn/mb-jpeg/mb-jpeg/trunk

Subversion Repositories mb-jpeg

[/] [mb-jpeg/] [tags/] [arelease/] [decoder/] [JpegToBmp.c] - Rev 66

Compare with Previous | Blame | View Log

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#include "jpeg.h"
#include "fast_int_idct.c"
#include "huffman.c"
#include "color.c"
#include "parse.c"
#include "table_vld.c"
#include "utils.c"
 
/* real declaration of global variables here */
/* see jpeg.h for more info			*/
 
cd_t   comp[3];	      /* descriptors for 3 components */
PBlock *MCU_buff[10]; /* decoded DCT blocks buffer */
int    MCU_valid[10]; /* components of above MCU blocks */
 
PBlock *QTable[4];	/* quantization tables */
int    QTvalid[4];
 
int   x_size,y_size;	 /* Video frame size	 */
int   rx_size,ry_size;	 /* down-rounded Video frame size (integer MCU) */
int   MCU_sx, MCU_sy;	 /* MCU size in pixels	 */
int   mx_size, my_size;	 /* picture size in units of MCUs */
int   n_comp;		 	 /* number of components 1,3 */
 
unsigned char *ColorBuffer; /* MCU after color conversion */
unsigned char *FrameBuffer; /* complete final RGB image */
FBlock	      *FBuff;	    /* scratch frequency buffer */
PBlock	      *PBuff;	    /* scratch pixel buffer */
 
int	in_frame, curcomp;   /* frame started ? current component ? */
int	MCU_row, MCU_column; /* current position in MCU unit */
 
FILE	*fi;			/* input  File stream pointer	*/
 
int stuffers = 0;	/* stuff bytes in entropy coded segments */
int passed = 0;		/* bytes passed when searching markers */
 
int verbose = 0;
 
 
/*-----------------------------------------------------------------*/
/*		MAIN		MAIN		MAIN		   */
/*-----------------------------------------------------------------*/
 
int JpegToBmp(void)
{
  char *p;
  unsigned int aux, mark;
  int n_restarts, restart_interval, leftover; /* RST check */
  int i,j;
 
  fi = fopen(file1,"rb");
  if (fi == NULL) {
    MessageBox(0,"unable to open the file",file1,0);
    return 0;
  }
 
  /* First find the SOI marker: */
  aux = get_next_MK(fi);
  if (aux != SOI_MK)
    aborted_stream(fi);
 
  if (verbose)
    fprintf(stderr, "%ld:\tINFO:\tFound the SOI marker!\n", ftell(fi));
  in_frame = 0;
  restart_interval = 0;
  for (i = 0; i < 4; i++)
    QTvalid[i] = 0;
 
  /* Now process segments as they appear: */
  do {
    mark = get_next_MK(fi);
 
    switch (mark) {
    case SOF_MK:
      if (verbose)
	fprintf(stderr, "%ld:\tINFO:\tFound the SOF marker!\n", ftell(fi));
      in_frame = 1;
      get_size(fi);	/* header size, don't care */
 
      /* load basic image parameters */
      fgetc(fi);	/* precision, 8bit, don't care */
      y_size = get_size(fi);
      x_size = get_size(fi);
      if (verbose)
	fprintf(stderr, "\tINFO:\tImage size is %d by %d\n", x_size, y_size);
 
      n_comp = fgetc(fi);	/* # of components */
      if (verbose) {
	fprintf(stderr, "\tINFO:\t");
	switch (n_comp)
	  {
	  case 1:
	    fprintf(stderr, "Monochrome");
	    break;
	  case 3:
	    fprintf(stderr, "Color");
	    break;
	  default:
	    fprintf(stderr, "Not a");
	    break;
	  }
	fprintf(stderr, " JPEG image!\n");
      }
 
      for (i = 0; i < n_comp; i++) {
	/* component specifiers */
	comp[i].CID = fgetc(fi);
	aux = fgetc(fi);
	comp[i].HS = first_quad(aux);
	comp[i].VS = second_quad(aux);
	comp[i].QT = fgetc(fi);
      }
      if ((n_comp > 1) && verbose)
	fprintf(stderr, "\tINFO:\tColor format is %d:%d:%d, H=%d\n",
		comp[0].HS * comp[0].VS,
		comp[1].HS * comp[1].VS,
		comp[2].HS * comp[2].VS,
		comp[1].HS);
 
      if (init_MCU() == -1)
	aborted_stream(fi);
 
      /* dimension scan buffer for YUV->RGB conversion */
      FrameBuffer =
	(unsigned char *) malloc( (size_t) x_size * y_size * n_comp);
      ColorBuffer =
	(unsigned char *) malloc( (size_t) MCU_sx * MCU_sy * n_comp);
      FBuff = (FBlock *) malloc(sizeof(FBlock));
      PBuff = (PBlock *) malloc(sizeof(PBlock));
 
      if ((FrameBuffer == NULL) || (ColorBuffer == NULL) ||
	  (FBuff == NULL) || (PBuff == NULL) ) {
	fprintf(stderr, "\tERROR:\tCould not allocate pixel storage!\n");
	exit(1);
      }
      break;
 
    case DHT_MK:
      if (verbose)
	fprintf(stderr, "%ld:\tINFO:\tDefining Huffman Tables\n", ftell(fi));
      if (load_huff_tables(fi) == -1)
	aborted_stream(fi);
      break;
 
    case DQT_MK:
      if (verbose)
	fprintf(stderr,
		"%ld:\tINFO:\tDefining Quantization Tables\n", ftell(fi));
      if (load_quant_tables(fi) == -1)
	aborted_stream(fi);
      break;
 
    case DRI_MK:
      get_size(fi);	/* skip size */
      restart_interval = get_size(fi);
      if (verbose)
	fprintf(stderr, "%ld:\tINFO:\tDefining Restart Interval %d\n",
		ftell(fi), restart_interval);
      break;
 
    case SOS_MK:		/* lots of things to do here */
      if (verbose)
	fprintf(stderr, "%ld:\tINFO:\tFound the SOS marker!\n", ftell(fi));
      get_size(fi); /* don't care */
      aux = fgetc(fi);
      if (aux != (unsigned int) n_comp) {
	fprintf(stderr, "\tERROR:\tBad component interleaving!\n");
	aborted_stream(fi);
      }
 
      for (i = 0; i < n_comp; i++) {
	aux = fgetc(fi);
	if (aux != comp[i].CID) {
	  fprintf(stderr, "\tERROR:\tBad Component Order!\n");
	  aborted_stream(fi);
	}
	aux = fgetc(fi);
	comp[i].DC_HT = first_quad(aux);
	comp[i].AC_HT = second_quad(aux);
      }
      get_size(fi); fgetc(fi);	/* skip things */
 
      MCU_column = 0;
      MCU_row = 0;
      clear_bits();
      reset_prediction();
 
      /* main MCU processing loop here */
      if (restart_interval) {
	n_restarts = ceil_div(mx_size * my_size, restart_interval) - 1;
	leftover = mx_size * my_size - n_restarts * restart_interval;
	/* final interval may be incomplete */
 
	for (i = 0; i < n_restarts; i++) {
	  for (j = 0; j < restart_interval; j++)
	    process_MCU(fi);
	  /* proc till all EOB met */
 
	  aux = get_next_MK(fi);
	  if (!RST_MK(aux)) {
	    fprintf(stderr, "%ld:\tERROR:\tLost Sync after interval!\n",
		   ftell(fi));
	    aborted_stream(fi);
	  }
	  else if (verbose)
	    fprintf(stderr, "%ld:\tINFO:\tFound Restart Marker\n", ftell(fi));
 
	  reset_prediction();
	  clear_bits();
	}		/* intra-interval loop */
      }
      else
	leftover = mx_size * my_size;
 
      /* process till end of row without restarts */
      for (i = 0; i < leftover; i++)
	process_MCU(fi);
 
      in_frame = 0;
      break;
 
    case EOI_MK:
      if (verbose)
	fprintf(stderr, "%ld:\tINFO:\tFound the EOI marker!\n", ftell(fi));
      if (in_frame)
	aborted_stream(fi);
 
      if (verbose)
	fprintf(stderr, "\tINFO:\tTotal skipped bytes %d, total stuffers %d\n",
		passed, stuffers);
      fclose(fi);
 
//******** WRITE IT HERE !!! *************
{
	FILE *fpBMP;
 
	// Create bitmap
	fpBMP=fopen(file2,"wb");
	if(fpBMP == 0)
		return 0;
 
	// Write header
	fprintf(fpBMP,"%c%c%c%c%c%c%c%c%c%c", 66, 77, 54,252, 18,  0,  0,  0,  0,  0);
	fprintf(fpBMP,"%c%c%c%c%c%c%c%c%c%c", 54,  0,  0,  0, 40,  0,  0,  0,x_size%256,  x_size/256);
	fprintf(fpBMP,"%c%c%c%c%c%c%c%c%c%c",  0,  0, y_size%256,  y_size/256,  0,  0,  1,  0, 24,  0);
	fprintf(fpBMP,"%c%c%c%c%c%c%c%c%c%c",  0,  0,  0,  0,  0,252, 18,  0,206, 14);
	fprintf(fpBMP,"%c%c%c%c%c%c%c%c%c%c",  0,  0,  0,  0,  0,  0,  0,  0,  0,  0);
	fprintf(fpBMP,"%c%c%c%c",  0,  0,216, 14,  0);
 
	for(int i=y_size-1; i>=0; i--){		// in bitmaps the bottom line of the image is at the beginning of the file
		for(int j=0; j<x_size; j++){
			putc(FrameBuffer[3*(i*x_size+j)+0],fpBMP);
			putc(FrameBuffer[3*(i*x_size+j)+1],fpBMP);
			putc(FrameBuffer[3*(i*x_size+j)+2],fpBMP);
		}
		for(int j=0; j<x_size%4; j++)
			putc(0,fpBMP);
	}
 
	fclose(fpBMP);
}
 
      free_structures();
	  return 0;
      break;
 
    case COM_MK:
      if (verbose)
	fprintf(stderr, "%ld:\tINFO:\tSkipping comments\n", ftell(fi));
      skip_segment(fi);
      break;
 
    case EOF:
      if (verbose)
	fprintf(stderr, "%ld:\tERROR:\tRan out of input data!\n", ftell(fi));
      aborted_stream(fi);
 
    default:
      if ((mark & MK_MSK) == APP_MK) {
	if (verbose)
	  fprintf(stderr, "%ld:\tINFO:\tSkipping application data\n",
		  ftell(fi));
	skip_segment(fi);
	break;
      }
      if (RST_MK(mark)) {
	reset_prediction();
	break;
      }
      /* if all else has failed ... */
      fprintf(stderr, "%ld:\tWARNING:\tLost Sync outside scan, %d!\n",
	     ftell(fi), mark);
      aborted_stream(fi);
      break;
    } /* end switch */
  }
  while (1);
 
  return 0;
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.