@@ -137,6 +137,7 @@ const uint32_t restab[CAMERA_RMAX][2] = {
137137 {320 , 240 }, // QVGA
138138 {320 , 320 },
139139 {640 , 480 }, // VGA
140+ {0 , 0 }, // Empty entry because there's a jump in the resolution enum initializers
140141 {800 , 600 }, // SVGA
141142 {1600 , 1200 }, // UXGA
142143};
@@ -504,36 +505,120 @@ int Camera::setFrameRate(int32_t framerate)
504505 return -1 ;
505506}
506507
507- int Camera::setResolution (int32_t resolution)
508+ int Camera::setResolutionWithZoom (int32_t resolution, int32_t zoom_resolution, int32_t zoom_x, int32_t zoom_y )
508509{
509510 if (this ->sensor == NULL || resolution >= CAMERA_RMAX
510511 || pixformat >= CAMERA_PMAX || pixformat == -1 ) {
511512 return -1 ;
512513 }
513514
515+ // resolution = the full resolution to set the camera to
516+ // zoom_resolution = the resolution to crop to when zooming (set equal to resolution for no zoom)
517+ // final_resolution = the resolution to crop to (depends on zoom or not)
518+ int32_t final_resolution;
519+ // Check if zooming is asked for
520+ if (resolution != zoom_resolution)
521+ {
522+ // Can't zoom into a larger window than the original
523+ if (zoom_resolution > resolution)
524+ {
525+ return -1 ;
526+ }
527+ final_resolution = zoom_resolution;
528+ }
529+ else
530+ {
531+ final_resolution = resolution;
532+ }
533+
514534 /*
515535 * @param X0 DCMI window X offset
516536 * @param Y0 DCMI window Y offset
517537 * @param XSize DCMI Pixel per line
518538 * @param YSize DCMI Line number
519539 */
520540 HAL_DCMI_EnableCROP (&hdcmi);
521- uint32_t bpl = restab[resolution ][0 ];
541+ uint32_t bpl = restab[final_resolution ][0 ];
522542 if (pixformat == CAMERA_RGB565 ||
523543 (pixformat == CAMERA_GRAYSCALE && !this ->sensor ->getMono ())) {
524544 // If the pixel format is Grayscale and sensor is Not monochrome,
525545 // the actual pixel format will be YUV (i.e 2 bytes per pixel).
526546 bpl *= 2 ;
527547 }
528- HAL_DCMI_ConfigCROP (&hdcmi, 0 , 0 , bpl - 1 , restab[resolution ][1 ] - 1 );
548+ HAL_DCMI_ConfigCROP (&hdcmi, 0 , 0 , bpl - 1 , restab[final_resolution ][1 ] - 1 );
529549
530- if (this ->sensor ->setResolution (resolution) == 0 ) {
531- this ->resolution = resolution ;
550+ if (this ->sensor ->setResolution (resolution, zoom_resolution, zoom_x, zoom_y ) == 0 ) {
551+ this ->resolution = final_resolution ;
532552 return 0 ;
533553 }
534554 return -1 ;
535555}
536556
557+ int Camera::setResolution (int32_t resolution)
558+ {
559+ // Check for resolutions that would cause out-of-bounds indexing of restab
560+ // This check is here because original_resolution will be trusted in all other code
561+ if ((resolution < 0 ) || (resolution >= CAMERA_RMAX))
562+ {
563+ return -1 ;
564+ }
565+ original_resolution = resolution;
566+ return setResolutionWithZoom (resolution, resolution, 0 , 0 );
567+ }
568+
569+ int Camera::zoomTo (int32_t zoom_resolution, uint32_t zoom_x, uint32_t zoom_y)
570+ {
571+ // Check for zoom resolutions that would cause out-of-bounds indexing of restab
572+ if ((zoom_resolution < 0 ) || (zoom_resolution >= CAMERA_RMAX))
573+ {
574+ return -1 ;
575+ }
576+ // Check if the zoom window goes outside the frame on the x axis
577+ // Notice that this form prevents uint32_t wraparound, so don't change it
578+ if (zoom_x >= (restab[this ->original_resolution ][0 ]) - (restab[zoom_resolution][0 ]))
579+ {
580+ return -1 ;
581+ }
582+ // Check if the zoom window goes outside the frame on the y axis
583+ // Notice that this form prevents uint32_t wraparound, so don't change it
584+ if (zoom_y >= (restab[this ->original_resolution ][1 ]) - (restab[zoom_resolution][1 ]))
585+ {
586+ return -1 ;
587+ }
588+ return setResolutionWithZoom (this ->original_resolution , zoom_resolution, zoom_x, zoom_y);
589+ }
590+
591+ int Camera::zoomToCenter (int32_t zoom_resolution)
592+ {
593+ // Check for zoom resolutions that would cause out-of-bounds indexing of restab
594+ if ((zoom_resolution < 0 ) || (zoom_resolution >= CAMERA_RMAX))
595+ {
596+ return -1 ;
597+ }
598+ uint32_t zoom_x = (restab[this ->original_resolution ][0 ] - restab[zoom_resolution][0 ]) / 2 ;
599+ uint32_t zoom_y = (restab[this ->original_resolution ][1 ] - restab[zoom_resolution][1 ]) / 2 ;
600+ return setResolutionWithZoom (this ->original_resolution , zoom_resolution, zoom_x, zoom_y);
601+ }
602+
603+ int Camera::setVerticalFlip (bool flip_mode)
604+ {
605+ return (this ->sensor ->setVerticalFlip (flip_mode));
606+ }
607+
608+ int Camera::setHorizontalMirror (bool mirror_mode)
609+ {
610+ return (this ->sensor ->setHorizontalMirror (mirror_mode));
611+ }
612+
613+ uint32_t Camera::getResolutionWidth ()
614+ {
615+ return (restab[this ->original_resolution ][0 ]);
616+ }
617+ uint32_t Camera::getResolutionHeight ()
618+ {
619+ return (restab[this ->original_resolution ][1 ]);
620+ }
621+
537622int Camera::setPixelFormat (int32_t pixformat)
538623{
539624 if (this ->sensor == NULL || pixformat >= CAMERA_PMAX) {
0 commit comments