Esempio n. 1
0
void jpeg_out() {
	int x,y;
	int xp;
	int p=0;
	int i,j;
	int m;
	int mincount;
	int* maskcount=(int*)malloc(g_numimages*sizeof(int));
	int* masklimit=(int*)malloc(g_numimages*sizeof(int));
	int* mask=(int*)malloc(g_numimages*sizeof(int));
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
	JSAMPROW row=(JSAMPROW)malloc(g_workwidth*3);
	uint32 temp;

	cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);
	jpeg_stdio_dest(&cinfo,g_jpeg);

	cinfo.image_width=g_workwidth;
	cinfo.image_height=g_workheight;
	cinfo.input_components=3;
	cinfo.in_color_space=JCS_RGB;

	jpeg_set_defaults(&cinfo);
	jpeg_set_quality(&cinfo,g_jpegquality,true);
	jpeg_start_compress(&cinfo,true);

	if (g_nomask) {
		for (y=0; y<g_workheight; y++) {
			xp=0;
			for (x=0; x<g_workwidth; x++) {
				((uint8*)row)[xp++]=((uint8*)g_out_channels[0])[p];
				((uint8*)row)[xp++]=((uint8*)g_out_channels[1])[p];
				((uint8*)row)[xp++]=((uint8*)g_out_channels[2])[p];
				p++;
			}
  		jpeg_write_scanlines(&cinfo,&row,1);
		}
	} else {
		for (y=0; y<g_workheight; y++) {
			for (i=0; i<g_numimages; i++) {
				mask[i]=MASKOFF;
				if (y>=g_images[i].ypos && y<g_images[i].ypos+g_images[i].height) {
					maskcount[i]=g_images[i].xpos;
					masklimit[i]=g_images[i].xpos+g_images[i].width;
					g_images[i].binary_mask.pointer=&g_images[i].binary_mask.data[g_images[i].binary_mask.rows[y-g_images[i].ypos]];
				} else {
					maskcount[i]=g_workwidth;
					masklimit[i]=g_workwidth;
				}
			}

			x=0;
			xp=0;
			while (x<g_workwidth) {
				m=MASKOFF;
				mincount=g_workwidth-x;
				for (i=0; i<g_numimages; i++) {
					if (maskcount[i]==0) {
						if (x<masklimit[i]) {
							NEXTiMASK(i);
						} else {
							mask[i]=MASKOFF;
							maskcount[i]=mincount;
						}
					}

					if (maskcount[i]<mincount) mincount=maskcount[i];
					if (mask[i]!=MASKOFF) m=MASKON;
				}

				if (m==MASKON) {
					for (j=0; j<mincount; j++) {
						((uint8*)row)[xp++]=((uint8*)g_out_channels[0])[p];
						((uint8*)row)[xp++]=((uint8*)g_out_channels[1])[p];
						((uint8*)row)[xp++]=((uint8*)g_out_channels[2])[p];
						p++;
					}
				} else {
					memset(&((uint8*)row)[xp],0,mincount*3);

					xp+=mincount*3;
					p+=mincount;
				}

				for (i=0; i<g_numimages; i++) maskcount[i]-=mincount;
				x+=mincount;
			}

			jpeg_write_scanlines(&cinfo,&row,1);
		}
	}

	jpeg_finish_compress(&cinfo);
	jpeg_destroy_compress(&cinfo);
  fclose(g_jpeg);
}
Esempio n. 2
0
void tiff_out() {
	int i,j;
	int m;
	int mincount;
	int* maskcount=(int*)malloc(g_numimages*sizeof(int));
	int* masklimit=(int*)malloc(g_numimages*sizeof(int));
	int* mask=(int*)malloc(g_numimages*sizeof(int));
	int rowsperstrip=64;
	int p=0;
	int strips;
	int remaining;
	int strip_p;
	int x,y=0,s;
	int stripy;
	int rows;
  uint16 out[1];
	uint32 temp;
	int mul;

	mul=3;
	if (!g_nomask) mul=4;
	if (g_workbpp==16) mul=mul<<1;
	mul=mul*g_workwidth;

	for (i=0; i<g_numimages; i++) g_images[i].binary_mask.pointer=g_images[i].binary_mask.data;

	void* strip=malloc((rowsperstrip*g_workwidth)<<(g_workbpp>>2));

	TIFFSetField(g_tiff, TIFFTAG_IMAGEWIDTH, g_workwidth);
	TIFFSetField(g_tiff, TIFFTAG_IMAGELENGTH, g_workheight);
	TIFFSetField(g_tiff, TIFFTAG_COMPRESSION, g_compression);
	TIFFSetField(g_tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	TIFFSetField(g_tiff, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
	TIFFSetField(g_tiff, TIFFTAG_BITSPERSAMPLE, g_workbpp);
	if (g_nomask) {
		TIFFSetField(g_tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
	} else {
		TIFFSetField(g_tiff, TIFFTAG_SAMPLESPERPIXEL, 4);
		out[0] = EXTRASAMPLE_UNASSALPHA;
    TIFFSetField(g_tiff, TIFFTAG_EXTRASAMPLES, 1, &out);
	}
  TIFFSetField(g_tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
  if (g_xres!=-1) { TIFFSetField(g_tiff, TIFFTAG_XRESOLUTION, g_xres); TIFFSetField(g_tiff, TIFFTAG_XPOSITION, (float)(g_min_left/g_xres)); }
  if (g_yres!=-1) { TIFFSetField(g_tiff, TIFFTAG_YRESOLUTION, g_yres); TIFFSetField(g_tiff, TIFFTAG_YPOSITION, (float)(g_min_top/g_yres)); }

	if (g_images[0].geotiff.set) {
		// if we got a georeferenced input, store the geotags in the output
		GeoTIFFInfo info(g_images[0].geotiff);
		info.XGeoRef = g_min_left * g_images[0].geotiff.XCellRes;
		info.YGeoRef = -g_min_top * g_images[0].geotiff.YCellRes;
		output(1,"Output georef: UL: %f %f, pixel size: %f %f\n",info.XGeoRef, info.YGeoRef, info.XCellRes, info.YCellRes);
		geotiff_write(g_tiff, &info);
	}

  strips=(int)((g_workheight+rowsperstrip-1)/rowsperstrip);
	remaining=g_workheight;

	for (s=0; s<strips; s++) {
		rows=min(remaining,rowsperstrip);
    strip_p=0;
		for (stripy=0; stripy<rows; stripy++) {
			if (g_nomask) {
				if (g_workbpp==8) {
					for (x=0; x<g_workwidth; x++) {
						((uint8*)strip)[strip_p++]=((uint8*)g_out_channels[0])[p];
						((uint8*)strip)[strip_p++]=((uint8*)g_out_channels[1])[p];
						((uint8*)strip)[strip_p++]=((uint8*)g_out_channels[2])[p];
						p++;
					}
				} else {
					for (x=0; x<g_workwidth; x++) {
						((uint16*)strip)[strip_p++]=((uint16*)g_out_channels[0])[p];
						((uint16*)strip)[strip_p++]=((uint16*)g_out_channels[1])[p];
						((uint16*)strip)[strip_p++]=((uint16*)g_out_channels[2])[p];
						p++;
					}
				}
			} else {
				for (i=0; i<g_numimages; i++) {
					mask[i]=MASKOFF;
					if (y>=g_images[i].ypos && y<g_images[i].ypos+g_images[i].height) {
						maskcount[i]=g_images[i].xpos;
						masklimit[i]=g_images[i].xpos+g_images[i].width;
						g_images[i].binary_mask.pointer=&g_images[i].binary_mask.data[g_images[i].binary_mask.rows[y-g_images[i].ypos]];
					} else {
						maskcount[i]=g_workwidth;
						masklimit[i]=g_workwidth;
					}
				}

				x=0;
			  while (x<g_workwidth) {
					m=MASKOFF;
					mincount=g_workwidth-x;
					for (i=0; i<g_numimages; i++) {
						if (maskcount[i]==0) {
							if (x<masklimit[i]) {
								NEXTiMASK(i);
							} else {
								mask[i]=MASKOFF;
								maskcount[i]=mincount;
							}
						}

						if (maskcount[i]<mincount) mincount=maskcount[i];
						if (mask[i]!=MASKOFF) m=MASKON;
					}

					if (m==MASKON) {
						if (g_workbpp==8) {
							for (j=0; j<mincount; j++) {
								((uint8*)strip)[strip_p++]=((uint8*)g_out_channels[0])[p];
								((uint8*)strip)[strip_p++]=((uint8*)g_out_channels[1])[p];
								((uint8*)strip)[strip_p++]=((uint8*)g_out_channels[2])[p];
								((uint8*)strip)[strip_p++]=0xff;
								p++;
							}
						} else {
							for (j=0; j<mincount; j++) {
								((uint16*)strip)[strip_p++]=((uint16*)g_out_channels[0])[p];
								((uint16*)strip)[strip_p++]=((uint16*)g_out_channels[1])[p];
								((uint16*)strip)[strip_p++]=((uint16*)g_out_channels[2])[p];
								if (!g_nomask) ((uint16*)strip)[strip_p++]=0xffff;
								p++;
							}
						}
					} else {
						if (g_workbpp==8) {
							memset(&((uint8*)strip)[strip_p],0,mincount<<2);
						} else {
							memset(&((uint16*)strip)[strip_p],0,mincount<<3);
						}
						strip_p+=mincount<<2;
						p+=mincount;
					}
/*
				if (m==MASKON || g_nomask) {
					if (g_workbpp==8) {
						for (j=0; j<mincount; j++) {
							((uint8*)strip)[strip_p++]=((uint8**)g_out_channels)[0][p];
							((uint8*)strip)[strip_p++]=((uint8**)g_out_channels)[1][p];
							((uint8*)strip)[strip_p++]=((uint8**)g_out_channels)[2][p];
							if (!g_nomask) ((uint8*)strip)[strip_p++]=0xff;
							p++;
						}
					} else {
						for (j=0; j<mincount; j++) {
							((uint16*)strip)[strip_p++]=((uint16**)g_out_channels)[0][p];
							((uint16*)strip)[strip_p++]=((uint16**)g_out_channels)[1][p];
							((uint16*)strip)[strip_p++]=((uint16**)g_out_channels)[2][p];
							if (!g_nomask) ((uint16*)strip)[strip_p++]=0xffff;
							p++;
						}
					}
				} else {
					if (g_workbpp==8) {
						if (g_nomask) blank=mincount*3; else blank=mincount<<2;
						memset(&((uint8*)strip)[strip_p],0,blank);
						strip_p+=mincount<<2;
					} else {
						if (g_nomask) blank=mincount*6; else blank=mincount<<3;
						memset(&((uint16*)strip)[strip_p],0,blank);
						strip_p+=mincount<<2;
					}
					p+=mincount;
				}
*/

					for (i=0; i<g_numimages; i++) maskcount[i]-=mincount;
					x+=mincount;
				}
			}
			y++;
		}
    TIFFWriteEncodedStrip(g_tiff,s,strip,rows*mul);

		remaining-=rows;
	}

	TIFFClose(g_tiff);
}
Esempio n. 3
0
void seam_png(int mode, const char *filename) {
  int x;
  int y;
  int count, i;
  int *maskcount = (int *)malloc(g_numimages * sizeof(int));
  int *masklimit = (int *)malloc(g_numimages * sizeof(int));
  int *mask = (int *)malloc(0x100 * sizeof(int));
  int mincount;
  int xorcount;
  int xorimage;
  int stop;
  uint32 temp;
  uint32 *seam_p;
  png_structp png_ptr;
  png_infop info_ptr;
  double base = 2;
  double rad;
  double r, g, b;
  FILE *f;

  if (!g_palette) {
    g_palette = (png_color *)malloc(256 * sizeof(png_color));

    for (i = 0; i < 255; i++) {
      rad = base;
      r = max<double>(0, min<double>(1.0, min<double>(rad, 4 - rad)));
      rad += 2;
      if (rad >= 6) rad -= 6;
      g = max<double>(0, min<double>(1.0, min<double>(rad, 4 - rad)));
      rad += 2;
      if (rad >= 6) rad -= 6;
      b = max<double>(0, min<double>(1.0, min<double>(rad, 4 - rad)));
      base += 6 * 0.618033988749895;
      if (base >= 6) base -= 6;
      g_palette[i].red = (int)(r * 255 + 0.5);
      g_palette[i].green = (int)(g * 255 + 0.5);
      g_palette[i].blue = (int)(b * 255 + 0.5);
    }
    g_palette[i].red = 0;
    g_palette[i].green = 0;
    g_palette[i].blue = 0;
  }

  switch (mode) {
    case 0:
      output(1, "saving xor map...\n");
      break;
    case 1:
      output(1, "saving seams...\n");
      break;
  }

  fopen_s(&f, filename, "wb");
  if (!f) {
    output(0, "WARNING: couldn't save seam file\n");
    return;
  }

  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (!png_ptr) {
    output(0, "WARNING: PNG create failed\n");
    return;
  }

  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
    return;
  }

  png_init_io(png_ptr, f);

  png_set_IHDR(png_ptr, info_ptr, g_workwidth, g_workheight, 8,
               PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
               PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  png_set_PLTE(png_ptr, info_ptr, g_palette, 256);

  png_write_info(png_ptr, info_ptr);

  if (mode == 0) {
    for (y = 0; y < g_workheight; y++) {
      for (i = 0; i < g_numimages; i++) {
        mask[i] = MASKOFF;
        if (y >= g_images[i].ypos &&
            y < g_images[i].ypos + g_images[i].height) {
          maskcount[i] = g_images[i].xpos;
          masklimit[i] = g_images[i].xpos + g_images[i].width;
          g_images[i].binary_mask.pointer =
              &g_images[i]
                   .binary_mask
                   .data[g_images[i].binary_mask.rows[y - g_images[i].ypos]];
        } else {
          maskcount[i] = g_workwidth;
          masklimit[i] = g_workwidth;
        }
      }

      x = 0;
      while (x < g_workwidth) {
        mincount = g_workwidth - x;
        xorcount = 0;
        for (i = 0; i < g_numimages; i++) {
          if (maskcount[i] == 0) {
            if (x < masklimit[i]) {
              NEXTiMASK(i);
            } else {
              mask[i] = MASKOFF;
              maskcount[i] = mincount;
            }
          }

          if (maskcount[i] < mincount) mincount = maskcount[i];
          if (mask[i] != MASKOFF) {
            xorcount++;
            xorimage = i;
          }
        }

        stop = x + mincount;

        if (xorcount != 1) xorimage = 255;

        while (x < stop) {
          ((uint8 *)g_line0)[x++] = xorimage;
        }

        for (i = 0; i < g_numimages; i++) maskcount[i] -= mincount;
      }

      png_write_row(png_ptr, (uint8 *)g_line0);
    }
  }

  else if (mode == 1) {
    seam_p = g_seams;

    for (y = 0; y < g_workheight; y++) {
      x = 0;
      while (x < g_workwidth) {
        i = *seam_p & 0xff;
        count = *seam_p++ >> 8;
        memset(&((uint8 *)g_line0)[x], i, count);
        x += count;
      }

      png_write_row(png_ptr, (uint8 *)g_line0);
    }
  }