Beispiel #1
0
// ServeTile returns a tile with appropriate Content-Type set.
func (d *Data) ServeTile(uuid dvid.UUID, ctx storage.Context, w http.ResponseWriter,
	r *http.Request, parts []string) error {

	if d.Levels == nil || len(d.Levels) == 0 {
		return ErrNoMetadataSet
	}
	tileReq, err := d.parseTileReq(r, parts)

	queryValues := r.URL.Query()
	noblanksStr := dvid.InstanceName(queryValues.Get("noblanks"))
	var noblanks bool
	if noblanksStr == "true" {
		noblanks = true
	}
	var formatStr string
	if len(parts) >= 8 {
		formatStr = parts[7]
	}

	data, err := d.getTileData(ctx, tileReq)
	if err != nil {
		server.BadRequest(w, r, err)
		return err
	}
	if data == nil {
		if noblanks {
			http.NotFound(w, r)
			return nil
		}
		img, err := d.getBlankTileImage(uuid, tileReq)
		if err != nil {
			return err
		}
		return dvid.WriteImageHttp(w, img, formatStr)
	}

	switch d.Encoding {
	case LZ4:
		var img dvid.Image
		if err := img.Deserialize(data); err != nil {
			return err
		}
		data, err = img.GetPNG()
		w.Header().Set("Content-type", "image/png")
	case PNG:
		w.Header().Set("Content-type", "image/png")
	case JPG:
		w.Header().Set("Content-type", "image/jpeg")
	}
	if err != nil {
		server.BadRequest(w, r, err)
		return err
	}
	if _, err = w.Write(data); err != nil {
		return err
	}
	return nil
}
Beispiel #2
0
// make sure the given labels match what would be expected from the test volume.
func (s sliceTester) testLabel(t *testing.T, vol labelVol, img *dvid.Image) {
	data := img.Data()
	var x, y, z int32
	i := 0
	switch s.orient {
	case "xy":
		for y = 0; y < s.height; y++ {
			for x = 0; x < s.width; x++ {
				label := binary.LittleEndian.Uint64(data[i*8 : (i+1)*8])
				i++
				vx := x + s.offset[0]
				vy := y + s.offset[1]
				vz := s.offset[2]
				expected := vol.label(vx, vy, vz)
				if label != expected {
					t.Errorf("Bad label @ (%d,%d,%d): expected %d, got %d\n", vx, vy, vz, expected, label)
					return
				}
			}
		}
		return
	case "xz":
		for z = 0; z < s.height; z++ {
			for x = 0; x < s.width; x++ {
				label := binary.LittleEndian.Uint64(data[i*8 : (i+1)*8])
				i++
				vx := x + s.offset[0]
				vy := s.offset[1]
				vz := z + s.offset[2]
				expected := vol.label(vx, vy, vz)
				if label != expected {
					t.Errorf("Bad label @ (%d,%d,%d): expected %d, got %d\n", vx, vy, vz, expected, label)
					return
				}
			}
		}
		return
	case "yz":
		for z = 0; z < s.height; z++ {
			for y = 0; x < s.width; x++ {
				label := binary.LittleEndian.Uint64(data[i*8 : (i+1)*8])
				i++
				vx := s.offset[0]
				vy := y * s.offset[1]
				vz := z + s.offset[2]
				expected := vol.label(vx, vy, vz)
				if label != expected {
					t.Errorf("Bad label @ (%d,%d,%d): expected %d, got %d\n", vx, vy, vz, expected, label)
					return
				}
			}
		}
		return
	default:
		t.Fatalf("Unknown slice orientation %q\n", s.orient)
	}
}
Beispiel #3
0
// getTileImage returns a 2d tile image or a placeholder, useful for further stitching before
// delivery of a final image.
func (d *Data) getTileImage(ctx storage.Context, req TileReq) (image.Image, error) {
	if d.Levels == nil || len(d.Levels) == 0 {
		return nil, ErrNoMetadataSet
	}
	data, err := d.getTileData(ctx, req)
	if err != nil {
		return nil, err
	}

	if len(data) == 0 {
		if d.Placeholder {
			if req.scale < 0 || req.scale >= Scaling(len(d.Levels)) {
				return nil, fmt.Errorf("Could not find tile specification at given scale %d", req.scale)
			}
			message := fmt.Sprintf("%s Tile coord %s @ scale %d", req.plane, req.tile, req.scale)
			return dvid.PlaceholderImage(req.plane, d.Levels[req.scale].TileSize, message)
		}
		return nil, nil // Not found
	}

	var goImg image.Image
	switch d.Encoding {
	case LZ4:
		var img dvid.Image
		err = img.Deserialize(data)
		if err != nil {
			return nil, err
		}
		goImg = img.Get()
	case PNG:
		pngBuffer := bytes.NewBuffer(data)
		goImg, err = png.Decode(pngBuffer)
	case JPG:
		jpgBuffer := bytes.NewBuffer(data)
		goImg, err = jpeg.Decode(jpgBuffer)
	default:
		return nil, fmt.Errorf("Unknown tile encoding: %s", d.Encoding)
	}
	return goImg, err
}
Beispiel #4
0
// GetTile returns a 2d tile image or a placeholder
func (d *Data) GetTile(ctx storage.Context, shape dvid.DataShape, scaling Scaling, index dvid.IndexZYX) (image.Image, error) {
	data, err := d.getTileData(ctx, shape, scaling, index)
	if err != nil {
		return nil, err
	}
	tileIndex := &IndexTile{&index, shape, scaling}

	if data == nil {
		if d.Placeholder {
			if d.Levels == nil || scaling < 0 || scaling >= Scaling(len(d.Levels)) {
				return nil, fmt.Errorf("Could not find tile specification at given scale %d", scaling)
			}
			message := fmt.Sprintf("%s Tile coord %s @ scale %d", shape, tileIndex, scaling)
			return dvid.PlaceholderImage(shape, d.Levels[scaling].TileSize, message)
		}
		return nil, nil // Not found
	}

	var goImg image.Image
	switch d.Encoding {
	case LZ4:
		var img dvid.Image
		err = img.Deserialize(data)
		if err != nil {
			return nil, err
		}
		goImg = img.Get()
	case PNG:
		pngBuffer := bytes.NewBuffer(data)
		goImg, err = png.Decode(pngBuffer)
	case JPG:
		jpgBuffer := bytes.NewBuffer(data)
		goImg, err = jpeg.Decode(jpgBuffer)
	default:
		return nil, fmt.Errorf("Unknown tile encoding: %s", d.Encoding)
	}
	return goImg, err
}
Beispiel #5
0
// ServeTile returns a tile with appropriate Content-Type set.
func (d *Data) ServeTile(uuid dvid.UUID, ctx storage.Context, w http.ResponseWriter,
	r *http.Request, parts []string) error {

	if len(parts) < 7 {
		return fmt.Errorf("'tile' request must be following by plane, scale level, and tile coordinate")
	}
	planeStr, scalingStr, coordStr := parts[4], parts[5], parts[6]
	queryValues := r.URL.Query()
	noblanksStr := dvid.InstanceName(queryValues.Get("noblanks"))
	var noblanks bool
	if noblanksStr == "true" {
		noblanks = true
	}
	var formatStr string
	if len(parts) >= 8 {
		formatStr = parts[7]
	}

	// Construct the index for this tile
	plane := dvid.DataShapeString(planeStr)
	shape, err := plane.DataShape()
	if err != nil {
		err = fmt.Errorf("Illegal tile plane: %s (%v)", planeStr, err)
		server.BadRequest(w, r, err)
		return err
	}
	scaling, err := strconv.ParseUint(scalingStr, 10, 8)
	if err != nil {
		err = fmt.Errorf("Illegal tile scale: %s (%v)", scalingStr, err)
		server.BadRequest(w, r, err)
		return err
	}
	tileCoord, err := dvid.StringToPoint(coordStr, "_")
	if err != nil {
		err = fmt.Errorf("Illegal tile coordinate: %s (%v)", coordStr, err)
		server.BadRequest(w, r, err)
		return err
	}
	if tileCoord.NumDims() != 3 {
		err = fmt.Errorf("Expected 3d tile coordinate, got %s", coordStr)
		server.BadRequest(w, r, err)
		return err
	}
	indexZYX := dvid.IndexZYX{tileCoord.Value(0), tileCoord.Value(1), tileCoord.Value(2)}
	data, err := d.getTileData(ctx, shape, Scaling(scaling), indexZYX)
	if err != nil {
		server.BadRequest(w, r, err)
		return err
	}
	if data == nil {
		if noblanks {
			http.NotFound(w, r)
			return nil
		}
		img, err := d.getBlankTileImage(uuid, shape, Scaling(scaling))
		if err != nil {
			return err
		}
		return dvid.WriteImageHttp(w, img, formatStr)
	}

	switch d.Encoding {
	case LZ4:
		var img dvid.Image
		if err := img.Deserialize(data); err != nil {
			return err
		}
		data, err = img.GetPNG()
		w.Header().Set("Content-type", "image/png")
	case PNG:
		w.Header().Set("Content-type", "image/png")
	case JPG:
		w.Header().Set("Content-type", "image/jpeg")
	}
	if err != nil {
		server.BadRequest(w, r, err)
		return err
	}
	if _, err = w.Write(data); err != nil {
		return err
	}
	return nil
}