Ejemplo n.º 1
0
int R2Image::
ReadJPEG(const char *filename)
{
#ifndef OMIT_JPEG
  // Open file
  FILE *fp = fopen(filename, "rb");
  if (!fp) {
    fprintf(stderr, "Unable to open image file: %s", filename);
    return 0;
  }

  // Initialize decompression info
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_decompress(&cinfo);
  jpeg_stdio_src(&cinfo, fp);
  jpeg_read_header(&cinfo, TRUE);
  jpeg_start_decompress(&cinfo);

  // Remember image attributes
  width = cinfo.output_width;
  height = cinfo.output_height;
  ncomponents = cinfo.output_components;
  rowsize = ncomponents * width;
  if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4;

  // Allocate image pixels
  int nbytes = rowsize * height;
  this->pixels = new unsigned char [nbytes];
  if (!this->pixels) {
    fprintf(stderr, "Unable to allocate memory for JPEG file");
    fclose(fp);
    return 0;
  }

  // Read scan lines 
  // First jpeg pixel is top-left, so read pixels in opposite scan-line order
  while (cinfo.output_scanline < cinfo.output_height) {
    int scanline = cinfo.output_height - cinfo.output_scanline - 1;
    unsigned char *row_pointer = &pixels[scanline * rowsize];
    jpeg_read_scanlines(&cinfo, &row_pointer, 1);
  }

  // Free everything
  jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);

  // Close file
  fclose(fp);

  // Return success
  return 1;
#else
  RNFail("JPEG not supported");
  return 0;
#endif
}
Ejemplo n.º 2
0
int R2Image::
WriteTIFF(const char *filename) const
{
#ifndef OMIT_TIFF
  // Open TIFF file
  TIFF *out = TIFFOpen(filename, "w");
  if (!out) {
    fprintf(stderr, "Unable to open TIFF file %s\n", filename);
    return 0;
  }

  // Set TIFF parameters
  TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
  TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
  TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
  TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
  TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
  TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
  TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
  TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, 1);

  // Allocate data for scan lines
  int scanline_size = TIFFScanlineSize(out);
  unsigned char *buf = (unsigned char *)_TIFFmalloc(scanline_size);
  if (!buf) {
    fprintf(stderr, "Unable to allocate memory for TIFF scan lines\n");
    return 0;
  }

  // Write scan lines to TIFF file
  for (int row = 0; row < height; row++) {
    const unsigned char *p = Pixels(row);
    if (TIFFWriteScanline(out, (tdata_t) p, height - row - 1, 0) < 0) {
      fprintf(stderr, "Unable to write scanline to TIFF image %s\n", filename);
      return 0;
    }
  }

  // Free data for scan lines
  _TIFFfree(buf);

  // Close TIFF file
  TIFFClose(out);

  // Return number of bytes written
  return 1;
#else
  RNFail("TIFF not supported");
  return 0;
#endif
}
Ejemplo n.º 3
0
int R2Image::
WriteJPEG(const char *filename) const
{
#ifndef OMIT_JPEG
  // Open file
  FILE *fp = fopen(filename, "wb");
  if (!fp) {
    fprintf(stderr, "Unable to open image file: %s", filename);
    return 0;
  }

  // Initialize compression info
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);
  jpeg_stdio_dest(&cinfo, fp);
  cinfo.image_width = width; 	/* image width and height, in pixels */
  cinfo.image_height = height;
  cinfo.input_components = ncomponents;		/* # of color components per pixel */
  cinfo.in_color_space = JCS_RGB; 	/* colorspace of input image */
  cinfo.dct_method = JDCT_ISLOW;
  jpeg_set_defaults(&cinfo);
  cinfo.optimize_coding = TRUE;
  jpeg_set_quality(&cinfo, 75, TRUE);
  jpeg_start_compress(&cinfo, TRUE);
	
  // Output scan lines
  // First jpeg pixel is top-left, so write in opposite scan-line order
  while (cinfo.next_scanline < cinfo.image_height) {
    int scanline = cinfo.image_height - cinfo.next_scanline - 1;
    unsigned char *row_pointer = &pixels[scanline * rowsize];
    jpeg_write_scanlines(&cinfo, &row_pointer, 1);
  }

  // Free everything
  jpeg_finish_compress(&cinfo);
  jpeg_destroy_compress(&cinfo);

  // Close file
  fclose(fp);

  // Return number of bytes written
  return 1;
#else
  RNFail("JPEG not supported");
  return 0;
#endif
}
Ejemplo n.º 4
0
int R3Model::
WriteObjFile(const char *filename) const
{
  // Open file
  FILE *fp;
  if (!(fp = fopen(filename, "w"))) {
    RNFail("Unable to open file %s", filename);
    return 0;
  }

  RNAbort("Not implemented");

  // Close file
  fclose(fp);

  // Return success
  return 1;
}
Ejemplo n.º 5
0
int R3Model::
WriteFile(const char *filename) const
{
  // Parse input filename extension
  const char *extension;
  if (!(extension = strrchr(filename, '.'))) {
    printf("Filename %s has no extension (e.g., .obj)\n", filename);
    return 0;
  }

  // Write file of appropriate type
  if (!strncmp(extension, ".obj", 4)) {
    if (!WriteObjFile(filename)) return 0;
  }
  else {
    RNFail("Unable to write file %s (unrecognized extension: %s)\n", filename, extension);
    return 0;
  }

  // Return success
  return 1;
}
Ejemplo n.º 6
0
int R2Image::
ReadGRD(const char *filename)
{
  // Open file
  FILE *fp = fopen(filename, "rb");
  if (!fp) {
    RNFail("Unable to open file %s", filename);
    return 0;
  }

  // Read grid resolution from file
  int grid_resolution[2];
  if (fread(&grid_resolution, sizeof(int), 2, fp) != 2) {
    RNFail("Unable to read resolution from grid file");
    return 0;
  }

  // Read world_to_grid transformation from file
  RNScalar m[9];
  if (fread(m, sizeof(RNScalar), 9, fp) != 9) {
    RNFail("Unable to read transformation matrix from file");
    return 0;
  }

  // Allocate grid values
  int grid_size = grid_resolution[0] * grid_resolution[1];
  RNScalar *grid_values = new RNScalar [ grid_size ];
  assert(grid_values);

  // Read grid values
  if (fread(grid_values, sizeof(RNScalar), grid_size, fp) != (unsigned int) grid_size) {
    RNFail("Unable to read %d grid values from file", grid_size);
    return 0;
  }

  // Close file
  fclose(fp);

  // Determine offset and scale
  RNScalar offset = 0;
  RNScalar scale = 1;
  if (grid_size > 0) {
    RNScalar sum = 0;
    RNScalar min_value = FLT_MAX;
    RNScalar max_value = -FLT_MAX;
    for (int i = 0; i < grid_size; i++) {
      if (grid_values[i] == R2_GRID_UNKNOWN_VALUE) continue;
      if (grid_values[i] > max_value) max_value = grid_values[i];
      if (grid_values[i] < min_value) min_value = grid_values[i];
      sum += grid_values[i];
    }
    RNScalar mean = sum / grid_size;
    RNScalar ssd = 0;
    for (int i = 0; i < grid_size; i++) {
      if (grid_values[i] == R2_GRID_UNKNOWN_VALUE) continue;
      RNScalar delta = grid_values[i] - mean;
      ssd += delta * delta;
    }
    RNScalar stddev = sqrt(ssd);
    RNScalar min_clamped = mean - 3 * stddev;
    if (min_clamped < min_value) min_clamped = min_value;
    RNScalar max_clamped = mean + 3 * stddev;
    if (max_clamped > max_value) max_clamped = max_value;
    RNScalar range = max_clamped - min_clamped;
    if (range > 0) {
      offset = min_clamped;
      scale = 1.0 / range;
    }
  }

  // Allocate pixels
  ncomponents = 3;
  width = grid_resolution[0];
  height = grid_resolution[1];
  rowsize = ncomponents * width;
  if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4;
  int nbytes = rowsize * height;
  pixels = new unsigned char [nbytes];
  assert(pixels);

  // Fill in pixels
  RNScalar *grid_valuesp = grid_values;
  for (int j = 0; j < height; j++) {
    unsigned char *pixelsp = &pixels[j*rowsize];
    for (int i = 0; i < width; i++) {
      int value = (int) ((*(grid_valuesp++) - offset) * 255.0 * scale);
      if (value < 0) value = 0;
      if (value > 255) value = 255;
      unsigned char p = (unsigned char) value;
      *(pixelsp++) = p;
      *(pixelsp++) = p;
      *(pixelsp++) = p;
    }
  }

  // Delete grid values
  delete [] grid_values;

  // Return number of bytes
  return nbytes;
}
Ejemplo n.º 7
0
int R2Image::
ReadTIFF(const char *filename)
{
#ifndef OMIT_TIFF
  // Open file
  TIFF* tif = TIFFOpen(filename, "r");
  if (!tif) {
    fprintf(stderr, "Unable to open TIFF file %s\n", filename);
    return 0;
  }

  // Get image dimensions
  uint32 w, h;
  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
  size_t npixels = w * h;

  // Allocate buffer for data
  uint32* raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
  if (!raster) {
    fprintf(stderr, "Unable to allocate data for TIFF file %s\n", filename);
    return 0;
  }

  // Read data into buffer
  if (!TIFFReadRGBAImage(tif, w, h, raster, 0)) {
    fprintf(stderr, "Unable to read TIFF file %s\n", filename);
    return 0;
  }

  // Initialize R2Image data
  width = w;
  height = h;
  ncomponents = 3;
  rowsize = ncomponents * width;
  if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4;
  int nbytes = rowsize * height;
  pixels = new unsigned char [nbytes];
  if (!pixels) {
    fprintf(stderr, "Unable to allocate memory for TIFF file %s", filename);
    return 0;
  }

  // Fill R2Image pixel data 
  uint32 *rasterp = raster;
  for (int j = 0; j < height; j++) {
    unsigned char *p = &pixels[j*rowsize];
    for (int i = 0; i < width; i++) {
      uint32 pixel = *(rasterp++);
      *(p++) = pixel & 0xFF;
      *(p++) = (pixel >> 8) & 0xFF;
      *(p++) = (pixel >> 16) & 0xFF;
    }
  }

  // Free data
  _TIFFfree(raster);

  // Close file
  TIFFClose(tif);

  // Return success
  return 1;
#else
  RNFail("TIFF not supported");
  return 0;
#endif
}
Ejemplo n.º 8
0
int R3Model::
ReadObjFile(const char *filename)
{
  // Open file
  FILE *fp = fopen(filename, "r");
  if (!fp) {
    RNFail("Unable to open file %s", filename);
    return 0;
  }

  // Determine directory name (for texture image files)
  char dirname[1024];
  strncpy(dirname, filename, 1024);
  char *endp = strrchr(dirname, '/');
  if (!endp) endp = strrchr(dirname, '\\');
  if (!endp) strcpy(dirname, ".");
  else *endp = '\0';

  // Read body
  char buffer[1024];
  int line_count = 0;
  int material_index =-1;
  RNArray<R2Point *> texture_coords;
  RNArray<R3TriangleVertex *> verts;
  RNArray<R3Triangle *> tris;
  while (fgets(buffer, 1023, fp)) {
    // Increment line counter
    line_count++;

    // Skip white space
    char *bufferp = buffer;
    while (isspace(*bufferp)) bufferp++;

    // Skip blank lines and comments
    if (*bufferp == '#') continue;
    if (*bufferp == '\0') continue;

    // Get keyword
    char keyword[80];
    if (sscanf(bufferp, "%s", keyword) != 1) {
      RNFail("Syntax error on line %d in file %s", line_count, filename);
      return 0;
    }

    // Check keyword
    if (!strcmp(keyword, "v")) {
      // Read vertex coordinates
      double x, y, z;
      if (sscanf(bufferp, "%s%lf%lf%lf", keyword, &x, &y, &z) != 4) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Create vertex
      R3TriangleVertex *vertex = new R3TriangleVertex(R3Point(x, y, z));
      verts.Insert(vertex);
    }
    else if (!strcmp(keyword, "vt")) {
      // Read texture coordinates
      double u, v;
      if (sscanf(bufferp, "%s%lf%lf", keyword, &u, &v) != 3) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Create texture coordinates
      R2Point *vt = new R2Point(u, v);
      texture_coords.Insert(vt);
    }
    else if (!strcmp(keyword, "f")) {
      // Read vertex indices
      int quad = 1;
      char s1[128], s2[128], s3[128], s4[128] = { '\0' };
      if (sscanf(bufferp, "%s%s%s%s%s", keyword, s1, s2, s3, s4) != 5) {
        quad = 0;;
        if (sscanf(bufferp, "%s%s%s%s", keyword, s1, s2, s3) != 4) {
          RNFail("Syntax error on line %d in file %s", line_count, filename);
          return 0;
        }
      }

      // Parse vertex indices
      int vi1 = -1, vi2 = -1, vi3 = -1, vi4 = -1;
      int ti1 = -1, ti2 = -1, ti3 = -1, ti4 = -1;
      char *p1 = strchr(s1, '/'); 
      if (p1) { *p1 = 0; vi1 = atoi(s1); p1++; if (*p1) ti1 = atoi(p1); }
      else { vi1 = atoi(s1); ti1 = vi1; }
      char *p2 = strchr(s2, '/'); 
      if (p2) { *p2 = 0; vi2 = atoi(s2); p2++; if (*p2) ti2 = atoi(p2); }
      else { vi2 = atoi(s2); ti2 = vi2; }
      char *p3 = strchr(s3, '/'); 
      if (p3) { *p3 = 0; vi3 = atoi(s3); p3++; if (*p3) ti3 = atoi(p3); }
      else { vi3 = atoi(s3); ti3 = vi3; }
      if (quad) {
        char *p4 = strchr(s4, '/'); 
        if (p4) { *p4 = 0; vi4 = atoi(s4); p4++; if (*p4) ti4 = atoi(p4); }
        else { vi4 = atoi(s4); ti4 = vi4; }
      }

      // Get vertices
      R3TriangleVertex *v1 = verts.Kth(vi1-1);
      R3TriangleVertex *v2 = verts.Kth(vi2-1);
      R3TriangleVertex *v3 = verts.Kth(vi3-1);
      R3TriangleVertex *v4 = (quad) ? verts.Kth(vi4-1) : NULL;
      
      // Assign texture coordinates
      if ((ti1 >= 0) && (ti1 < texture_coords.NEntries())) v1->SetTextureCoords(*(texture_coords.Kth(ti1-1)));
      if ((ti2 >= 0) && (ti2 < texture_coords.NEntries())) v2->SetTextureCoords(*(texture_coords.Kth(ti2-1)));
      if ((ti3 >= 0) && (ti3 < texture_coords.NEntries())) v3->SetTextureCoords(*(texture_coords.Kth(ti3-1)));
      if (quad) {
        if ((ti4 >= 0) && (ti4 < texture_coords.NEntries())) v4->SetTextureCoords(*(texture_coords.Kth(ti4-1)));
      }

      // Check vertices
      if ((v1 == v2) || (v2 == v3) || (v1 == v3)) continue;
      if ((quad) && ((v4 == v1) || (v4 == v2) || (v4 == v3))) quad = 0;

      // Create default material, if needed
      if (material_index == -1) {
        R3Brdf *brdf = new R3Brdf(RNRgb(0.2, 0.2, 0.2), RNRgb(0.8, 0.8, 0.8), 
          RNRgb(0.0, 0.0, 0.0), RNRgb(0.0, 0.0, 0.0), 0.2, 1.0, 1.0);
        R3Material *material = new R3Material(brdf, "Default");
        materials.Insert(material);
        RNArray<R3Triangle *> *mat_tris = new RNArray<R3Triangle *>();
        material_triangles.Insert(mat_tris);
        material_index = 0;
      }

      // Get material
      assert(material_index >= 0);
      R3Material *material = materials.Kth(material_index);

      // Create first triangle
      R3Triangle *triangle = new R3Triangle(v1, v2, v3);
      tris.Insert(triangle);
      triangle_materials.Insert(material);
      material_triangles[material_index]->Insert(triangle);

      // Create second triangle
      if (quad) {
        R3Triangle *triangle = new R3Triangle(v1, v3, v4);
        tris.Insert(triangle);
        triangle_materials.Insert(material);
        material_triangles[material_index]->Insert(triangle);
      }
    }
    else if (!strcmp(keyword, "mtllib")) {
      // Read fields
      char mtlname[1024];
      if (sscanf(bufferp, "%s%s", keyword, mtlname) != 2) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Read materials
      if (!ReadObjMtlFile(dirname, mtlname)) return 0;
    }
    else if (!strcmp(keyword, "usemtl")) {
      // Read fields
      char mtlname[1024];
      if (sscanf(bufferp, "%s%s", keyword, mtlname) != 2) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Find material
      material_index = FindMaterialIndex(materials, mtlname);
      if (material_index == -1) {
        fprintf(stderr, "Unable to find material %s at on line %d in file %s", mtlname, line_count, filename);
        return 0;
      }
    }
  }

  // Create triangle array
  triangles = new R3TriangleArray(verts, tris);

  // Delete texture coordinates
  for (int i = 0; i < texture_coords.NEntries(); i++) {
    R2Point *vt = texture_coords.Kth(i);
    delete vt;
  }

  // Close file
  fclose(fp);

  // Return success
  return 1;
}
Ejemplo n.º 9
0
int R3Model::
ReadObjMtlFile(const char *dirname, const char *mtlname)
{
  // Open file
  char filename[1024];
  sprintf(filename, "%s/%s", dirname, mtlname);
  FILE *fp = fopen(filename, "r");
  if (!fp) {
    RNFail("Unable to open file %s", filename);
    return 0;
  }

  // Parse file
  char buffer[1024];
  int line_count = 0;
  R3Brdf *brdf = NULL;
  R2Texture *texture = NULL;
  R3Material *material = NULL;
  while (fgets(buffer, 1023, fp)) {
    // Increment line counter
    line_count++;

    // Skip white space
    char *bufferp = buffer;
    while (isspace(*bufferp)) bufferp++;

    // Skip blank lines and comments
    if (*bufferp == '#') continue;
    if (*bufferp == '\0') continue;

    // Get keyword
    char keyword[80];
    if (sscanf(bufferp, "%s", keyword) != 1) {
      RNFail("Syntax error on line %d in file %s", line_count, filename);
      return 0;
    }

    // Check keyword
    if (!strcmp(keyword, "newmtl")) {
      // Parse line
      char name[1024];
      if (sscanf(bufferp, "%s%s", keyword, name) != (unsigned int) 2) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Create new material
      texture = NULL;
      brdf = new R3Brdf();
      material = new R3Material(brdf, texture, name);
      materials.Insert(material);
      RNArray<R3Triangle *> *mat_tris = new RNArray<R3Triangle *>();
      material_triangles.Insert(mat_tris);
    }
    else if (!strcmp(keyword, "Ka")) {
      // Parse line
      double r, g, b;
      if (sscanf(bufferp, "%s%lf%lf%lf", keyword, &r, &g, &b) != (unsigned int) 4) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Set ambient reflectance 
      if (material && brdf) {
        brdf->SetAmbient(RNRgb(r, g, b));
        material->Update();
      }
    }
    else if (!strcmp(keyword, "Kd")) {
      // Parse line
      double r, g, b;
      if (sscanf(bufferp, "%s%lf%lf%lf", keyword, &r, &g, &b) != (unsigned int) 4) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Set diffuse reflectance 
      if (material && brdf) {
        brdf->SetDiffuse(RNRgb(r, g, b));
        material->Update();
      }
    }
    else if (!strcmp(keyword, "Ks")) {
      // Parse line
      double r, g, b;
      if (sscanf(bufferp, "%s%lf%lf%lf", keyword, &r, &g, &b) != (unsigned int) 4) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Set specular reflectance 
      if (material && brdf) {
        brdf->SetSpecular(RNRgb(r, g, b));
        material->Update();
      }
    }
    else if (!strcmp(keyword, "Ns")) {
      // Parse line
      double ns;
      if (sscanf(bufferp, "%s%lf", keyword, &ns) != (unsigned int) 2) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Set shininess
      if (material && brdf) {
        brdf->SetShininess(ns);
        material->Update();
      }
    }
    else if (!strcmp(keyword, "Ni")) {
      // Parse line
      double index_of_refraction;
      if (sscanf(bufferp, "%s%lf", keyword, &index_of_refraction) != (unsigned int) 2) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Set index of refraction
      if (material && brdf) {
        brdf->SetIndexOfRefraction(index_of_refraction);
        material->Update();
      }
    }
    else if (!strcmp(keyword, "d")) {
      // Parse line
      double transparency;
      if (sscanf(bufferp, "%s%lf", keyword, &transparency) != (unsigned int) 2) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Set opacity
      if (material && brdf) {
        brdf->SetOpacity(1 - transparency);
        material->Update();
      }
    }
    else if (!strcmp(keyword, "map_Kd")) {
      // Parse line
      char texture_name[1024];
      if (sscanf(bufferp, "%s%s", keyword, texture_name) != (unsigned int) 2) {
        RNFail("Syntax error on line %d in file %s", line_count, filename);
        return 0;
      }

      // Set texture
      if (material) {
        char texture_filename[1024];
        sprintf(texture_filename, "%s/%s", dirname, texture_name);
        R2Image *image = new R2Image();
        if (!image->Read(texture_filename)) return 0;
        R2Texture *texture = new R2Texture(image);
        material->SetTexture(texture);
        material->Update();
      }
    }
  }

  // Close file
  fclose(fp);

  // Return success
  return 1;
}