output.c

Go to the documentation of this file.
00001 // file output.c
00002 
00003 // load and prepare any image maps used by the renderer
00004 
00005 
00006 #define MODULE_OUTPUT
00007 
00008 /* Output file writing + image map loading */
00009 
00010 #include "render.h"
00011 
00012 extern unsigned char *gRed,   *gGreen,   *gBlue,
00013                      *gL_Red, *gL_Green, *gL_Blue;
00014 extern char gszHomeDir[];
00015 
00016 
00017 // code to deal with anti-aliasing
00018 
00019 static int n_per_line[5]={1,1,2,2,3};
00020 
00021 long AntiAliasLine(long scanline,long aa,
00022          UCHAR *Red, UCHAR *Green, UCHAR *Blue, UCHAR *Alfa,
00023          UCHAR *L_Red, UCHAR *L_Green, UCHAR *L_Blue, UCHAR *L_Alfa,
00024          UCHAR *LL_Red, UCHAR *LL_Green, UCHAR *LL_Blue, UCHAR *LL_Alfa){
00025  fullscreenbuffer *f;
00026  unsigned short r,g,b,val,Nt;
00027  unsigned short *Ergb;
00028  short          *LineBuffer;
00029  long j,k,xmax;
00030  Ergb=RendererUshortBuffer;
00031  LineBuffer=RendererShortBuffer;
00032  xmax=ResolutionX;
00033  if(aa == NONE){
00034    OUTPUT:
00035    if(ntsc_colours == YES){ /* limit colours 0-240 */
00036      for(j=0;j<xmax;j++){
00037        Red[j]   = (unsigned char)( ((double)Red[j])   * 0.9412);
00038        Green[j] = (unsigned char)( ((double)Green[j]) * 0.9412);
00039        Blue[j]  = (unsigned char)( ((double)Blue[j])  * 0.9412);
00040      }
00041    }
00042    if(instant_callback == YES) // used for main preview and for texture/shader test preview
00043      AddToRenderImagePreview(scanline/n_per_line[aa],
00044                              ResolutionX,ResolutionY,
00045                              NULL,Red,Green,Blue);
00046    if(FullScreenBuffer != NULL){
00047      f=FullScreenBuffer+(scanline/n_per_line[aa])*xmax;
00048      for(j=0; j<xmax; j++){ 
00049        f->R = *(Red+j);  f->G = *(Green+j);
00050        f->B = *(Blue+j); f->A = *(Alfa+j);
00051        f++;
00052      }
00053      return 0;
00054    }
00055  }
00056  else if(aa == LOW){
00057    for (j = XMIN+1,k=0; j < XMAX ; j += 2,k++) {
00058      Red[k] = (unsigned char)(((long)Red[j]+(long)Red[j-1])/2);
00059      Green[k] = (unsigned char)(((long)Green[j]+(long)Green[j-1])/2);
00060      Blue[k] = (unsigned char)(((long)Blue[j]+(long)Blue[j-1])/2);
00061      Alfa[k] = (unsigned char)(((long)Alfa[j]+(long)Alfa[j-1])/2);
00062    }
00063    goto OUTPUT;
00064  }
00065  else if(aa == MEDIUM){
00066    if(scanline & 1){
00067      for (j = XMIN+1,k=0; j < XMAX ; j += 2,k++) {
00068        Red[k] = (unsigned char)(((long)Red[j]
00069               +(long)Red[j-1]+(long)L_Red[j]+(long)L_Red[j-1])/4);
00070        Green[k] = (unsigned char)(((long)Green[j]
00071               +(long)Green[j-1]+(long)L_Green[j]+(long)L_Green[j-1])/4);
00072        Blue[k] = (unsigned char)(((long)Blue[j]
00073               +(long)Blue[j-1]+(long)L_Blue[j]+(long)L_Blue[j-1])/4);
00074        Alfa[k] = (unsigned char)(((long)Alfa[j]
00075               +(long)Alfa[j-1]+(long)L_Alfa[j]+(long)L_Alfa[j-1])/4);
00076      }
00077      goto OUTPUT;
00078    }
00079    else{
00080      memcpy(L_Red,Red,XMAX);
00081      memcpy(L_Green,Green,XMAX);
00082      memcpy(L_Blue,Blue,XMAX);
00083      memcpy(L_Alfa,Alfa,XMAX);
00084    }
00085  }
00086  else if(aa == HIGH){
00087    if(scanline & 1){
00088      for (j = XMIN+2,k=0; j < XMAX ; j += 3,k++) {
00089        Red[k]   = (unsigned char)(0.5+
00090            ((double)Red[j]+(double)Red[j-1]+(double)Red[j-2]+
00091             (double)L_Red[j]+(double)L_Red[j-1]+(double)L_Red[j-2])/6.0);
00092        Green[k]   = (unsigned char)(0.5+
00093            ((double)Green[j]+(double)Green[j-1]+(double)Green[j-2]+
00094             (double)L_Green[j]+(double)L_Green[j-1]+(double)L_Green[j-2])/6.0);
00095        Blue[k]   = (unsigned char)(0.5+
00096            ((double)Blue[j]+(double)Blue[j-1]+(double)Blue[j-2]+
00097             (double)L_Blue[j]+(double)L_Blue[j-1]+(double)L_Blue[j-2])/6.0);
00098        Alfa[k]   = (unsigned char)(0.5+
00099            ((double)Alfa[j]+(double)Alfa[j-1]+(double)Alfa[j-2]+
00100             (double)L_Alfa[j]+(double)L_Alfa[j-1]+(double)L_Alfa[j-2])/6.0);
00101      }
00102      goto OUTPUT;
00103    }
00104    else{
00105      memcpy(L_Red,Red,XMAX);
00106      memcpy(L_Green,Green,XMAX);
00107      memcpy(L_Blue,Blue,XMAX);
00108      memcpy(L_Alfa,Alfa,XMAX);
00109    }
00110  }
00111  else if(aa == ULTRA){
00112    if(scanline%3 == 2){
00113      for (j = XMIN+2,k=0; j < XMAX ; j += 3,k++) {
00114        Red[k]   = (unsigned char)(0.5+
00115            ((double)Red[j]+(double)Red[j-1]+(double)Red[j-2]+
00116             (double)L_Red[j]+(double)L_Red[j-1]+(double)L_Red[j-2]+
00117             (double)LL_Red[j]+(double)LL_Red[j-1]+(double)LL_Red[j-2])/9.0);
00118        Green[k]   = (unsigned char)(0.5+
00119            ((double)Green[j]+(double)Green[j-1]+(double)Green[j-2]+
00120             (double)L_Green[j]+(double)L_Green[j-1]+(double)L_Green[j-2]+
00121             (double)LL_Green[j]+(double)LL_Green[j-1]+(double)LL_Green[j-2])/9.0);
00122        Blue[k]   = (unsigned char)(0.5+
00123            ((double)Blue[j]+(double)Blue[j-1]+(double)Blue[j-2]+
00124             (double)L_Blue[j]+(double)L_Blue[j-1]+(double)L_Blue[j-2]+
00125             (double)LL_Blue[j]+(double)LL_Blue[j-1]+(double)LL_Blue[j-2])/9.0);
00126        Alfa[k]   = (unsigned char)(0.5+
00127            ((double)Alfa[j]+(double)Alfa[j-1]+(double)Alfa[j-2]+
00128             (double)L_Alfa[j]+(double)L_Alfa[j-1]+(double)L_Alfa[j-2]+
00129             (double)LL_Alfa[j]+(double)LL_Alfa[j-1]+(double)LL_Alfa[j-2])/9.0);
00130      }
00131      goto OUTPUT;
00132    }
00133    else{
00134      if(scanline%3 == 1){
00135        memcpy(L_Red,Red,XMAX);
00136        memcpy(L_Green,Green,XMAX);
00137        memcpy(L_Blue,Blue,XMAX);
00138        memcpy(L_Alfa,Alfa,XMAX);
00139      }
00140      else if(scanline%3 == 0){
00141        memcpy(LL_Red,Red,XMAX);
00142        memcpy(LL_Green,Green,XMAX);
00143        memcpy(LL_Blue,Blue,XMAX);
00144        memcpy(LL_Alfa,Alfa,XMAX);
00145      }
00146    }
00147  }
00148  return 0;
00149 }
00150 
00151 void ScanlineToZbuffer(long k, double *Zdepth){
00152  float *buf;
00153  long i;
00154  if     (anti_alias == ULTRA){
00155    if(k%3 != 0)return;
00156    k=k/3;
00157  }
00158  else if(anti_alias == MEDIUM || anti_alias == HIGH){
00159    if(k%2 != 0)return;
00160    k=k/2;
00161  }
00162  buf=(fszBuffer+(long)ResolutionX*k);
00163  for(i=0;i<XMAX;i+=aaXstep) *buf++ = (float)Zdepth[i];
00164 }
00165 
00166 void ScanlineToZobject(long k, long *Zobject){
00167  unsigned char *buf;
00168  long i;
00169  if     (anti_alias == ULTRA){
00170    if(k%3 != 0)return;
00171    k=k/3;
00172  }
00173  else if(anti_alias == MEDIUM || anti_alias == HIGH){
00174    if(k%2 != 0)return;
00175    k=k/2;
00176  }
00177  buf=(ObjectIdBuffer+(long)ResolutionX*k);
00178  for(i=0;i<XMAX;i+=aaXstep) *buf++ = (unsigned char)Zobject[i];
00179 }
00180 
00181 void FillAlfaLine(UCHAR *Alfa, long *ZglassO[], long *Zobject){
00182  long i;
00183  for(i=XMIN;i<XMAX;i++){
00184    if(Zobject[i] == -2){
00185      Alfa[i]=0;  /* the sky */
00186      if(ZglassO[0][i] >= 0){ /* glass over sky */
00187        Alfa[i] = 128;
00188      }
00189    }
00190    else{
00191      if(alfagroundON || Zobject[i] != -1)Alfa[i]=255;
00192    }
00193  }
00194  return;
00195 }
00196 
00197 // end of anti-aliasing  -  start of image writing 
00198 
00199 static short CompressLongLine(unsigned long *input, long *buffer, long xmax){
00200  long i;
00201  long *p,run,length,bufsize;
00202  p=buffer;  buffer++; *buffer++ = *input++;
00203  *p=0; run=0; length=0; bufsize = 2;
00204  for(i=1;i<xmax;i++){
00205    if( *input == *(input-1) ){
00206      if(length > 0){
00207        (*p)++; p = (buffer-1); *p = 1; *buffer++ = *input++; bufsize++;
00208        length=0; run=1;
00209      }
00210      else{
00211        (*p)++; input++; run++;
00212      }
00213    }
00214    else{
00215      if(run > 0){
00216        p=buffer++; *p=0; *buffer++ = *input++; bufsize +=2;
00217        run=0;
00218      }
00219      else{
00220        (*p)--; *buffer++ = *input++; bufsize++; length++;
00221      }
00222      if(bufsize > xmax-10)return 0;
00223    }
00224  }
00225  return bufsize;
00226 }
00227 
00228 long ScreenTo32bitFile(long frame, char *outputfile, char *out_root, fullscreenbuffer *stereo){
00229  char format[32];
00230  FILE *f16;
00231  fullscreenbuffer *f,*FSB;
00232  unsigned long r,g,b,val,Nt;
00233  unsigned long *Ergb;
00234  long          *LineBuffer;
00235  long i,j,k,xmax,ResY;
00236  if(stereo != NULL){
00237    FSB=stereo;
00238    ResY=ResolutionY*2;
00239    frame /= 2;
00240  }
00241  else{
00242    FSB=FullScreenBuffer;
00243    ResY=ResolutionY;
00244  }
00245  sprintf(format,"%s%ld%s","%s%0",tzeros,"d.32b");
00246  if(nScriptframes > 1)
00247    sprintf(outputfile,format,out_root,frame);
00248  else
00249    sprintf(outputfile,"%s.32b",out_root);
00250  //MessageBox(NULL,outputfile,"Writing 32 bit file",NULL);
00251  if((f16=fopen(strlwr(outputfile),"wb")) == NULL)return FAIL;
00252  Render_Message(46,0,outputfile);
00253  Ergb=RendererUlongBuffer;
00254  LineBuffer=RendererLongBuffer;
00255  xmax=ResolutionX;
00256  if(fwrite((char *)&ResolutionX,sizeof(long),1,f16) != 1 ||
00257     fwrite((char *)&ResY,sizeof(long),1,f16) != 1 ||
00258     fflush(f16) != 0){
00259    Render_Message(49,1,NULL);
00260    goto FPT;
00261  }
00262  for(i=0;i<ResY;i++){
00263    f=FSB+i*xmax;
00264    for(j=0; j<xmax; j++){
00265      *(gRed+j)   = f->R;
00266      *(gGreen+j) = f->G;
00267      *(gBlue+j)  = f->B;
00268      f++;
00269    }
00270    for (k=0; k<xmax; k++) {
00271      val = ((unsigned long)gRed[k])<< 16
00272          | ((unsigned long)gGreen[k])<< 8
00273          | ((unsigned long)gBlue[k]);
00274      Ergb[k]=val;
00275    }
00276    Nt=CompressLongLine(Ergb,LineBuffer,xmax);
00277    if(fwrite((char *)&Nt,sizeof(long),1,f16) != 1)goto FPT;
00278    else if(fflush(f16) != 0)goto FPT;
00279    if(Nt == 0){
00280      if(fwrite((char *)Ergb,sizeof(unsigned long),xmax,f16) != xmax)goto FPT;
00281      else if(fflush(f16) != 0)goto FPT;
00282    }
00283    else{
00284      if(fwrite((char *)LineBuffer,sizeof(long),Nt,f16) != Nt)goto FPT;
00285      else if(fflush(f16) != 0)goto FPT;
00286    }
00287  }
00288  fclose(f16);
00289  return 0;
00290  FPT:
00291  fclose(f16);
00292  return FAIL;
00293 }
00294 
00295 void OneExternalFrame(long frame, void *sbuffer, char *out_root,
00296                       long type, long quality){
00297  long x,y;
00298  char lname[256],outputfile[256],dll[256],type_list[16],format[32];
00299  HMODULE hLib;
00300  FARPROC fpFun;
00301  BOOL (*fpPutMap)(char *, long, long, long, fullscreenbuffer *);
00302  fullscreenbuffer *FSB;
00303  if(FullScreenBuffer == NULL){
00304    Render_Message(97,0,NULL);
00305    return;
00306  }
00307  if     (type == J24_FILE)strcpy(type_list,"jpg");
00308  else if(type == B24_FILE)strcpy(type_list,"bmp");
00309  else if(type == PNG_FILE)strcpy(type_list,"png");
00310  else if(type == TIF_FILE)strcpy(type_list,"tif");
00311  else if(type == JPS_FILE)strcpy(type_list,"jps");
00312  // add GIF here !!!
00313  x=ResolutionX;
00314  y=ResolutionY;
00315  if(type == JPS_FILE)FSB=(fullscreenbuffer *)sbuffer; 
00316  else                FSB=FullScreenBuffer;
00317  strcpy(lname,gszHomeDir);
00318  sprintf(dll,"%s_map.dll",type_list);
00319  strcat(lname,dll);
00320  sprintf(format,"%s%ld%s","%s%0",tzeros,"d.%s");
00321  if(nScriptframes > 1)
00322    sprintf(outputfile,format,out_root,frame,type_list);
00323  else
00324    sprintf(outputfile,"%s.%s",out_root,type_list);
00325  hLib=AddLoadedLibrary(lname);
00326  if(hLib != NULL){
00327    if((fpFun=GetProcAddress(hLib,"_PutExternalImage")) != NULL){
00328      fpPutMap = (void *)fpFun;
00329      //MessageBox(NULL,outputfile,lname,MB_OK);
00330      if((*fpPutMap)(outputfile,x,y,quality,FSB)){;}
00331    }
00332    //else MessageBox(NULL,"Failed to get adddress DLL",dll,MB_OK);
00333 
00334  }
00335  //else MessageBox(NULL,"Failed to load DLL",dll,MB_OK);
00336  return;
00337 }

Generated on Sun Apr 27 14:20:13 2014 for OpenFX by  doxygen 1.5.6