class_docstr: The server maintains the port and hands off the requests to workers
  
  example of use:
  
  context = zmq.Context()
  with KnimeBridgeServer(
      context,
      "tcp://127.0.0.1:4000", # server address
      "inproc://Notify        # kill notify address
      ) as server:
      notify_socket = context.socket(zmq.PUB)
      notify_socket.bind("inproc://Notify")
      ....
      notify_socket.send("Stop")
class_docstr_tok: ["The","server","maintains","the","port","and","hands","off","the","requests","to","workers","example","of","use",":","context","=","zmq.Context","(",")","with","KnimeBridgeServer","(","context",",","``","tcp",":","\/\/127.0.0.1:4000","''",",","#","server","address","``","inproc",":","\/\/Notify","#","kill","notify","address",")","as","server",":","notify_socket","=","context.socket","(","zmq.PUB",")","notify_socket.bind","(","``","inproc",":","\/\/Notify","''",")","....","notify_socket.send","(","``","Stop","''",")"]
docstr: Decode an image sent via the wire format
  
  channel_metadata: sequence of 3 tuples of axis name, dimension and stride
  buf: byte-buffer, low-endian representation of doubles
  grouping_allowed: true if we can accept images grouped by X or T
  
  returns numpy array in y, x indexing format.
docstr_tok: ["Decode","an","image","sent","via","the","wire","format","channel_metadata",":","sequence","of","3","tuples","of","axis","name",",","dimension","and","stride","buf",":","byte-buffer",",","low-endian","representation","of","doubles","grouping_allowed",":","true","if","we","can","accept","images","grouped","by","X","or","T","returns","numpy","array","in","y",",","x","indexing","format","."]
code: def decode_image(self, channel_metadata, buf, grouping_allowed=False):
      """Decode an image sent via the wire format
  
      channel_metadata: sequence of 3 tuples of axis name, dimension and stride
      buf: byte-buffer, low-endian representation of doubles
      grouping_allowed: true if we can accept images grouped by X or T
  
      returns numpy array in y, x indexing format.
      """
      pixel_data = numpy.frombuffer(buf, "<f8")
      strides_out = [None] * len(channel_metadata)
      dimensions_out = [None] * len(channel_metadata)
      grouping = False
      for axis_name, dim, stride in channel_metadata:
          if axis_name.lower() == "y":
              if strides_out[0] is not None:
                  raise RuntimeError("Y dimension doubly specified")
              strides_out[0] = stride * 8
              dimensions_out[0] = dim
          elif axis_name.lower() == "x":
              if strides_out[1] is not None:
                  raise RuntimeError("X dimension doubly specified")
              strides_out[1] = stride * 8
              dimensions_out[1] = dim
          elif axis_name.lower() == "channel":
              if strides_out[2] is not None:
                  raise RuntimeError("Channel doubly specified")
              strides_out[2] = stride * 8
              dimensions_out[2] = dim
          elif grouping == False and grouping_allowed:
              grouping = True
              strides_out[-1] = stride * 8
              dimensions_out[-1] = dim
          else:
              raise RuntimeError("Unknown dimension: " + axis_name)
      if grouping:
          strides_out[0], strides_out[1:] = (
              strides_out[-1],
              strides_out[:-1],
          )
          dimensions_out[0], dimensions_out[1:] = (
              dimensions_out[-1],
              dimensions_out[:-1],
          )
      pixel_data.shape = tuple(dimensions_out)
      pixel_data.strides = tuple(strides_out)
      return pixel_data
  
imports: import json
  import logging
  import threading
  import uuid
  from io import StringIO
  import numpy
  import zmq
  from cellprofiler_core.constants.measurement import GROUP_NUMBER, GROUP_INDEX, OBJECT_NUMBER, EXPERIMENT, MCA_AVAILABLE_POST_RUN, COLTYPE_FLOAT, COLTYPE_INTEGER, COLTYPE_VARCHAR, IMAGE_NUMBER
  from cellprofiler_core.constants.workspace import DISPOSITION_SKIP, DISPOSITION_CANCEL
  from cellprofiler_core.image import Image
  from cellprofiler_core.measurement import Measurements
  from cellprofiler_core.module import Module
  from cellprofiler_core.setting.text import ImageName
  import cellprofiler_core.object
  import cellprofiler_core.pipeline
  import cellprofiler_core.workspace
label_desc: Use image node_id 17 for calling the KnimeBridgeServer obj's underlying member method code with example usage: obj.decode_image(channel_metadata, buf, grouping_allowed) and returns: pixel_data