@@ -137,6 +137,7 @@ const uint32_t restab[CAMERA_RMAX][2] = {
137
137
{320 , 240 }, // QVGA
138
138
{320 , 320 },
139
139
{640 , 480 }, // VGA
140
+ {0 , 0 }, // Empty entry because there's a jump in the resolution enum initializers
140
141
{800 , 600 }, // SVGA
141
142
{1600 , 1200 }, // UXGA
142
143
};
@@ -504,36 +505,120 @@ int Camera::setFrameRate(int32_t framerate)
504
505
return -1 ;
505
506
}
506
507
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 )
508
509
{
509
510
if (this ->sensor == NULL || resolution >= CAMERA_RMAX
510
511
|| pixformat >= CAMERA_PMAX || pixformat == -1 ) {
511
512
return -1 ;
512
513
}
513
514
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
+
514
534
/*
515
535
* @param X0 DCMI window X offset
516
536
* @param Y0 DCMI window Y offset
517
537
* @param XSize DCMI Pixel per line
518
538
* @param YSize DCMI Line number
519
539
*/
520
540
HAL_DCMI_EnableCROP (&hdcmi);
521
- uint32_t bpl = restab[resolution ][0 ];
541
+ uint32_t bpl = restab[final_resolution ][0 ];
522
542
if (pixformat == CAMERA_RGB565 ||
523
543
(pixformat == CAMERA_GRAYSCALE && !this ->sensor ->getMono ())) {
524
544
// If the pixel format is Grayscale and sensor is Not monochrome,
525
545
// the actual pixel format will be YUV (i.e 2 bytes per pixel).
526
546
bpl *= 2 ;
527
547
}
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 );
529
549
530
- if (this ->sensor ->setResolution (resolution) == 0 ) {
531
- this ->resolution = resolution ;
550
+ if (this ->sensor ->setResolutionWithZoom (resolution, zoom_resolution, zoom_x, zoom_y ) == 0 ) {
551
+ this ->resolution = final_resolution ;
532
552
return 0 ;
533
553
}
534
554
return -1 ;
535
555
}
536
556
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_enable)
604
+ {
605
+ return (this ->sensor ->setVerticalFlip (flip_enable));
606
+ }
607
+
608
+ int Camera::setHorizontalMirror (bool mirror_enable)
609
+ {
610
+ return (this ->sensor ->setHorizontalMirror (mirror_enable));
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
+
537
622
int Camera::setPixelFormat (int32_t pixformat)
538
623
{
539
624
if (this ->sensor == NULL || pixformat >= CAMERA_PMAX) {
0 commit comments