#!/usr/bin/env python3
#
# Copyright (c) 2024-2025 LAAS/CNRS
# All rights reserved.
#
# Redistribution  and  use  in  source  and binary  forms,  with  or  without
# modification, are permitted provided that the following conditions are met:
#
#   1. Redistributions of  source  code must retain the  above copyright
#      notice and this list of conditions.
#   2. Redistributions in binary form must reproduce the above copyright
#      notice and  this list of  conditions in the  documentation and/or
#      other materials provided with the distribution.
#
# THE SOFTWARE  IS PROVIDED "AS IS"  AND THE AUTHOR  DISCLAIMS ALL WARRANTIES
# WITH  REGARD   TO  THIS  SOFTWARE  INCLUDING  ALL   IMPLIED  WARRANTIES  OF
# MERCHANTABILITY AND  FITNESS.  IN NO EVENT  SHALL THE AUTHOR  BE LIABLE FOR
# ANY  SPECIAL, DIRECT,  INDIRECT, OR  CONSEQUENTIAL DAMAGES  OR  ANY DAMAGES
# WHATSOEVER  RESULTING FROM  LOSS OF  USE, DATA  OR PROFITS,  WHETHER  IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR  OTHER TORTIOUS ACTION, ARISING OUT OF OR
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
#                                           Anthony Mallet on Tue Feb  6 2024
#
import argparse
import cv2
import genomix
import numpy
import os.path

def image(cam, bank, slot):
  b = cam.image(bank)
  i = b['image']['images'][slot]['pixmap']

  # empty image
  if i['pixfmt'] == '::or::sensor::pixmap::ANY':
    return numpy.random.randn(120,160).astype(numpy.uint8)

  # compressed formats
  if i['pixfmt'] in ['::or::sensor::pixmap::JPEG',
                     '::or::sensor::pixmap::PNG',
                     '::or::sensor::pixmap::TIFF']:
    img = cv2.imdecode(
      numpy.frombuffer(bytearray(i['data']), numpy.uint8),
      cv2.IMREAD_UNCHANGED)
    return img if img is not None else \
      numpy.random.randn(120,160).astype(numpy.uint8)

  # uncompressed formats
  if i['pixfmt'] == '::or::sensor::pixmap::MONO8':
    fmt, chans = numpy.uint8, 1
  elif i['pixfmt'] == '::or::sensor::pixmap::RGB8' \
     or i['pixfmt'] == '::or::sensor::pixmap::BGR8':
    fmt, chans = numpy.uint8, 3
  elif i['pixfmt'] == '::or::sensor::pixmap::Z32':
    fmt, chans = numpy.float32, 1
  else:
    raise ValueError('Unknown encoding %s' % i['pixfmt'])

  img = numpy.frombuffer(bytearray(i['data']), fmt).\
    reshape(i['height'], i['width'], chans)

  if i['pixfmt'] == '::or::sensor::pixmap::RGB8':
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)

  return img

def main():
  parser = argparse.ArgumentParser(description='camera-genom3 image viewer')
  parser.add_argument('--host', default='localhost',
                      help='genomixd host to connect to')
  parser.add_argument('--port', default='8080',
                      help='genomixd port to connect to')
  parser.add_argument('--path', default='', help='component plugin path')
  parser.add_argument('component', help='component name')
  parser.add_argument('bank', help='bank name')
  parser.add_argument('slot', type=int, help='bank slot')

  args = parser.parse_args()

  g = genomix.connect(args.host + ':' + args.port)
  cam = g.load(os.path.join(args.path, args.component))

  while(True):
    img = image(cam, args.bank, args.slot)
    cv2.imshow('%s %s#%d' % (args.component, args.bank, args.slot), img)
    if cv2.waitKeyEx(20) == ord('q'):
      return

main()
